@syntrologie/runtime-sdk 2.8.0-canary.4 → 2.8.0-canary.41
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/CAPABILITIES.md +44 -0
- package/dist/actions/schema.d.ts +1 -1
- package/dist/actions/schema.js +1 -1
- package/dist/actions/validation-core.d.ts +24 -0
- package/dist/actions/validation-rules.d.ts +74 -0
- package/dist/actions/validation.d.ts +5 -11
- package/dist/bootstrap-init.d.ts +33 -0
- package/dist/bootstrap-runtime.d.ts +7 -0
- package/dist/bootstrap-types.d.ts +90 -0
- package/dist/bootstrap.d.ts +17 -83
- package/dist/{chunk-R5DNAIRI.js → chunk-TN5BLBPU.js} +1 -1
- package/dist/{chunk-R5DNAIRI.js.map → chunk-TN5BLBPU.js.map} +1 -1
- package/dist/{chunk-5GTCL2IH.js → chunk-X2XEU6KD.js} +1506 -599
- package/dist/chunk-X2XEU6KD.js.map +7 -0
- package/dist/components/TileIcon.d.ts +2 -2
- package/dist/components/emojiToIcon.d.ts +24 -0
- package/dist/events/EventBus.d.ts +27 -1
- package/dist/events/history.d.ts +9 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/normalizers/posthog.d.ts +4 -50
- package/dist/events/types.d.ts +30 -23
- package/dist/events/validation.d.ts +7 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.js +1523 -182
- package/dist/index.js.map +4 -4
- package/dist/overlays/runtime/overlay/overlay-runner.d.ts +4 -0
- package/dist/overlays/runtime/overlay/overlay-state.d.ts +21 -0
- package/dist/overlays/types.d.ts +3 -1
- package/dist/react.js +4 -2
- package/dist/react.js.map +2 -2
- package/dist/smart-canvas.esm.js +123 -54
- package/dist/smart-canvas.esm.js.map +4 -4
- package/dist/smart-canvas.js +5650 -2964
- package/dist/smart-canvas.js.map +4 -4
- package/dist/smart-canvas.min.js +123 -54
- package/dist/smart-canvas.min.js.map +4 -4
- package/dist/telemetry/adapters/posthog.d.ts +30 -4
- package/dist/test/setup.d.ts +1 -0
- package/dist/token.d.ts +2 -0
- package/dist/version.d.ts +1 -1
- package/package.json +23 -28
- package/schema/canvas-config.schema.json +100 -2
- package/scripts/syntroReactPlugin.mjs +3 -0
- package/scripts/validate-config.mjs +42 -0
- package/dist/chunk-5GTCL2IH.js.map +0 -7
|
@@ -34,6 +34,11 @@ function guardAgainstReconciliation(container, anchor, reinsertFn, opts) {
|
|
|
34
34
|
debounceTimer = setTimeout(() => {
|
|
35
35
|
if (disconnected)
|
|
36
36
|
return;
|
|
37
|
+
if (!anchor.isConnected) {
|
|
38
|
+
observer.disconnect();
|
|
39
|
+
disconnected = true;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
37
42
|
retries++;
|
|
38
43
|
try {
|
|
39
44
|
reinsertFn();
|
|
@@ -75,7 +80,16 @@ var ALLOWED_TAGS = /* @__PURE__ */ new Set([
|
|
|
75
80
|
"sup",
|
|
76
81
|
"sub",
|
|
77
82
|
"a",
|
|
78
|
-
"button"
|
|
83
|
+
"button",
|
|
84
|
+
// SVG elements (for inline Lucide icons in config HTML)
|
|
85
|
+
"svg",
|
|
86
|
+
"path",
|
|
87
|
+
"circle",
|
|
88
|
+
"line",
|
|
89
|
+
"polyline",
|
|
90
|
+
"polygon",
|
|
91
|
+
"rect",
|
|
92
|
+
"g"
|
|
79
93
|
]);
|
|
80
94
|
function sanitizeHtml(html) {
|
|
81
95
|
var _a2;
|
|
@@ -113,6 +127,12 @@ function sanitizeHtml(html) {
|
|
|
113
127
|
}
|
|
114
128
|
}
|
|
115
129
|
}
|
|
130
|
+
const svgs = Array.from(root.querySelectorAll("svg"));
|
|
131
|
+
for (const svg of svgs) {
|
|
132
|
+
if (toRemove.some((el) => svg.contains(el) && el.tagName.toLowerCase() === "script")) {
|
|
133
|
+
toRemove.push(svg);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
116
136
|
for (const el of toRemove) {
|
|
117
137
|
while (el.firstChild) {
|
|
118
138
|
(_a2 = el.parentNode) == null ? void 0 : _a2.insertBefore(el.firstChild, el);
|
|
@@ -213,15 +233,20 @@ var executeInsertHtml = async (action, context) => {
|
|
|
213
233
|
container.removeEventListener("click", deepLinkHandler);
|
|
214
234
|
}
|
|
215
235
|
guardCleanup();
|
|
216
|
-
if (
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
restoredEl.
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
236
|
+
if (!container.isConnected)
|
|
237
|
+
return;
|
|
238
|
+
try {
|
|
239
|
+
if (action.position === "replace" && originalContent !== null) {
|
|
240
|
+
const restoredEl = document.createElement(anchorEl.tagName);
|
|
241
|
+
restoredEl.innerHTML = originalContent;
|
|
242
|
+
Array.from(anchorEl.attributes).forEach((attr) => {
|
|
243
|
+
restoredEl.setAttribute(attr.name, attr.value);
|
|
244
|
+
});
|
|
245
|
+
container.replaceWith(restoredEl);
|
|
246
|
+
} else {
|
|
247
|
+
container.remove();
|
|
248
|
+
}
|
|
249
|
+
} catch {
|
|
225
250
|
}
|
|
226
251
|
},
|
|
227
252
|
updateFn: (changes) => {
|
|
@@ -251,6 +276,8 @@ var executeSetText = async (action, context) => {
|
|
|
251
276
|
});
|
|
252
277
|
return {
|
|
253
278
|
cleanup: () => {
|
|
279
|
+
if (!anchorEl.isConnected)
|
|
280
|
+
return;
|
|
254
281
|
anchorEl.textContent = originalText;
|
|
255
282
|
},
|
|
256
283
|
updateFn: (changes) => {
|
|
@@ -292,6 +319,8 @@ var executeSetAttr = async (action, context) => {
|
|
|
292
319
|
});
|
|
293
320
|
return {
|
|
294
321
|
cleanup: () => {
|
|
322
|
+
if (!anchorEl.isConnected)
|
|
323
|
+
return;
|
|
295
324
|
if (hadAttribute && originalValue !== null) {
|
|
296
325
|
anchorEl.setAttribute(action.attr, originalValue);
|
|
297
326
|
} else {
|
|
@@ -325,6 +354,8 @@ var executeAddClass = async (action, context) => {
|
|
|
325
354
|
});
|
|
326
355
|
return {
|
|
327
356
|
cleanup: () => {
|
|
357
|
+
if (!anchorEl.isConnected)
|
|
358
|
+
return;
|
|
328
359
|
if (!hadClass) {
|
|
329
360
|
anchorEl.classList.remove(action.className);
|
|
330
361
|
}
|
|
@@ -351,6 +382,8 @@ var executeRemoveClass = async (action, context) => {
|
|
|
351
382
|
});
|
|
352
383
|
return {
|
|
353
384
|
cleanup: () => {
|
|
385
|
+
if (!anchorEl.isConnected)
|
|
386
|
+
return;
|
|
354
387
|
if (hadClass) {
|
|
355
388
|
anchorEl.classList.add(action.className);
|
|
356
389
|
}
|
|
@@ -383,6 +416,8 @@ var executeSetStyle = async (action, context) => {
|
|
|
383
416
|
});
|
|
384
417
|
return {
|
|
385
418
|
cleanup: () => {
|
|
419
|
+
if (!anchorEl.isConnected)
|
|
420
|
+
return;
|
|
386
421
|
for (const [prop, originalValue] of originalStyles) {
|
|
387
422
|
if (originalValue) {
|
|
388
423
|
anchorEl.style.setProperty(prop, originalValue);
|
|
@@ -726,6 +761,10 @@ var CelebrationEngine = class {
|
|
|
726
761
|
this.container = null;
|
|
727
762
|
}
|
|
728
763
|
start(container, effect, config) {
|
|
764
|
+
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
765
|
+
if (prefersReducedMotion) {
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
729
768
|
this.container = container;
|
|
730
769
|
this.effect = effect;
|
|
731
770
|
this.duration = config.duration;
|
|
@@ -1558,10 +1597,10 @@ function showHighlight(anchorEl, overlayRoot, opts) {
|
|
|
1558
1597
|
return;
|
|
1559
1598
|
}
|
|
1560
1599
|
const rect = anchorEl.getBoundingClientRect();
|
|
1561
|
-
const x =
|
|
1562
|
-
const y =
|
|
1563
|
-
const w =
|
|
1564
|
-
const h =
|
|
1600
|
+
const x = rect.left - padding;
|
|
1601
|
+
const y = rect.top - padding;
|
|
1602
|
+
const w = rect.width + padding * 2;
|
|
1603
|
+
const h = rect.height + padding * 2;
|
|
1565
1604
|
Object.assign(ring.style, {
|
|
1566
1605
|
left: `${x}px`,
|
|
1567
1606
|
top: `${y}px`,
|
|
@@ -1610,17 +1649,22 @@ function showHighlight(anchorEl, overlayRoot, opts) {
|
|
|
1610
1649
|
window.addEventListener("scroll", onScroll, true);
|
|
1611
1650
|
window.addEventListener("resize", onResize);
|
|
1612
1651
|
const onKey = (e) => {
|
|
1613
|
-
|
|
1652
|
+
var _a3;
|
|
1653
|
+
if (e.key === "Escape" && onEsc) {
|
|
1654
|
+
(_a3 = opts == null ? void 0 : opts.onDismiss) == null ? void 0 : _a3.call(opts);
|
|
1614
1655
|
handle.destroy();
|
|
1656
|
+
}
|
|
1615
1657
|
};
|
|
1616
1658
|
if (onEsc) {
|
|
1617
1659
|
window.addEventListener("keydown", onKey);
|
|
1618
1660
|
}
|
|
1619
1661
|
const onClick = (event) => {
|
|
1662
|
+
var _a3;
|
|
1620
1663
|
if (blocking) {
|
|
1621
1664
|
event.preventDefault();
|
|
1622
1665
|
event.stopPropagation();
|
|
1623
1666
|
} else if (onClickOutside) {
|
|
1667
|
+
(_a3 = opts == null ? void 0 : opts.onDismiss) == null ? void 0 : _a3.call(opts);
|
|
1624
1668
|
handle.destroy();
|
|
1625
1669
|
}
|
|
1626
1670
|
};
|
|
@@ -1637,8 +1681,14 @@ function showHighlight(anchorEl, overlayRoot, opts) {
|
|
|
1637
1681
|
scrim.style.pointerEvents = "none";
|
|
1638
1682
|
scrim.style.opacity = "0";
|
|
1639
1683
|
setTimeout(() => {
|
|
1640
|
-
|
|
1641
|
-
|
|
1684
|
+
try {
|
|
1685
|
+
scrim.remove();
|
|
1686
|
+
} catch {
|
|
1687
|
+
}
|
|
1688
|
+
try {
|
|
1689
|
+
ring.remove();
|
|
1690
|
+
} catch {
|
|
1691
|
+
}
|
|
1642
1692
|
}, 220);
|
|
1643
1693
|
}
|
|
1644
1694
|
};
|
|
@@ -1666,7 +1716,16 @@ var ALLOWED_TAGS2 = /* @__PURE__ */ new Set([
|
|
|
1666
1716
|
"sup",
|
|
1667
1717
|
"sub",
|
|
1668
1718
|
"a",
|
|
1669
|
-
"button"
|
|
1719
|
+
"button",
|
|
1720
|
+
// SVG elements (for inline Lucide icons in config HTML)
|
|
1721
|
+
"svg",
|
|
1722
|
+
"path",
|
|
1723
|
+
"circle",
|
|
1724
|
+
"line",
|
|
1725
|
+
"polyline",
|
|
1726
|
+
"polygon",
|
|
1727
|
+
"rect",
|
|
1728
|
+
"g"
|
|
1670
1729
|
]);
|
|
1671
1730
|
function sanitizeHtml2(html) {
|
|
1672
1731
|
var _a2;
|
|
@@ -1875,8 +1934,14 @@ var executeModal = async (action, context) => {
|
|
|
1875
1934
|
modal2.style.transform = "translate(-50%, -50%) scale(0.95)";
|
|
1876
1935
|
scrimEl.style.opacity = "0";
|
|
1877
1936
|
setTimeout(() => {
|
|
1878
|
-
|
|
1879
|
-
|
|
1937
|
+
try {
|
|
1938
|
+
modal2.remove();
|
|
1939
|
+
} catch {
|
|
1940
|
+
}
|
|
1941
|
+
try {
|
|
1942
|
+
scrimEl.remove();
|
|
1943
|
+
} catch {
|
|
1944
|
+
}
|
|
1880
1945
|
}, 200);
|
|
1881
1946
|
context.publishEvent("action.modal_dismissed", {
|
|
1882
1947
|
actionClicked
|
|
@@ -1923,10 +1988,12 @@ function getAnchorReference(anchorEl) {
|
|
|
1923
1988
|
}
|
|
1924
1989
|
function showTooltip(anchorEl, overlayRoot, opts) {
|
|
1925
1990
|
var _a2;
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1991
|
+
if (!opts.trigger || opts.trigger === "immediate") {
|
|
1992
|
+
const rect = anchorEl.getBoundingClientRect();
|
|
1993
|
+
const isLargeElement = rect.width > window.innerWidth * 0.8 || rect.height > window.innerHeight * 0.8;
|
|
1994
|
+
if (!isLargeElement) {
|
|
1995
|
+
anchorEl.scrollIntoView({ behavior: "smooth", block: "center", inline: "center" });
|
|
1996
|
+
}
|
|
1930
1997
|
}
|
|
1931
1998
|
const div = document.createElement("div");
|
|
1932
1999
|
div.className = "syntro-tooltip";
|
|
@@ -2136,7 +2203,12 @@ function showTooltip(anchorEl, overlayRoot, opts) {
|
|
|
2136
2203
|
}
|
|
2137
2204
|
div.style.pointerEvents = "none";
|
|
2138
2205
|
div.style.opacity = "0";
|
|
2139
|
-
setTimeout(() =>
|
|
2206
|
+
setTimeout(() => {
|
|
2207
|
+
try {
|
|
2208
|
+
div.remove();
|
|
2209
|
+
} catch {
|
|
2210
|
+
}
|
|
2211
|
+
}, 200);
|
|
2140
2212
|
}
|
|
2141
2213
|
};
|
|
2142
2214
|
return handle;
|
|
@@ -2169,7 +2241,7 @@ function WorkflowTracker({ workflows, expanded, onStepClick, onDismiss }) {
|
|
|
2169
2241
|
}
|
|
2170
2242
|
|
|
2171
2243
|
// ../adaptives/adaptive-overlays/dist/WorkflowWidget.js
|
|
2172
|
-
function showWorkflowToast(
|
|
2244
|
+
function showWorkflowToast(notification) {
|
|
2173
2245
|
const toast = document.createElement("div");
|
|
2174
2246
|
toast.setAttribute("data-testid", "workflow-toast");
|
|
2175
2247
|
toast.className = "se-fixed se-bottom-4 se-right-4 se-z-50";
|
|
@@ -2203,7 +2275,7 @@ function showWorkflowToast(container, notification) {
|
|
|
2203
2275
|
bodyEl.textContent = notification.body;
|
|
2204
2276
|
toast.appendChild(bodyEl);
|
|
2205
2277
|
}
|
|
2206
|
-
|
|
2278
|
+
document.body.appendChild(toast);
|
|
2207
2279
|
let removeTimer;
|
|
2208
2280
|
const fadeTimer = setTimeout(() => {
|
|
2209
2281
|
toast.style.opacity = "0";
|
|
@@ -2302,10 +2374,10 @@ function WorkflowWidgetInner({ runtime: runtime3 }) {
|
|
|
2302
2374
|
return newEntries.length > 0 ? [...prev, ...newEntries] : prev;
|
|
2303
2375
|
});
|
|
2304
2376
|
for (const [tourId, { meta }] of tourWorkflows) {
|
|
2305
|
-
if (!notifiedRef.current.has(tourId) && meta.notification &&
|
|
2377
|
+
if (!notifiedRef.current.has(tourId) && meta.notification && !dismissed.includes(tourId) && !completed[tourId]) {
|
|
2306
2378
|
notifiedRef.current.add(tourId);
|
|
2307
2379
|
(_c = stateNs == null ? void 0 : stateNs.set) == null ? void 0 : _c.call(stateNs, "notified", [...notifiedRef.current]);
|
|
2308
|
-
const cleanup = showWorkflowToast(
|
|
2380
|
+
const cleanup = showWorkflowToast(meta.notification);
|
|
2309
2381
|
toastCleanupsRef.current.push(cleanup);
|
|
2310
2382
|
}
|
|
2311
2383
|
}
|
|
@@ -2338,8 +2410,8 @@ function WorkflowWidgetInner({ runtime: runtime3 }) {
|
|
|
2338
2410
|
notifiedRef.current.add(tourId);
|
|
2339
2411
|
(_c = stateNs == null ? void 0 : stateNs.set) == null ? void 0 : _c.call(stateNs, "notified", [...notifiedRef.current]);
|
|
2340
2412
|
const workflow = currentWorkflows.get(tourId);
|
|
2341
|
-
if (
|
|
2342
|
-
const cleanup = showWorkflowToast(
|
|
2413
|
+
if (workflow == null ? void 0 : workflow.meta.notification) {
|
|
2414
|
+
const cleanup = showWorkflowToast(workflow.meta.notification);
|
|
2343
2415
|
toastCleanupsRef.current.push(cleanup);
|
|
2344
2416
|
}
|
|
2345
2417
|
}
|
|
@@ -2443,6 +2515,10 @@ var executeHighlight = async (action, context) => {
|
|
|
2443
2515
|
return { cleanup: () => {
|
|
2444
2516
|
} };
|
|
2445
2517
|
}
|
|
2518
|
+
if (anchorEl.getAttribute("data-syntro-highlight-dismissed")) {
|
|
2519
|
+
return { cleanup: () => {
|
|
2520
|
+
} };
|
|
2521
|
+
}
|
|
2446
2522
|
const existing = anchorEl.getAttribute("data-syntro-highlight");
|
|
2447
2523
|
if (existing) {
|
|
2448
2524
|
const prev = context.overlayRoot.querySelectorAll(".syntro-spotlight-scrim, .syntro-spotlight-ring");
|
|
@@ -2465,7 +2541,10 @@ var executeHighlight = async (action, context) => {
|
|
|
2465
2541
|
ringColor,
|
|
2466
2542
|
blocking: (_i = action.blocking) != null ? _i : false,
|
|
2467
2543
|
onClickOutside: (_j = action.onClickOutside) != null ? _j : true,
|
|
2468
|
-
onEsc: (_k = action.onEsc) != null ? _k : true
|
|
2544
|
+
onEsc: (_k = action.onEsc) != null ? _k : true,
|
|
2545
|
+
onDismiss: () => {
|
|
2546
|
+
anchorEl.setAttribute("data-syntro-highlight-dismissed", "true");
|
|
2547
|
+
}
|
|
2469
2548
|
});
|
|
2470
2549
|
context.publishEvent("action.applied", {
|
|
2471
2550
|
id: context.generateId(),
|
|
@@ -2476,6 +2555,7 @@ var executeHighlight = async (action, context) => {
|
|
|
2476
2555
|
cleanup: () => {
|
|
2477
2556
|
handle.destroy();
|
|
2478
2557
|
anchorEl.removeAttribute("data-syntro-highlight");
|
|
2558
|
+
anchorEl.removeAttribute("data-syntro-highlight-dismissed");
|
|
2479
2559
|
}
|
|
2480
2560
|
};
|
|
2481
2561
|
};
|
|
@@ -2565,6 +2645,8 @@ var executePulse = async (action, context) => {
|
|
|
2565
2645
|
return {
|
|
2566
2646
|
cleanup: () => {
|
|
2567
2647
|
clearTimeout(timeoutId);
|
|
2648
|
+
if (!anchorEl.isConnected)
|
|
2649
|
+
return;
|
|
2568
2650
|
anchorEl.style.animation = originalAnimation;
|
|
2569
2651
|
anchorEl.removeAttribute("data-syntro-pulse");
|
|
2570
2652
|
}
|
|
@@ -2634,7 +2716,12 @@ var executeBadge = async (action, context) => {
|
|
|
2634
2716
|
});
|
|
2635
2717
|
return {
|
|
2636
2718
|
cleanup: () => {
|
|
2637
|
-
|
|
2719
|
+
try {
|
|
2720
|
+
badge2.remove();
|
|
2721
|
+
} catch {
|
|
2722
|
+
}
|
|
2723
|
+
if (!anchorEl.isConnected)
|
|
2724
|
+
return;
|
|
2638
2725
|
if (originalPosition !== void 0) {
|
|
2639
2726
|
anchorEl.style.position = originalPosition;
|
|
2640
2727
|
}
|
|
@@ -2851,6 +2938,14 @@ var CORE_ACTION_KINDS = /* @__PURE__ */ new Set([
|
|
|
2851
2938
|
"core:parallel",
|
|
2852
2939
|
"core:tour"
|
|
2853
2940
|
]);
|
|
2941
|
+
var BUNDLED_APP_IDS = /* @__PURE__ */ new Set([
|
|
2942
|
+
"adaptive-chatbot",
|
|
2943
|
+
"adaptive-content",
|
|
2944
|
+
"adaptive-faq",
|
|
2945
|
+
"adaptive-gamification",
|
|
2946
|
+
"adaptive-nav",
|
|
2947
|
+
"adaptive-overlays"
|
|
2948
|
+
]);
|
|
2854
2949
|
var NAMESPACE_TO_APP_ID = {
|
|
2855
2950
|
faq: "adaptive-faq",
|
|
2856
2951
|
nav: "adaptive-nav",
|
|
@@ -3003,6 +3098,9 @@ function createAppLoader(options) {
|
|
|
3003
3098
|
}
|
|
3004
3099
|
}
|
|
3005
3100
|
}
|
|
3101
|
+
for (const bundled of BUNDLED_APP_IDS) {
|
|
3102
|
+
appIds.delete(bundled);
|
|
3103
|
+
}
|
|
3006
3104
|
return Array.from(appIds);
|
|
3007
3105
|
}
|
|
3008
3106
|
async function loadAppsForConfig(config) {
|
|
@@ -3358,7 +3456,7 @@ function getAntiFlickerSnippet(config = {}) {
|
|
|
3358
3456
|
}
|
|
3359
3457
|
|
|
3360
3458
|
// src/version.ts
|
|
3361
|
-
var SDK_VERSION = "2.8.0-canary.
|
|
3459
|
+
var SDK_VERSION = "2.8.0-canary.41";
|
|
3362
3460
|
|
|
3363
3461
|
// src/types.ts
|
|
3364
3462
|
var SDK_SCHEMA_VERSION = "2.0";
|
|
@@ -3641,7 +3739,8 @@ function registerFromTriggerWhen(triggerWhen, accumulator) {
|
|
|
3641
3739
|
if (cond.type === "event_count" && cond.key) {
|
|
3642
3740
|
const counter = cond.counter;
|
|
3643
3741
|
const predicate = counter ? buildPredicate(counter) : () => true;
|
|
3644
|
-
|
|
3742
|
+
const needsTimestamps = typeof cond.withinMs === "number";
|
|
3743
|
+
accumulator.register(cond.key, predicate, needsTimestamps);
|
|
3645
3744
|
}
|
|
3646
3745
|
}
|
|
3647
3746
|
}
|
|
@@ -3734,8 +3833,529 @@ function useShadowRoot() {
|
|
|
3734
3833
|
return ctx;
|
|
3735
3834
|
}
|
|
3736
3835
|
|
|
3737
|
-
//
|
|
3836
|
+
// ../event-processor/dist/types.js
|
|
3837
|
+
var EVENT_SCHEMA_VERSION = "1.0.0";
|
|
3738
3838
|
var StandardEvents = {
|
|
3839
|
+
UI_CLICK: "ui.click",
|
|
3840
|
+
UI_SCROLL: "ui.scroll",
|
|
3841
|
+
UI_INPUT: "ui.input",
|
|
3842
|
+
UI_CHANGE: "ui.change",
|
|
3843
|
+
UI_SUBMIT: "ui.submit",
|
|
3844
|
+
NAV_PAGE_VIEW: "nav.page_view",
|
|
3845
|
+
NAV_PAGE_LEAVE: "nav.page_leave",
|
|
3846
|
+
UI_HESITATE: "ui.hesitate",
|
|
3847
|
+
UI_RAGE_CLICK: "ui.rage_click",
|
|
3848
|
+
UI_SCROLL_THRASH: "ui.scroll_thrash",
|
|
3849
|
+
UI_FOCUS_BOUNCE: "ui.focus_bounce",
|
|
3850
|
+
UI_IDLE: "ui.idle",
|
|
3851
|
+
UI_HOVER: "ui.hover"
|
|
3852
|
+
};
|
|
3853
|
+
var RRWebSource = {
|
|
3854
|
+
Mutation: 0,
|
|
3855
|
+
MouseMove: 1,
|
|
3856
|
+
MouseInteraction: 2,
|
|
3857
|
+
Scroll: 3,
|
|
3858
|
+
ViewportResize: 4,
|
|
3859
|
+
Input: 5,
|
|
3860
|
+
TouchMove: 6,
|
|
3861
|
+
MediaInteraction: 7,
|
|
3862
|
+
Drag: 12
|
|
3863
|
+
};
|
|
3864
|
+
var RRWebMouseInteraction = {
|
|
3865
|
+
MouseUp: 0,
|
|
3866
|
+
MouseDown: 1,
|
|
3867
|
+
Click: 2,
|
|
3868
|
+
ContextMenu: 3,
|
|
3869
|
+
DblClick: 4,
|
|
3870
|
+
Focus: 5,
|
|
3871
|
+
Blur: 6,
|
|
3872
|
+
TouchStart: 7,
|
|
3873
|
+
TouchEnd: 9
|
|
3874
|
+
};
|
|
3875
|
+
var DEFAULT_DETECTOR_CONFIG = {
|
|
3876
|
+
hesitationMs: 3e3,
|
|
3877
|
+
hesitationRadiusPx: 10,
|
|
3878
|
+
rageClickCount: 3,
|
|
3879
|
+
rageClickWindowMs: 1e3,
|
|
3880
|
+
rageClickRadiusPx: 30,
|
|
3881
|
+
scrollThrashReversals: 3,
|
|
3882
|
+
scrollThrashWindowMs: 2e3,
|
|
3883
|
+
focusBounceMaxInputs: 0,
|
|
3884
|
+
idleMs: 5e3,
|
|
3885
|
+
hoverSampleMs: 100
|
|
3886
|
+
};
|
|
3887
|
+
|
|
3888
|
+
// ../event-processor/dist/normalizers/posthog.js
|
|
3889
|
+
var POSTHOG_EVENT_MAP = {
|
|
3890
|
+
// NOTE: $autocapture is intentionally NOT in this map.
|
|
3891
|
+
// It's handled below in getEventName() with $event_type refinement
|
|
3892
|
+
// so that change/submit events aren't all mapped to ui.click.
|
|
3893
|
+
$click: StandardEvents.UI_CLICK,
|
|
3894
|
+
$scroll: StandardEvents.UI_SCROLL,
|
|
3895
|
+
$input: StandardEvents.UI_INPUT,
|
|
3896
|
+
$change: StandardEvents.UI_CHANGE,
|
|
3897
|
+
$submit: StandardEvents.UI_SUBMIT,
|
|
3898
|
+
// Navigation events
|
|
3899
|
+
$pageview: StandardEvents.NAV_PAGE_VIEW,
|
|
3900
|
+
$pageleave: StandardEvents.NAV_PAGE_LEAVE,
|
|
3901
|
+
// Session events
|
|
3902
|
+
$session_start: "session.start",
|
|
3903
|
+
// Identify events
|
|
3904
|
+
$identify: "user.identify"
|
|
3905
|
+
};
|
|
3906
|
+
function getEventName(phEvent) {
|
|
3907
|
+
var _a2, _b;
|
|
3908
|
+
const eventName = phEvent.event;
|
|
3909
|
+
if (typeof eventName !== "string") {
|
|
3910
|
+
return "posthog.unknown";
|
|
3911
|
+
}
|
|
3912
|
+
if (POSTHOG_EVENT_MAP[eventName]) {
|
|
3913
|
+
return POSTHOG_EVENT_MAP[eventName];
|
|
3914
|
+
}
|
|
3915
|
+
if (eventName === "$autocapture") {
|
|
3916
|
+
const tagName = (_a2 = phEvent.properties) == null ? void 0 : _a2.$tag_name;
|
|
3917
|
+
const eventType = (_b = phEvent.properties) == null ? void 0 : _b.$event_type;
|
|
3918
|
+
if (eventType === "submit")
|
|
3919
|
+
return StandardEvents.UI_SUBMIT;
|
|
3920
|
+
if (eventType === "change")
|
|
3921
|
+
return StandardEvents.UI_CHANGE;
|
|
3922
|
+
if (tagName === "input" || tagName === "textarea")
|
|
3923
|
+
return StandardEvents.UI_INPUT;
|
|
3924
|
+
return StandardEvents.UI_CLICK;
|
|
3925
|
+
}
|
|
3926
|
+
if (!eventName.startsWith("$")) {
|
|
3927
|
+
return `posthog.${eventName}`;
|
|
3928
|
+
}
|
|
3929
|
+
return eventName.replace("$", "posthog.");
|
|
3930
|
+
}
|
|
3931
|
+
var INTERACTIVE_TAGS = /* @__PURE__ */ new Set(["a", "button", "input", "select", "textarea"]);
|
|
3932
|
+
function resolveInteractiveTag(elements, directTag) {
|
|
3933
|
+
if (directTag && INTERACTIVE_TAGS.has(directTag))
|
|
3934
|
+
return directTag;
|
|
3935
|
+
if (!elements)
|
|
3936
|
+
return directTag;
|
|
3937
|
+
for (const el of elements) {
|
|
3938
|
+
const tag2 = el.tag_name;
|
|
3939
|
+
if (tag2 && INTERACTIVE_TAGS.has(tag2))
|
|
3940
|
+
return tag2;
|
|
3941
|
+
}
|
|
3942
|
+
return directTag;
|
|
3943
|
+
}
|
|
3944
|
+
function extractProps(phEvent) {
|
|
3945
|
+
var _a2, _b;
|
|
3946
|
+
const props = {};
|
|
3947
|
+
const phProps = phEvent.properties || {};
|
|
3948
|
+
const elements = phProps.$elements;
|
|
3949
|
+
const directTag = (_b = phProps.$tag_name) != null ? _b : (_a2 = elements == null ? void 0 : elements[0]) == null ? void 0 : _a2.tag_name;
|
|
3950
|
+
const isClickEvent = phEvent.event === "$autocapture" || phEvent.event === "$click";
|
|
3951
|
+
props.tagName = isClickEvent ? resolveInteractiveTag(elements, directTag) : directTag;
|
|
3952
|
+
if (phProps.$el_text)
|
|
3953
|
+
props.elementText = phProps.$el_text;
|
|
3954
|
+
if (elements)
|
|
3955
|
+
props.elements = elements;
|
|
3956
|
+
if (phProps.$current_url)
|
|
3957
|
+
props.url = phProps.$current_url;
|
|
3958
|
+
if (phProps.$pathname)
|
|
3959
|
+
props.pathname = phProps.$pathname;
|
|
3960
|
+
if (phProps.$host)
|
|
3961
|
+
props.host = phProps.$host;
|
|
3962
|
+
if (phProps.$viewport_width)
|
|
3963
|
+
props.viewportWidth = phProps.$viewport_width;
|
|
3964
|
+
if (phProps.$viewport_height)
|
|
3965
|
+
props.viewportHeight = phProps.$viewport_height;
|
|
3966
|
+
if (phProps.$session_id)
|
|
3967
|
+
props.sessionId = phProps.$session_id;
|
|
3968
|
+
if (phProps.$scroll_depth)
|
|
3969
|
+
props.scrollDepth = phProps.$scroll_depth;
|
|
3970
|
+
if (phProps.$scroll_percentage)
|
|
3971
|
+
props.scrollPercentage = phProps.$scroll_percentage;
|
|
3972
|
+
props.originalEvent = phEvent.event;
|
|
3973
|
+
return props;
|
|
3974
|
+
}
|
|
3975
|
+
function normalizePostHogEvent(phEvent) {
|
|
3976
|
+
let ts;
|
|
3977
|
+
if (typeof phEvent.timestamp === "number") {
|
|
3978
|
+
ts = phEvent.timestamp;
|
|
3979
|
+
} else if (typeof phEvent.timestamp === "string") {
|
|
3980
|
+
ts = new Date(phEvent.timestamp).getTime();
|
|
3981
|
+
} else {
|
|
3982
|
+
ts = Date.now();
|
|
3983
|
+
}
|
|
3984
|
+
return {
|
|
3985
|
+
ts,
|
|
3986
|
+
name: getEventName(phEvent),
|
|
3987
|
+
source: "posthog",
|
|
3988
|
+
props: extractProps(phEvent),
|
|
3989
|
+
schemaVersion: EVENT_SCHEMA_VERSION
|
|
3990
|
+
};
|
|
3991
|
+
}
|
|
3992
|
+
function shouldNormalizeEvent(phEvent) {
|
|
3993
|
+
const eventName = phEvent.event;
|
|
3994
|
+
if (typeof eventName !== "string")
|
|
3995
|
+
return false;
|
|
3996
|
+
const skipEvents = [
|
|
3997
|
+
"$feature_flag_called",
|
|
3998
|
+
"$feature_flags",
|
|
3999
|
+
"$groups",
|
|
4000
|
+
"$groupidentify",
|
|
4001
|
+
"$set",
|
|
4002
|
+
"$set_once",
|
|
4003
|
+
"$unset",
|
|
4004
|
+
"$create_alias",
|
|
4005
|
+
"$capture_metrics",
|
|
4006
|
+
"$performance_event",
|
|
4007
|
+
"$web_vitals",
|
|
4008
|
+
"$exception",
|
|
4009
|
+
"$dead_click",
|
|
4010
|
+
"$heatmap"
|
|
4011
|
+
];
|
|
4012
|
+
if (skipEvents.includes(eventName)) {
|
|
4013
|
+
return false;
|
|
4014
|
+
}
|
|
4015
|
+
return true;
|
|
4016
|
+
}
|
|
4017
|
+
function createPostHogNormalizer(publishFn) {
|
|
4018
|
+
return (eventName, properties) => {
|
|
4019
|
+
if (typeof eventName !== "string")
|
|
4020
|
+
return;
|
|
4021
|
+
const phEvent = {
|
|
4022
|
+
event: eventName,
|
|
4023
|
+
properties,
|
|
4024
|
+
timestamp: Date.now()
|
|
4025
|
+
};
|
|
4026
|
+
if (shouldNormalizeEvent(phEvent)) {
|
|
4027
|
+
const normalizedEvent = normalizePostHogEvent(phEvent);
|
|
4028
|
+
publishFn(normalizedEvent);
|
|
4029
|
+
}
|
|
4030
|
+
};
|
|
4031
|
+
}
|
|
4032
|
+
|
|
4033
|
+
// ../event-processor/dist/detectors/focus-bounce.js
|
|
4034
|
+
var FocusBounceDetector = class {
|
|
4035
|
+
constructor(config, emit2) {
|
|
4036
|
+
this.config = config;
|
|
4037
|
+
this.emit = emit2;
|
|
4038
|
+
this.focused = /* @__PURE__ */ new Map();
|
|
4039
|
+
}
|
|
4040
|
+
ingest(raw) {
|
|
4041
|
+
var _a2, _b;
|
|
4042
|
+
if (raw.type !== 3)
|
|
4043
|
+
return;
|
|
4044
|
+
const ts = raw.timestamp;
|
|
4045
|
+
if (raw.data.source === RRWebSource.MouseInteraction) {
|
|
4046
|
+
const id = (_a2 = raw.data.id) != null ? _a2 : 0;
|
|
4047
|
+
if (raw.data.type === RRWebMouseInteraction.Focus) {
|
|
4048
|
+
this.focused.set(id, { id, focusTs: ts, inputCount: 0 });
|
|
4049
|
+
} else if (raw.data.type === RRWebMouseInteraction.Blur) {
|
|
4050
|
+
const entry = this.focused.get(id);
|
|
4051
|
+
if (entry && entry.inputCount <= this.config.focusBounceMaxInputs) {
|
|
4052
|
+
this.emit({
|
|
4053
|
+
ts,
|
|
4054
|
+
name: StandardEvents.UI_FOCUS_BOUNCE,
|
|
4055
|
+
source: "rrweb",
|
|
4056
|
+
schemaVersion: EVENT_SCHEMA_VERSION,
|
|
4057
|
+
props: {
|
|
4058
|
+
elementId: id,
|
|
4059
|
+
duration_ms: ts - entry.focusTs
|
|
4060
|
+
}
|
|
4061
|
+
});
|
|
4062
|
+
}
|
|
4063
|
+
this.focused.delete(id);
|
|
4064
|
+
}
|
|
4065
|
+
} else if (raw.data.source === RRWebSource.Input) {
|
|
4066
|
+
const id = (_b = raw.data.id) != null ? _b : 0;
|
|
4067
|
+
const entry = this.focused.get(id);
|
|
4068
|
+
if (entry) {
|
|
4069
|
+
entry.inputCount++;
|
|
4070
|
+
}
|
|
4071
|
+
}
|
|
4072
|
+
}
|
|
4073
|
+
};
|
|
4074
|
+
|
|
4075
|
+
// ../event-processor/dist/detectors/hesitation.js
|
|
4076
|
+
var HesitationDetector = class {
|
|
4077
|
+
constructor(config, emit2) {
|
|
4078
|
+
this.config = config;
|
|
4079
|
+
this.emit = emit2;
|
|
4080
|
+
this.anchorX = 0;
|
|
4081
|
+
this.anchorY = 0;
|
|
4082
|
+
this.anchorTs = 0;
|
|
4083
|
+
this.emitted = false;
|
|
4084
|
+
this.hasPosition = false;
|
|
4085
|
+
}
|
|
4086
|
+
ingest(raw) {
|
|
4087
|
+
var _a2;
|
|
4088
|
+
if (raw.type !== 3 || raw.data.source !== RRWebSource.MouseMove)
|
|
4089
|
+
return;
|
|
4090
|
+
const positions = raw.data.positions;
|
|
4091
|
+
if (!positions || positions.length === 0)
|
|
4092
|
+
return;
|
|
4093
|
+
const last = positions[positions.length - 1];
|
|
4094
|
+
const ts = raw.timestamp + ((_a2 = last.timeOffset) != null ? _a2 : 0);
|
|
4095
|
+
if (!this.hasPosition) {
|
|
4096
|
+
this.anchorX = last.x;
|
|
4097
|
+
this.anchorY = last.y;
|
|
4098
|
+
this.anchorTs = ts;
|
|
4099
|
+
this.hasPosition = true;
|
|
4100
|
+
this.emitted = false;
|
|
4101
|
+
return;
|
|
4102
|
+
}
|
|
4103
|
+
const dx = last.x - this.anchorX;
|
|
4104
|
+
const dy = last.y - this.anchorY;
|
|
4105
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
4106
|
+
if (dist > this.config.hesitationRadiusPx) {
|
|
4107
|
+
this.anchorX = last.x;
|
|
4108
|
+
this.anchorY = last.y;
|
|
4109
|
+
this.anchorTs = ts;
|
|
4110
|
+
this.emitted = false;
|
|
4111
|
+
}
|
|
4112
|
+
}
|
|
4113
|
+
tick(now) {
|
|
4114
|
+
if (!this.hasPosition || this.emitted)
|
|
4115
|
+
return;
|
|
4116
|
+
const elapsed = now - this.anchorTs;
|
|
4117
|
+
if (elapsed >= this.config.hesitationMs) {
|
|
4118
|
+
this.emit({
|
|
4119
|
+
ts: now,
|
|
4120
|
+
name: StandardEvents.UI_HESITATE,
|
|
4121
|
+
source: "rrweb",
|
|
4122
|
+
schemaVersion: EVENT_SCHEMA_VERSION,
|
|
4123
|
+
props: {
|
|
4124
|
+
x: this.anchorX,
|
|
4125
|
+
y: this.anchorY,
|
|
4126
|
+
duration_ms: elapsed
|
|
4127
|
+
}
|
|
4128
|
+
});
|
|
4129
|
+
this.emitted = true;
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4132
|
+
};
|
|
4133
|
+
|
|
4134
|
+
// ../event-processor/dist/detectors/hover.js
|
|
4135
|
+
var HoverTracker = class {
|
|
4136
|
+
constructor(config, emit2, elementResolver) {
|
|
4137
|
+
this.config = config;
|
|
4138
|
+
this.emit = emit2;
|
|
4139
|
+
this.elementResolver = elementResolver;
|
|
4140
|
+
this.currentElement = null;
|
|
4141
|
+
this.hoverStartTs = null;
|
|
4142
|
+
this.lastX = 0;
|
|
4143
|
+
this.lastY = 0;
|
|
4144
|
+
this.lastSampleTs = -Infinity;
|
|
4145
|
+
}
|
|
4146
|
+
ingest(raw) {
|
|
4147
|
+
if (raw.type !== 3 || raw.data.source !== RRWebSource.MouseMove)
|
|
4148
|
+
return;
|
|
4149
|
+
const positions = raw.data.positions;
|
|
4150
|
+
if (!positions || positions.length === 0)
|
|
4151
|
+
return;
|
|
4152
|
+
const last = positions[positions.length - 1];
|
|
4153
|
+
this.lastX = last.x;
|
|
4154
|
+
this.lastY = last.y;
|
|
4155
|
+
}
|
|
4156
|
+
tick(now) {
|
|
4157
|
+
if (!this.elementResolver)
|
|
4158
|
+
return;
|
|
4159
|
+
if (now - this.lastSampleTs < this.config.hoverSampleMs)
|
|
4160
|
+
return;
|
|
4161
|
+
this.lastSampleTs = now;
|
|
4162
|
+
const newElement = this.elementResolver(this.lastX, this.lastY);
|
|
4163
|
+
const newKey = newElement ? elementKey(newElement) : null;
|
|
4164
|
+
const currentKey = this.currentElement ? elementKey(this.currentElement) : null;
|
|
4165
|
+
if (newKey !== currentKey) {
|
|
4166
|
+
if (this.currentElement && this.hoverStartTs !== null) {
|
|
4167
|
+
this.emit({
|
|
4168
|
+
ts: now,
|
|
4169
|
+
name: StandardEvents.UI_HOVER,
|
|
4170
|
+
source: "rrweb",
|
|
4171
|
+
schemaVersion: EVENT_SCHEMA_VERSION,
|
|
4172
|
+
props: {
|
|
4173
|
+
x: this.lastX,
|
|
4174
|
+
y: this.lastY,
|
|
4175
|
+
duration_ms: now - this.hoverStartTs,
|
|
4176
|
+
element: this.currentElement
|
|
4177
|
+
}
|
|
4178
|
+
});
|
|
4179
|
+
}
|
|
4180
|
+
this.currentElement = newElement;
|
|
4181
|
+
this.hoverStartTs = now;
|
|
4182
|
+
}
|
|
4183
|
+
}
|
|
4184
|
+
};
|
|
4185
|
+
function elementKey(el) {
|
|
4186
|
+
var _a2, _b, _c;
|
|
4187
|
+
return `${(_a2 = el.tag_name) != null ? _a2 : ""}|${(_b = el.attr__id) != null ? _b : ""}|${((_c = el.classes) != null ? _c : []).join(",")}`;
|
|
4188
|
+
}
|
|
4189
|
+
|
|
4190
|
+
// ../event-processor/dist/detectors/idle.js
|
|
4191
|
+
var IdleDetector = class {
|
|
4192
|
+
constructor(config, emit2) {
|
|
4193
|
+
this.config = config;
|
|
4194
|
+
this.emit = emit2;
|
|
4195
|
+
this.lastActivityTs = null;
|
|
4196
|
+
this.emitted = false;
|
|
4197
|
+
}
|
|
4198
|
+
ingest(raw) {
|
|
4199
|
+
if (raw.type !== 3)
|
|
4200
|
+
return;
|
|
4201
|
+
const src = raw.data.source;
|
|
4202
|
+
if (src === RRWebSource.MouseMove || src === RRWebSource.MouseInteraction || src === RRWebSource.Scroll) {
|
|
4203
|
+
this.lastActivityTs = raw.timestamp;
|
|
4204
|
+
this.emitted = false;
|
|
4205
|
+
}
|
|
4206
|
+
}
|
|
4207
|
+
tick(now) {
|
|
4208
|
+
if (this.lastActivityTs === null || this.emitted)
|
|
4209
|
+
return;
|
|
4210
|
+
if (now - this.lastActivityTs >= this.config.idleMs) {
|
|
4211
|
+
this.emit({
|
|
4212
|
+
ts: now,
|
|
4213
|
+
name: StandardEvents.UI_IDLE,
|
|
4214
|
+
source: "rrweb",
|
|
4215
|
+
schemaVersion: EVENT_SCHEMA_VERSION,
|
|
4216
|
+
props: {
|
|
4217
|
+
idle_ms: now - this.lastActivityTs
|
|
4218
|
+
}
|
|
4219
|
+
});
|
|
4220
|
+
this.emitted = true;
|
|
4221
|
+
}
|
|
4222
|
+
}
|
|
4223
|
+
};
|
|
4224
|
+
|
|
4225
|
+
// ../event-processor/dist/detectors/rage-click.js
|
|
4226
|
+
var RageClickDetector = class {
|
|
4227
|
+
constructor(config, emit2) {
|
|
4228
|
+
this.config = config;
|
|
4229
|
+
this.emit = emit2;
|
|
4230
|
+
this.clicks = [];
|
|
4231
|
+
}
|
|
4232
|
+
ingest(raw) {
|
|
4233
|
+
var _a2, _b;
|
|
4234
|
+
if (raw.type !== 3 || raw.data.source !== RRWebSource.MouseInteraction)
|
|
4235
|
+
return;
|
|
4236
|
+
if (raw.data.type !== RRWebMouseInteraction.Click)
|
|
4237
|
+
return;
|
|
4238
|
+
const x = (_a2 = raw.data.x) != null ? _a2 : 0;
|
|
4239
|
+
const y = (_b = raw.data.y) != null ? _b : 0;
|
|
4240
|
+
const ts = raw.timestamp;
|
|
4241
|
+
const cutoff = ts - this.config.rageClickWindowMs;
|
|
4242
|
+
this.clicks = this.clicks.filter((c) => c.ts >= cutoff);
|
|
4243
|
+
this.clicks.push({ ts, x, y });
|
|
4244
|
+
const nearby = this.clicks.filter((c) => {
|
|
4245
|
+
const dx = c.x - x;
|
|
4246
|
+
const dy = c.y - y;
|
|
4247
|
+
return Math.sqrt(dx * dx + dy * dy) <= this.config.rageClickRadiusPx;
|
|
4248
|
+
});
|
|
4249
|
+
if (nearby.length >= this.config.rageClickCount) {
|
|
4250
|
+
this.emit({
|
|
4251
|
+
ts,
|
|
4252
|
+
name: StandardEvents.UI_RAGE_CLICK,
|
|
4253
|
+
source: "rrweb",
|
|
4254
|
+
schemaVersion: EVENT_SCHEMA_VERSION,
|
|
4255
|
+
props: {
|
|
4256
|
+
x,
|
|
4257
|
+
y,
|
|
4258
|
+
clickCount: nearby.length,
|
|
4259
|
+
duration_ms: ts - nearby[0].ts
|
|
4260
|
+
}
|
|
4261
|
+
});
|
|
4262
|
+
this.clicks = [];
|
|
4263
|
+
}
|
|
4264
|
+
}
|
|
4265
|
+
};
|
|
4266
|
+
|
|
4267
|
+
// ../event-processor/dist/detectors/scroll-thrash.js
|
|
4268
|
+
var ScrollThrashDetector = class {
|
|
4269
|
+
constructor(config, emit2) {
|
|
4270
|
+
this.config = config;
|
|
4271
|
+
this.emit = emit2;
|
|
4272
|
+
this.lastY = null;
|
|
4273
|
+
this.lastDirection = null;
|
|
4274
|
+
this.reversals = [];
|
|
4275
|
+
}
|
|
4276
|
+
ingest(raw) {
|
|
4277
|
+
var _a2;
|
|
4278
|
+
if (raw.type !== 3 || raw.data.source !== RRWebSource.Scroll)
|
|
4279
|
+
return;
|
|
4280
|
+
const y = (_a2 = raw.data.y) != null ? _a2 : 0;
|
|
4281
|
+
const ts = raw.timestamp;
|
|
4282
|
+
if (this.lastY !== null) {
|
|
4283
|
+
const direction = y > this.lastY ? "down" : y < this.lastY ? "up" : this.lastDirection;
|
|
4284
|
+
if (direction && direction !== this.lastDirection) {
|
|
4285
|
+
const cutoff = ts - this.config.scrollThrashWindowMs;
|
|
4286
|
+
this.reversals = this.reversals.filter((t) => t > cutoff);
|
|
4287
|
+
this.reversals.push(ts);
|
|
4288
|
+
if (this.reversals.length >= this.config.scrollThrashReversals) {
|
|
4289
|
+
this.emit({
|
|
4290
|
+
ts,
|
|
4291
|
+
name: StandardEvents.UI_SCROLL_THRASH,
|
|
4292
|
+
source: "rrweb",
|
|
4293
|
+
schemaVersion: EVENT_SCHEMA_VERSION,
|
|
4294
|
+
props: {
|
|
4295
|
+
reversals: this.reversals.length,
|
|
4296
|
+
duration_ms: ts - this.reversals[0]
|
|
4297
|
+
}
|
|
4298
|
+
});
|
|
4299
|
+
this.reversals = [];
|
|
4300
|
+
}
|
|
4301
|
+
}
|
|
4302
|
+
this.lastDirection = direction;
|
|
4303
|
+
}
|
|
4304
|
+
this.lastY = y;
|
|
4305
|
+
}
|
|
4306
|
+
};
|
|
4307
|
+
|
|
4308
|
+
// ../event-processor/dist/processor.js
|
|
4309
|
+
function createEventProcessor(options) {
|
|
4310
|
+
const config = { ...DEFAULT_DETECTOR_CONFIG, ...options == null ? void 0 : options.config };
|
|
4311
|
+
const listeners = [];
|
|
4312
|
+
function emit2(event) {
|
|
4313
|
+
for (const cb of listeners)
|
|
4314
|
+
cb(event);
|
|
4315
|
+
}
|
|
4316
|
+
const hesitation = new HesitationDetector(config, emit2);
|
|
4317
|
+
const rageClick = new RageClickDetector(config, emit2);
|
|
4318
|
+
const scrollThrash = new ScrollThrashDetector(config, emit2);
|
|
4319
|
+
const focusBounce = new FocusBounceDetector(config, emit2);
|
|
4320
|
+
const idle = new IdleDetector(config, emit2);
|
|
4321
|
+
const hover = new HoverTracker(config, emit2, options == null ? void 0 : options.elementResolver);
|
|
4322
|
+
const clickAttrBuffer = [];
|
|
4323
|
+
return {
|
|
4324
|
+
ingest(raw) {
|
|
4325
|
+
if (raw.kind === "posthog") {
|
|
4326
|
+
const { kind: _, ...phEvent } = raw;
|
|
4327
|
+
if (shouldNormalizeEvent(phEvent)) {
|
|
4328
|
+
emit2(normalizePostHogEvent(phEvent));
|
|
4329
|
+
}
|
|
4330
|
+
} else if (raw.kind === "rrweb") {
|
|
4331
|
+
hesitation.ingest(raw);
|
|
4332
|
+
rageClick.ingest(raw);
|
|
4333
|
+
scrollThrash.ingest(raw);
|
|
4334
|
+
focusBounce.ingest(raw);
|
|
4335
|
+
idle.ingest(raw);
|
|
4336
|
+
hover.ingest(raw);
|
|
4337
|
+
}
|
|
4338
|
+
},
|
|
4339
|
+
onEvent(callback) {
|
|
4340
|
+
listeners.push(callback);
|
|
4341
|
+
},
|
|
4342
|
+
tick(timestamp) {
|
|
4343
|
+
hesitation.tick(timestamp);
|
|
4344
|
+
idle.tick(timestamp);
|
|
4345
|
+
hover.tick(timestamp);
|
|
4346
|
+
},
|
|
4347
|
+
enrichClickAttributes(timestamp, elements) {
|
|
4348
|
+
clickAttrBuffer.push({ ts: timestamp, elements });
|
|
4349
|
+
const cutoff = timestamp - 500;
|
|
4350
|
+
while (clickAttrBuffer.length > 0 && clickAttrBuffer[0].ts < cutoff) {
|
|
4351
|
+
clickAttrBuffer.shift();
|
|
4352
|
+
}
|
|
4353
|
+
}
|
|
4354
|
+
};
|
|
4355
|
+
}
|
|
4356
|
+
|
|
4357
|
+
// src/events/types.ts
|
|
4358
|
+
var StandardEvents2 = {
|
|
3739
4359
|
// UI events (from PostHog autocapture)
|
|
3740
4360
|
UI_CLICK: "ui.click",
|
|
3741
4361
|
UI_SCROLL: "ui.scroll",
|
|
@@ -3775,7 +4395,6 @@ var StandardEvents = {
|
|
|
3775
4395
|
SURFACE_MOUNTED: "surface.mounted",
|
|
3776
4396
|
SURFACE_UNMOUNTED: "surface.unmounted"
|
|
3777
4397
|
};
|
|
3778
|
-
var EVENT_SCHEMA_VERSION = "1.0.0";
|
|
3779
4398
|
|
|
3780
4399
|
// src/events/normalizers/canvas.ts
|
|
3781
4400
|
function createCanvasEvent(name, props) {
|
|
@@ -3788,48 +4407,48 @@ function createCanvasEvent(name, props) {
|
|
|
3788
4407
|
};
|
|
3789
4408
|
}
|
|
3790
4409
|
function canvasOpened(surface) {
|
|
3791
|
-
return createCanvasEvent(
|
|
4410
|
+
return createCanvasEvent(StandardEvents2.CANVAS_OPENED, { surface });
|
|
3792
4411
|
}
|
|
3793
4412
|
function canvasClosed(surface) {
|
|
3794
|
-
return createCanvasEvent(
|
|
4413
|
+
return createCanvasEvent(StandardEvents2.CANVAS_CLOSED, { surface });
|
|
3795
4414
|
}
|
|
3796
4415
|
function tileViewed(tileId, surface) {
|
|
3797
|
-
return createCanvasEvent(
|
|
4416
|
+
return createCanvasEvent(StandardEvents2.TILE_VIEWED, { tileId, surface });
|
|
3798
4417
|
}
|
|
3799
4418
|
function tileExpanded(tileId, surface) {
|
|
3800
|
-
return createCanvasEvent(
|
|
4419
|
+
return createCanvasEvent(StandardEvents2.TILE_EXPANDED, { tileId, surface });
|
|
3801
4420
|
}
|
|
3802
4421
|
function tileCollapsed(tileId, surface) {
|
|
3803
|
-
return createCanvasEvent(
|
|
4422
|
+
return createCanvasEvent(StandardEvents2.TILE_COLLAPSED, { tileId, surface });
|
|
3804
4423
|
}
|
|
3805
4424
|
function tileAction(tileId, actionId, surface) {
|
|
3806
|
-
return createCanvasEvent(
|
|
4425
|
+
return createCanvasEvent(StandardEvents2.TILE_ACTION, {
|
|
3807
4426
|
tileId,
|
|
3808
4427
|
actionId,
|
|
3809
4428
|
surface
|
|
3810
4429
|
});
|
|
3811
4430
|
}
|
|
3812
4431
|
function overlayStarted(recipeId, recipeName) {
|
|
3813
|
-
return createCanvasEvent(
|
|
4432
|
+
return createCanvasEvent(StandardEvents2.OVERLAY_STARTED, {
|
|
3814
4433
|
recipeId,
|
|
3815
4434
|
recipeName
|
|
3816
4435
|
});
|
|
3817
4436
|
}
|
|
3818
4437
|
function overlayCompleted(recipeId, recipeName) {
|
|
3819
|
-
return createCanvasEvent(
|
|
4438
|
+
return createCanvasEvent(StandardEvents2.OVERLAY_COMPLETED, {
|
|
3820
4439
|
recipeId,
|
|
3821
4440
|
recipeName
|
|
3822
4441
|
});
|
|
3823
4442
|
}
|
|
3824
4443
|
function overlayDismissed(recipeId, recipeName, stepIndex) {
|
|
3825
|
-
return createCanvasEvent(
|
|
4444
|
+
return createCanvasEvent(StandardEvents2.OVERLAY_DISMISSED, {
|
|
3826
4445
|
recipeId,
|
|
3827
4446
|
recipeName,
|
|
3828
4447
|
stepIndex
|
|
3829
4448
|
});
|
|
3830
4449
|
}
|
|
3831
4450
|
function overlayStepViewed(recipeId, stepIndex, stepTitle) {
|
|
3832
|
-
return createCanvasEvent(
|
|
4451
|
+
return createCanvasEvent(StandardEvents2.OVERLAY_STEP_VIEWED, {
|
|
3833
4452
|
recipeId,
|
|
3834
4453
|
stepIndex,
|
|
3835
4454
|
stepTitle
|
|
@@ -3853,8 +4472,65 @@ var CanvasEvents = {
|
|
|
3853
4472
|
custom: customCanvasEvent
|
|
3854
4473
|
};
|
|
3855
4474
|
|
|
3856
|
-
// src/
|
|
3857
|
-
import {
|
|
4475
|
+
// src/components/emojiToIcon.tsx
|
|
4476
|
+
import {
|
|
4477
|
+
AlertTriangle,
|
|
4478
|
+
ArrowRight,
|
|
4479
|
+
Banknote,
|
|
4480
|
+
Bell,
|
|
4481
|
+
BookOpen,
|
|
4482
|
+
CheckCircle,
|
|
4483
|
+
ClipboardList,
|
|
4484
|
+
Compass,
|
|
4485
|
+
FileText,
|
|
4486
|
+
Gamepad2,
|
|
4487
|
+
HelpCircle,
|
|
4488
|
+
Landmark,
|
|
4489
|
+
Layers,
|
|
4490
|
+
Lightbulb,
|
|
4491
|
+
MessageCircle,
|
|
4492
|
+
SkipForward,
|
|
4493
|
+
Sparkles,
|
|
4494
|
+
Timer,
|
|
4495
|
+
Trophy
|
|
4496
|
+
} from "lucide-react";
|
|
4497
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
4498
|
+
var EMOJI_ICON_MAP = {
|
|
4499
|
+
"\u2753": HelpCircle,
|
|
4500
|
+
"\u{1F9ED}": Compass,
|
|
4501
|
+
"\u{1F4DD}": FileText,
|
|
4502
|
+
"\u{1F3AF}": Layers,
|
|
4503
|
+
"\u{1F3C6}": Trophy,
|
|
4504
|
+
"\u2728": Sparkles,
|
|
4505
|
+
"\u{1F4AC}": MessageCircle,
|
|
4506
|
+
"\u{1F3AE}": Gamepad2,
|
|
4507
|
+
"\u{1F4A1}": Lightbulb,
|
|
4508
|
+
"\u{1F4B0}": Banknote,
|
|
4509
|
+
"\u{1F4CB}": ClipboardList,
|
|
4510
|
+
"\u2705": CheckCircle,
|
|
4511
|
+
"\u26A0\uFE0F": AlertTriangle,
|
|
4512
|
+
"\u{1F4B5}": Banknote,
|
|
4513
|
+
"\u{1F3DB}\uFE0F": Landmark,
|
|
4514
|
+
"\u23ED\uFE0F": SkipForward,
|
|
4515
|
+
"\u27A1\uFE0F": ArrowRight,
|
|
4516
|
+
"\u23F1\uFE0F": Timer,
|
|
4517
|
+
"\u{1F4D6}": BookOpen,
|
|
4518
|
+
"\u{1F514}": Bell
|
|
4519
|
+
};
|
|
4520
|
+
function EmojiIcon({
|
|
4521
|
+
emoji,
|
|
4522
|
+
size = 14,
|
|
4523
|
+
color = "currentColor"
|
|
4524
|
+
}) {
|
|
4525
|
+
const Icon = EMOJI_ICON_MAP[emoji];
|
|
4526
|
+
if (!Icon) {
|
|
4527
|
+
return /* @__PURE__ */ jsx2("span", { children: emoji });
|
|
4528
|
+
}
|
|
4529
|
+
return /* @__PURE__ */ jsx2(Icon, { size, color });
|
|
4530
|
+
}
|
|
4531
|
+
|
|
4532
|
+
// src/notifications/NotificationToastStack.tsx
|
|
4533
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
3858
4534
|
var TOAST_STYLES_ID = "syntro-toast-styles";
|
|
3859
4535
|
var TOAST_CSS = `
|
|
3860
4536
|
@keyframes syntro-toast-slide-in {
|
|
@@ -3891,7 +4567,7 @@ function NotificationToastStack({
|
|
|
3891
4567
|
const { shadowRoot } = useShadowRoot();
|
|
3892
4568
|
ensureToastStyles(shadowRoot);
|
|
3893
4569
|
if (notifications.length === 0) return null;
|
|
3894
|
-
return /* @__PURE__ */
|
|
4570
|
+
return /* @__PURE__ */ jsx3(
|
|
3895
4571
|
"div",
|
|
3896
4572
|
{
|
|
3897
4573
|
"data-testid": "notification-toast-stack",
|
|
@@ -3946,7 +4622,7 @@ function NotificationToastStack({
|
|
|
3946
4622
|
padding: "10px 12px"
|
|
3947
4623
|
},
|
|
3948
4624
|
children: [
|
|
3949
|
-
/* @__PURE__ */
|
|
4625
|
+
/* @__PURE__ */ jsx3(
|
|
3950
4626
|
"div",
|
|
3951
4627
|
{
|
|
3952
4628
|
style: {
|
|
@@ -3960,11 +4636,11 @@ function NotificationToastStack({
|
|
|
3960
4636
|
flexShrink: 0,
|
|
3961
4637
|
fontSize: "14px"
|
|
3962
4638
|
},
|
|
3963
|
-
children: (_a2 = notif.icon) != null ? _a2 : "\u{1F514}"
|
|
4639
|
+
children: /* @__PURE__ */ jsx3(EmojiIcon, { emoji: (_a2 = notif.icon) != null ? _a2 : "\u{1F514}", size: 14 })
|
|
3964
4640
|
}
|
|
3965
4641
|
),
|
|
3966
4642
|
/* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
3967
|
-
/* @__PURE__ */
|
|
4643
|
+
/* @__PURE__ */ jsx3(
|
|
3968
4644
|
"div",
|
|
3969
4645
|
{
|
|
3970
4646
|
style: {
|
|
@@ -3979,7 +4655,7 @@ function NotificationToastStack({
|
|
|
3979
4655
|
children: notif.title
|
|
3980
4656
|
}
|
|
3981
4657
|
),
|
|
3982
|
-
notif.body && /* @__PURE__ */
|
|
4658
|
+
notif.body && /* @__PURE__ */ jsx3(
|
|
3983
4659
|
"div",
|
|
3984
4660
|
{
|
|
3985
4661
|
style: {
|
|
@@ -3995,7 +4671,7 @@ function NotificationToastStack({
|
|
|
3995
4671
|
}
|
|
3996
4672
|
)
|
|
3997
4673
|
] }),
|
|
3998
|
-
/* @__PURE__ */
|
|
4674
|
+
/* @__PURE__ */ jsx3(
|
|
3999
4675
|
"button",
|
|
4000
4676
|
{
|
|
4001
4677
|
type: "button",
|
|
@@ -4020,7 +4696,7 @@ function NotificationToastStack({
|
|
|
4020
4696
|
]
|
|
4021
4697
|
}
|
|
4022
4698
|
),
|
|
4023
|
-
/* @__PURE__ */
|
|
4699
|
+
/* @__PURE__ */ jsx3("div", { style: { height: "2px", background: "rgba(0, 0, 0, 0.08)" }, children: /* @__PURE__ */ jsx3(
|
|
4024
4700
|
"div",
|
|
4025
4701
|
{
|
|
4026
4702
|
className: "syntro-toast-progress",
|
|
@@ -4098,7 +4774,7 @@ function useNotifications(eventBus, tiles) {
|
|
|
4098
4774
|
const timerIds = useRef2(/* @__PURE__ */ new Map());
|
|
4099
4775
|
const publishDismissed = useCallback2(
|
|
4100
4776
|
(notif) => {
|
|
4101
|
-
eventBus == null ? void 0 : eventBus.publish(
|
|
4777
|
+
eventBus == null ? void 0 : eventBus.publish(StandardEvents2.NOTIFICATION_DISMISSED, {
|
|
4102
4778
|
notificationId: notif.id,
|
|
4103
4779
|
tileId: notif.tileId,
|
|
4104
4780
|
itemId: notif.itemId
|
|
@@ -4163,7 +4839,7 @@ function useNotifications(eventBus, tiles) {
|
|
|
4163
4839
|
}
|
|
4164
4840
|
return next;
|
|
4165
4841
|
});
|
|
4166
|
-
eventBus.publish(
|
|
4842
|
+
eventBus.publish(StandardEvents2.NOTIFICATION_SHOWN, {
|
|
4167
4843
|
notificationId: matched.id,
|
|
4168
4844
|
tileId: matched.tileId,
|
|
4169
4845
|
itemId: matched.itemId,
|
|
@@ -4234,7 +4910,7 @@ function useNotifyWatcher(runtime3, tiles, appRegistry2) {
|
|
|
4234
4910
|
|
|
4235
4911
|
// src/RuntimeProvider.tsx
|
|
4236
4912
|
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect4, useMemo as useMemo2, useState as useState3 } from "react";
|
|
4237
|
-
import { jsx as
|
|
4913
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
4238
4914
|
var RuntimeReactContext = createContext2({
|
|
4239
4915
|
runtime: null,
|
|
4240
4916
|
context: null
|
|
@@ -4252,7 +4928,7 @@ function RuntimeProvider({ runtime: runtime3, children }) {
|
|
|
4252
4928
|
return unsubscribe;
|
|
4253
4929
|
}, [runtime3]);
|
|
4254
4930
|
const value = useMemo2(() => ({ runtime: runtime3, context }), [runtime3, context]);
|
|
4255
|
-
return /* @__PURE__ */
|
|
4931
|
+
return /* @__PURE__ */ jsx4(RuntimeReactContext.Provider, { value, children });
|
|
4256
4932
|
}
|
|
4257
4933
|
function useRuntime() {
|
|
4258
4934
|
const { runtime: runtime3 } = useContext2(RuntimeReactContext);
|
|
@@ -4326,41 +5002,17 @@ import {
|
|
|
4326
5002
|
} from "react";
|
|
4327
5003
|
|
|
4328
5004
|
// src/components/TileIcon.tsx
|
|
4329
|
-
import {
|
|
4330
|
-
Compass,
|
|
4331
|
-
FileText,
|
|
4332
|
-
Gamepad2,
|
|
4333
|
-
HelpCircle,
|
|
4334
|
-
Layers,
|
|
4335
|
-
MessageCircle,
|
|
4336
|
-
Sparkles,
|
|
4337
|
-
Trophy
|
|
4338
|
-
} from "lucide-react";
|
|
4339
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
4340
|
-
var ICON_MAP = {
|
|
4341
|
-
"\u2753": HelpCircle,
|
|
4342
|
-
"\u{1F9ED}": Compass,
|
|
4343
|
-
"\u{1F4DD}": FileText,
|
|
4344
|
-
"\u{1F3AF}": Layers,
|
|
4345
|
-
"\u{1F3C6}": Trophy,
|
|
4346
|
-
"\u2728": Sparkles,
|
|
4347
|
-
"\u{1F4AC}": MessageCircle,
|
|
4348
|
-
"\u{1F3AE}": Gamepad2
|
|
4349
|
-
};
|
|
5005
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
4350
5006
|
function TileIcon({
|
|
4351
5007
|
emoji,
|
|
4352
5008
|
size = 18,
|
|
4353
5009
|
color = "currentColor"
|
|
4354
5010
|
}) {
|
|
4355
|
-
|
|
4356
|
-
if (!Icon) {
|
|
4357
|
-
return /* @__PURE__ */ jsx4("span", { children: emoji });
|
|
4358
|
-
}
|
|
4359
|
-
return /* @__PURE__ */ jsx4(Icon, { size, color });
|
|
5011
|
+
return /* @__PURE__ */ jsx5(EmojiIcon, { emoji, size, color });
|
|
4360
5012
|
}
|
|
4361
5013
|
|
|
4362
5014
|
// src/components/TileCard.tsx
|
|
4363
|
-
import { jsx as
|
|
5015
|
+
import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
4364
5016
|
function WidgetMount({ widgetId, props }) {
|
|
4365
5017
|
var _a2;
|
|
4366
5018
|
const runtime3 = useRuntime();
|
|
@@ -4390,7 +5042,6 @@ function WidgetMount({ widgetId, props }) {
|
|
|
4390
5042
|
return () => {
|
|
4391
5043
|
handle.unmount();
|
|
4392
5044
|
handleRef.current = null;
|
|
4393
|
-
container.remove();
|
|
4394
5045
|
};
|
|
4395
5046
|
}, [registry, widgetId, widgetAvailable]);
|
|
4396
5047
|
const propsJson = JSON.stringify(props);
|
|
@@ -4401,7 +5052,7 @@ function WidgetMount({ widgetId, props }) {
|
|
|
4401
5052
|
prevPropsJsonRef.current = propsJson;
|
|
4402
5053
|
(_a3 = handleRef.current) == null ? void 0 : _a3.update(propsRef.current);
|
|
4403
5054
|
}, [propsJson]);
|
|
4404
|
-
if (!registry
|
|
5055
|
+
if (!(registry == null ? void 0 : registry.has(widgetId))) {
|
|
4405
5056
|
return /* @__PURE__ */ jsxs2(
|
|
4406
5057
|
"div",
|
|
4407
5058
|
{
|
|
@@ -4418,7 +5069,7 @@ function WidgetMount({ widgetId, props }) {
|
|
|
4418
5069
|
}
|
|
4419
5070
|
);
|
|
4420
5071
|
}
|
|
4421
|
-
return /* @__PURE__ */
|
|
5072
|
+
return /* @__PURE__ */ jsx6("div", { ref: parentRef });
|
|
4422
5073
|
}
|
|
4423
5074
|
function TileCard({
|
|
4424
5075
|
config,
|
|
@@ -4491,9 +5142,9 @@ function TileCard({
|
|
|
4491
5142
|
onMouseLeave,
|
|
4492
5143
|
children: [
|
|
4493
5144
|
/* @__PURE__ */ jsxs2("div", { style: headerStyle, children: [
|
|
4494
|
-
/* @__PURE__ */
|
|
5145
|
+
/* @__PURE__ */ jsx6("div", { style: iconStyle, children: /* @__PURE__ */ jsx6(TileIcon, { emoji: resolvedIcon, size: resolvedSubtitle ? 36 : 24 }) }),
|
|
4495
5146
|
/* @__PURE__ */ jsxs2("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
4496
|
-
/* @__PURE__ */
|
|
5147
|
+
/* @__PURE__ */ jsx6(
|
|
4497
5148
|
"h3",
|
|
4498
5149
|
{
|
|
4499
5150
|
style: {
|
|
@@ -4508,7 +5159,7 @@ function TileCard({
|
|
|
4508
5159
|
children: title != null ? title : widget
|
|
4509
5160
|
}
|
|
4510
5161
|
),
|
|
4511
|
-
resolvedSubtitle && /* @__PURE__ */
|
|
5162
|
+
resolvedSubtitle && /* @__PURE__ */ jsx6(
|
|
4512
5163
|
"p",
|
|
4513
5164
|
{
|
|
4514
5165
|
style: {
|
|
@@ -4525,14 +5176,14 @@ function TileCard({
|
|
|
4525
5176
|
)
|
|
4526
5177
|
] })
|
|
4527
5178
|
] }),
|
|
4528
|
-
/* @__PURE__ */
|
|
5179
|
+
/* @__PURE__ */ jsx6(
|
|
4529
5180
|
"div",
|
|
4530
5181
|
{
|
|
4531
5182
|
style: {
|
|
4532
5183
|
padding: "var(--sc-tile-body-padding, 0 0.75rem 0.5rem)",
|
|
4533
5184
|
borderTop: "1px solid rgba(255, 255, 255, 0.06)"
|
|
4534
5185
|
},
|
|
4535
|
-
children: /* @__PURE__ */
|
|
5186
|
+
children: /* @__PURE__ */ jsx6("div", { style: { paddingTop: "var(--sc-tile-gap, 0.25rem)" }, children: /* @__PURE__ */ jsx6(WidgetMount, { widgetId: widget, props: { ...props, instanceId: config.id } }) })
|
|
4536
5187
|
}
|
|
4537
5188
|
)
|
|
4538
5189
|
]
|
|
@@ -4940,7 +5591,7 @@ function flattenThemeConfig(config) {
|
|
|
4940
5591
|
|
|
4941
5592
|
// src/theme/ThemeProvider.tsx
|
|
4942
5593
|
import { createContext as createContext3, useContext as useContext3, useEffect as useEffect6, useMemo as useMemo4 } from "react";
|
|
4943
|
-
import { jsx as
|
|
5594
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
4944
5595
|
var ThemeContext = createContext3(null);
|
|
4945
5596
|
function ThemeProvider({
|
|
4946
5597
|
children,
|
|
@@ -4971,7 +5622,7 @@ ${cssRules}
|
|
|
4971
5622
|
mode: merged.mode,
|
|
4972
5623
|
cssVariables
|
|
4973
5624
|
};
|
|
4974
|
-
return /* @__PURE__ */
|
|
5625
|
+
return /* @__PURE__ */ jsx7(ThemeContext.Provider, { value, children });
|
|
4975
5626
|
}
|
|
4976
5627
|
function useTheme() {
|
|
4977
5628
|
const context = useContext3(ThemeContext);
|
|
@@ -4982,7 +5633,7 @@ function useTheme() {
|
|
|
4982
5633
|
}
|
|
4983
5634
|
|
|
4984
5635
|
// src/components/ShadowCanvasOverlay.tsx
|
|
4985
|
-
import { Fragment, jsx as
|
|
5636
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
4986
5637
|
var LAUNCHER_STYLES_ID = "syntro-launcher-styles";
|
|
4987
5638
|
function ensureLauncherStyles(target, css) {
|
|
4988
5639
|
if (target.querySelector(`#${LAUNCHER_STYLES_ID}`)) return;
|
|
@@ -5022,7 +5673,7 @@ function ShadowCanvasOverlay({
|
|
|
5022
5673
|
const handleNotificationClick = useCallback4(
|
|
5023
5674
|
(notif) => {
|
|
5024
5675
|
if (runtime3) {
|
|
5025
|
-
runtime3.events.publish(
|
|
5676
|
+
runtime3.events.publish(StandardEvents2.NOTIFICATION_CLICKED, {
|
|
5026
5677
|
notificationId: notif.id,
|
|
5027
5678
|
tileId: notif.tileId,
|
|
5028
5679
|
itemId: notif.itemId
|
|
@@ -5032,7 +5683,7 @@ function ShadowCanvasOverlay({
|
|
|
5032
5683
|
onToggle();
|
|
5033
5684
|
}
|
|
5034
5685
|
if (runtime3 && notif.tileId) {
|
|
5035
|
-
runtime3.events.publish(
|
|
5686
|
+
runtime3.events.publish(StandardEvents2.NOTIFICATION_DEEP_LINK, {
|
|
5036
5687
|
tileId: notif.tileId,
|
|
5037
5688
|
itemId: notif.itemId
|
|
5038
5689
|
});
|
|
@@ -5105,6 +5756,17 @@ function ShadowCanvasOverlay({
|
|
|
5105
5756
|
}
|
|
5106
5757
|
onToggle();
|
|
5107
5758
|
}, [isOpen, telemetry, runtime3, onToggle]);
|
|
5759
|
+
useEffect7(() => {
|
|
5760
|
+
if (!isOpen) return;
|
|
5761
|
+
const handleOutsideClick = (e) => {
|
|
5762
|
+
const path = e.composedPath();
|
|
5763
|
+
if (containerRef.current && !path.includes(containerRef.current) && launcherRef.current && !path.includes(launcherRef.current)) {
|
|
5764
|
+
toggle2();
|
|
5765
|
+
}
|
|
5766
|
+
};
|
|
5767
|
+
document.addEventListener("mousedown", handleOutsideClick);
|
|
5768
|
+
return () => document.removeEventListener("mousedown", handleOutsideClick);
|
|
5769
|
+
}, [isOpen, toggle2]);
|
|
5108
5770
|
const onLauncherPointerDown = useCallback4((e) => {
|
|
5109
5771
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
5110
5772
|
dragRef.current = {
|
|
@@ -5143,6 +5805,7 @@ function ShadowCanvasOverlay({
|
|
|
5143
5805
|
const isPush = config.canvas.layout === "push";
|
|
5144
5806
|
const canvasBorder = (_b = config.canvas.border) != null ? _b : "none";
|
|
5145
5807
|
const containerRef = useRef5(null);
|
|
5808
|
+
const launcherRef = useRef5(null);
|
|
5146
5809
|
const zIndex = 2147483600;
|
|
5147
5810
|
useEffect7(() => {
|
|
5148
5811
|
var _a3, _b2, _c2, _d2;
|
|
@@ -5223,19 +5886,19 @@ function ShadowCanvasOverlay({
|
|
|
5223
5886
|
pointerEvents: "none",
|
|
5224
5887
|
padding: "0"
|
|
5225
5888
|
};
|
|
5226
|
-
const content = /* @__PURE__ */
|
|
5889
|
+
const content = /* @__PURE__ */ jsx8(
|
|
5227
5890
|
"div",
|
|
5228
5891
|
{
|
|
5229
5892
|
"data-shadow-canvas-id": "overlay-root",
|
|
5230
5893
|
style: {
|
|
5231
5894
|
position: "fixed",
|
|
5232
5895
|
inset: 0,
|
|
5233
|
-
pointerEvents:
|
|
5896
|
+
pointerEvents: "none",
|
|
5234
5897
|
zIndex
|
|
5235
5898
|
},
|
|
5236
5899
|
children: /* @__PURE__ */ jsxs3("div", { style: wrapperStyle, children: [
|
|
5237
5900
|
/* @__PURE__ */ jsxs3("div", { ref: containerRef, "data-shadow-canvas-id": "overlay-container", style: containerStyle, children: [
|
|
5238
|
-
isFocused && canvasTitle && /* @__PURE__ */
|
|
5901
|
+
isFocused && canvasTitle && /* @__PURE__ */ jsx8("header", { style: { color: "white", padding: "1.5rem 1.5rem 0" }, children: /* @__PURE__ */ jsx8(
|
|
5239
5902
|
"p",
|
|
5240
5903
|
{
|
|
5241
5904
|
style: {
|
|
@@ -5248,7 +5911,7 @@ function ShadowCanvasOverlay({
|
|
|
5248
5911
|
children: canvasTitle
|
|
5249
5912
|
}
|
|
5250
5913
|
) }),
|
|
5251
|
-
/* @__PURE__ */
|
|
5914
|
+
/* @__PURE__ */ jsx8("div", { style: { flex: 1, overflowY: "auto", padding: isFocused ? "0" : "1rem" }, children: isLoading ? /* @__PURE__ */ jsx8(
|
|
5252
5915
|
"div",
|
|
5253
5916
|
{
|
|
5254
5917
|
style: { color: "var(--sc-overlay-text-color)", padding: isFocused ? "1rem" : "0" },
|
|
@@ -5268,7 +5931,7 @@ function ShadowCanvasOverlay({
|
|
|
5268
5931
|
}
|
|
5269
5932
|
) : isFocused ? (
|
|
5270
5933
|
/* Focused Mode: Render first tile full size */
|
|
5271
|
-
tiles.length > 0 ? /* @__PURE__ */
|
|
5934
|
+
tiles.length > 0 ? /* @__PURE__ */ jsx8(
|
|
5272
5935
|
TileCard,
|
|
5273
5936
|
{
|
|
5274
5937
|
config: tiles[0],
|
|
@@ -5279,7 +5942,7 @@ function ShadowCanvasOverlay({
|
|
|
5279
5942
|
) : null
|
|
5280
5943
|
) : (
|
|
5281
5944
|
/* Standard Mode: Stacked cards — widgets always visible */
|
|
5282
|
-
/* @__PURE__ */
|
|
5945
|
+
/* @__PURE__ */ jsx8(
|
|
5283
5946
|
"div",
|
|
5284
5947
|
{
|
|
5285
5948
|
style: {
|
|
@@ -5288,7 +5951,7 @@ function ShadowCanvasOverlay({
|
|
|
5288
5951
|
gap: "0.75rem",
|
|
5289
5952
|
width: "100%"
|
|
5290
5953
|
},
|
|
5291
|
-
children: tiles.map((tile) => /* @__PURE__ */
|
|
5954
|
+
children: tiles.map((tile) => /* @__PURE__ */ jsx8(
|
|
5292
5955
|
TileCard,
|
|
5293
5956
|
{
|
|
5294
5957
|
config: tile,
|
|
@@ -5303,17 +5966,7 @@ function ShadowCanvasOverlay({
|
|
|
5303
5966
|
) }),
|
|
5304
5967
|
footerSlot
|
|
5305
5968
|
] }),
|
|
5306
|
-
/* @__PURE__ */
|
|
5307
|
-
"div",
|
|
5308
|
-
{
|
|
5309
|
-
onClick: toggle2,
|
|
5310
|
-
style: {
|
|
5311
|
-
flex: "1 1 auto",
|
|
5312
|
-
pointerEvents: isOpen ? "auto" : "none",
|
|
5313
|
-
cursor: "default"
|
|
5314
|
-
}
|
|
5315
|
-
}
|
|
5316
|
-
)
|
|
5969
|
+
/* @__PURE__ */ jsx8("div", { style: { flex: "1 1 auto" } })
|
|
5317
5970
|
] })
|
|
5318
5971
|
}
|
|
5319
5972
|
);
|
|
@@ -5331,7 +5984,7 @@ function ShadowCanvasOverlay({
|
|
|
5331
5984
|
zIndex: zIndex + 47
|
|
5332
5985
|
},
|
|
5333
5986
|
children: [
|
|
5334
|
-
/* @__PURE__ */
|
|
5987
|
+
/* @__PURE__ */ jsx8(
|
|
5335
5988
|
NotificationToastStack,
|
|
5336
5989
|
{
|
|
5337
5990
|
notifications,
|
|
@@ -5343,6 +5996,7 @@ function ShadowCanvasOverlay({
|
|
|
5343
5996
|
/* @__PURE__ */ jsxs3(
|
|
5344
5997
|
"button",
|
|
5345
5998
|
{
|
|
5999
|
+
ref: launcherRef,
|
|
5346
6000
|
type: "button",
|
|
5347
6001
|
"aria-label": "Toggle shadow canvas",
|
|
5348
6002
|
className: launcherAnimate && !isOpen ? "syntro-launcher-animate" : void 0,
|
|
@@ -5401,11 +6055,11 @@ function ShadowCanvasOverlay({
|
|
|
5401
6055
|
focusable: "false",
|
|
5402
6056
|
style: { transition: "transform 200ms ease" },
|
|
5403
6057
|
children: [
|
|
5404
|
-
/* @__PURE__ */
|
|
5405
|
-
/* @__PURE__ */
|
|
6058
|
+
/* @__PURE__ */ jsx8("path", { d: "M18 6L6 18" }),
|
|
6059
|
+
/* @__PURE__ */ jsx8("path", { d: "M6 6l12 12" })
|
|
5406
6060
|
]
|
|
5407
6061
|
}
|
|
5408
|
-
) : launcherIcon ? /* @__PURE__ */
|
|
6062
|
+
) : launcherIcon ? /* @__PURE__ */ jsx8(
|
|
5409
6063
|
"img",
|
|
5410
6064
|
{
|
|
5411
6065
|
src: launcherIcon,
|
|
@@ -5433,16 +6087,16 @@ function ShadowCanvasOverlay({
|
|
|
5433
6087
|
focusable: "false",
|
|
5434
6088
|
style: { transition: "transform 200ms ease" },
|
|
5435
6089
|
children: [
|
|
5436
|
-
/* @__PURE__ */
|
|
5437
|
-
/* @__PURE__ */
|
|
5438
|
-
/* @__PURE__ */
|
|
5439
|
-
/* @__PURE__ */
|
|
5440
|
-
/* @__PURE__ */
|
|
6090
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 3l1.912 5.813a2 2 0 0 0 1.275 1.275L21 12l-5.813 1.912a2 2 0 0 0-1.275 1.275L12 21l-1.912-5.813a2 2 0 0 0-1.275-1.275L3 12l5.813-1.912a2 2 0 0 0 1.275-1.275L12 3Z" }),
|
|
6091
|
+
/* @__PURE__ */ jsx8("path", { d: "M5 3v4" }),
|
|
6092
|
+
/* @__PURE__ */ jsx8("path", { d: "M3 5h4" }),
|
|
6093
|
+
/* @__PURE__ */ jsx8("path", { d: "M19 17v4" }),
|
|
6094
|
+
/* @__PURE__ */ jsx8("path", { d: "M17 19h4" })
|
|
5441
6095
|
]
|
|
5442
6096
|
}
|
|
5443
6097
|
),
|
|
5444
6098
|
!isOpen && notifications.length > 0 && /* @__PURE__ */ jsxs3("div", { style: { position: "absolute", top: -2, right: -2, pointerEvents: "none" }, children: [
|
|
5445
|
-
/* @__PURE__ */
|
|
6099
|
+
/* @__PURE__ */ jsx8(
|
|
5446
6100
|
"span",
|
|
5447
6101
|
{
|
|
5448
6102
|
className: "syntro-badge-ping",
|
|
@@ -5454,7 +6108,7 @@ function ShadowCanvasOverlay({
|
|
|
5454
6108
|
}
|
|
5455
6109
|
}
|
|
5456
6110
|
),
|
|
5457
|
-
/* @__PURE__ */
|
|
6111
|
+
/* @__PURE__ */ jsx8(
|
|
5458
6112
|
"span",
|
|
5459
6113
|
{
|
|
5460
6114
|
className: "syntro-badge-glow",
|
|
@@ -5465,7 +6119,7 @@ function ShadowCanvasOverlay({
|
|
|
5465
6119
|
}
|
|
5466
6120
|
}
|
|
5467
6121
|
),
|
|
5468
|
-
/* @__PURE__ */
|
|
6122
|
+
/* @__PURE__ */ jsx8(
|
|
5469
6123
|
"span",
|
|
5470
6124
|
{
|
|
5471
6125
|
className: "syntro-badge-bounce",
|
|
@@ -5600,7 +6254,7 @@ function useShadowCanvasConfig({
|
|
|
5600
6254
|
|
|
5601
6255
|
// src/SmartCanvasApp.tsx
|
|
5602
6256
|
import { useEffect as useEffect9, useMemo as useMemo7, useRef as useRef7, useState as useState7 } from "react";
|
|
5603
|
-
import { jsx as
|
|
6257
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
5604
6258
|
function SmartCanvasApp({
|
|
5605
6259
|
controller,
|
|
5606
6260
|
fetcher,
|
|
@@ -5623,7 +6277,7 @@ function SmartCanvasApp({
|
|
|
5623
6277
|
workspaceTheme
|
|
5624
6278
|
}) {
|
|
5625
6279
|
if (runtime3) {
|
|
5626
|
-
return /* @__PURE__ */
|
|
6280
|
+
return /* @__PURE__ */ jsx9(RuntimeProvider, { runtime: runtime3, children: /* @__PURE__ */ jsx9(
|
|
5627
6281
|
SmartCanvasAppInner,
|
|
5628
6282
|
{
|
|
5629
6283
|
controller,
|
|
@@ -5648,7 +6302,7 @@ function SmartCanvasApp({
|
|
|
5648
6302
|
}
|
|
5649
6303
|
) });
|
|
5650
6304
|
}
|
|
5651
|
-
return /* @__PURE__ */
|
|
6305
|
+
return /* @__PURE__ */ jsx9(
|
|
5652
6306
|
SmartCanvasAppInner,
|
|
5653
6307
|
{
|
|
5654
6308
|
controller,
|
|
@@ -5679,7 +6333,7 @@ function SmartCanvasAppInner({
|
|
|
5679
6333
|
configUriFeatureKey = "smart-canvas-config-uri",
|
|
5680
6334
|
configFeatureKey = "smart-canvas-config",
|
|
5681
6335
|
fetchCredentials = "include",
|
|
5682
|
-
pollIntervalMs,
|
|
6336
|
+
pollIntervalMs: _pollIntervalMs,
|
|
5683
6337
|
experiments,
|
|
5684
6338
|
telemetry,
|
|
5685
6339
|
runtime: runtime3,
|
|
@@ -5803,16 +6457,13 @@ function SmartCanvasAppInner({
|
|
|
5803
6457
|
}, [runtime3, controller]);
|
|
5804
6458
|
const { shadowRoot } = useShadowRoot();
|
|
5805
6459
|
const themeConfig = configState.theme;
|
|
5806
|
-
|
|
5807
|
-
return null;
|
|
5808
|
-
}
|
|
5809
|
-
return /* @__PURE__ */ jsx8(
|
|
6460
|
+
return /* @__PURE__ */ jsx9(
|
|
5810
6461
|
ThemeProvider,
|
|
5811
6462
|
{
|
|
5812
6463
|
themeConfig,
|
|
5813
6464
|
workspaceTheme,
|
|
5814
6465
|
shadowRoot,
|
|
5815
|
-
children: /* @__PURE__ */
|
|
6466
|
+
children: !configState.isLoading && !hasContent ? null : /* @__PURE__ */ jsx9(
|
|
5816
6467
|
ShadowCanvasOverlay,
|
|
5817
6468
|
{
|
|
5818
6469
|
tiles: configState.tiles,
|
|
@@ -5837,7 +6488,7 @@ function SmartCanvasAppInner({
|
|
|
5837
6488
|
|
|
5838
6489
|
// src/SmartCanvasElement.tsx
|
|
5839
6490
|
import { createRoot as createRoot2 } from "react-dom/client";
|
|
5840
|
-
import { jsx as
|
|
6491
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
5841
6492
|
var TAG_NAME = "smart-canvas";
|
|
5842
6493
|
var BASE_CSS = `
|
|
5843
6494
|
:host {
|
|
@@ -5938,13 +6589,13 @@ var SmartCanvasElement = class extends HTMLElement {
|
|
|
5938
6589
|
__privateSet(this, _root, createRoot2(__privateGet(this, _mount)));
|
|
5939
6590
|
}
|
|
5940
6591
|
__privateGet(this, _root).render(
|
|
5941
|
-
/* @__PURE__ */
|
|
6592
|
+
/* @__PURE__ */ jsx10(
|
|
5942
6593
|
ShadowRootProvider,
|
|
5943
6594
|
{
|
|
5944
6595
|
shadowRoot: __privateGet(this, _shadow),
|
|
5945
6596
|
portalRoot: __privateGet(this, _portalRoot),
|
|
5946
6597
|
overlayContainer: __privateGet(this, _overlayContainer),
|
|
5947
|
-
children: /* @__PURE__ */
|
|
6598
|
+
children: /* @__PURE__ */ jsx10(SmartCanvasApp, { ...__privateGet(this, _lastAppProps), controller: __privateGet(this, _controller), canvasHost: this })
|
|
5948
6599
|
}
|
|
5949
6600
|
)
|
|
5950
6601
|
);
|
|
@@ -6513,7 +7164,7 @@ var createSmartCanvas = async (config = {}) => {
|
|
|
6513
7164
|
console.log(
|
|
6514
7165
|
"[SmartCanvas] Actions to apply:",
|
|
6515
7166
|
canvasConfig.actions.map(
|
|
6516
|
-
(a, i) => `[${i}] ${a.kind}${a.anchorId ? ` anchor="${
|
|
7167
|
+
(a, i) => `[${i}] ${a.kind}${a.anchorId ? ` anchor="${a.anchorId.selector}"` : ""}${a.label ? ` "${a.label}"` : ""}`
|
|
6517
7168
|
).join(", ")
|
|
6518
7169
|
);
|
|
6519
7170
|
}
|
|
@@ -6964,17 +7615,18 @@ var PostHogAdapter = class {
|
|
|
6964
7615
|
__publicField(this, "client");
|
|
6965
7616
|
__publicField(this, "featureFlagsCallback");
|
|
6966
7617
|
__publicField(this, "captureCallback");
|
|
6967
|
-
__publicField(this, "
|
|
7618
|
+
__publicField(this, "rrwebCallback");
|
|
6968
7619
|
this.client = options.client;
|
|
6969
7620
|
this.featureFlagsCallback = options.onFeatureFlagsLoaded;
|
|
6970
7621
|
this.captureCallback = options.onCapture;
|
|
7622
|
+
this.rrwebCallback = options.onRRWebEvent;
|
|
6971
7623
|
if (!this.client && options.consent && options.requireExplicitConsent && typeof window !== "undefined" && options.apiKey) {
|
|
6972
7624
|
const consent = options.consent;
|
|
6973
7625
|
const currentStatus = consent.getStatus();
|
|
6974
7626
|
if (currentStatus === "granted") {
|
|
6975
7627
|
this.initPostHog();
|
|
6976
7628
|
}
|
|
6977
|
-
|
|
7629
|
+
consent.subscribe((status) => {
|
|
6978
7630
|
if (status === "granted") {
|
|
6979
7631
|
if (!this.client) {
|
|
6980
7632
|
this.initPostHog();
|
|
@@ -7001,68 +7653,120 @@ var PostHogAdapter = class {
|
|
|
7001
7653
|
if (!options.apiKey) return;
|
|
7002
7654
|
const enableFeatureFlags = (_a2 = options.enableFeatureFlags) != null ? _a2 : true;
|
|
7003
7655
|
const instanceName = `syntro_${options.apiKey.slice(-6) || "sdk"}`;
|
|
7004
|
-
|
|
7005
|
-
options.
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
7021
|
-
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
|
|
7027
|
-
|
|
7028
|
-
|
|
7029
|
-
|
|
7030
|
-
|
|
7031
|
-
|
|
7032
|
-
|
|
7033
|
-
|
|
7034
|
-
if (allFlags && this.featureFlagsCallback) {
|
|
7035
|
-
this.featureFlagsCallback(allFlags);
|
|
7036
|
-
}
|
|
7037
|
-
});
|
|
7038
|
-
const existingFlags = this.getAllFeatureFlags();
|
|
7039
|
-
if (existingFlags && Object.keys(existingFlags).length > 0) {
|
|
7040
|
-
this.featureFlagsCallback(existingFlags);
|
|
7656
|
+
const initOptions = {
|
|
7657
|
+
api_host: (_b = options.apiHost) != null ? _b : "https://telemetry.syntrologie.com",
|
|
7658
|
+
// Feature flags for segment membership (in_segment_* flags)
|
|
7659
|
+
// When enabled, /decide is called to get segment flags
|
|
7660
|
+
advanced_disable_feature_flags: !enableFeatureFlags,
|
|
7661
|
+
advanced_disable_feature_flags_on_first_load: !enableFeatureFlags,
|
|
7662
|
+
// Full-page tracking - all ON by default
|
|
7663
|
+
autocapture: (_c = options.autocapture) != null ? _c : true,
|
|
7664
|
+
capture_pageview: (_d = options.capturePageview) != null ? _d : "history_change",
|
|
7665
|
+
capture_pageleave: (_e = options.capturePageleave) != null ? _e : true,
|
|
7666
|
+
disable_session_recording: !((_f = options.sessionRecording) != null ? _f : true),
|
|
7667
|
+
// CRITICAL: Disable user agent filtering to allow headless Chrome
|
|
7668
|
+
// PostHog blocks "HeadlessChrome" user agents by default as bot detection
|
|
7669
|
+
// This enables session recording in Playwright/crawler sessions
|
|
7670
|
+
opt_out_useragent_filter: true,
|
|
7671
|
+
// Cross-domain iframe recording for embeds
|
|
7672
|
+
session_recording: {
|
|
7673
|
+
recordCrossDomainIFrames: true
|
|
7674
|
+
},
|
|
7675
|
+
// Capture performance metrics
|
|
7676
|
+
capture_performance: true,
|
|
7677
|
+
// Enable web vitals
|
|
7678
|
+
enable_recording_console_log: true,
|
|
7679
|
+
// Bootstrap callback for when flags are loaded
|
|
7680
|
+
loaded: (ph) => {
|
|
7681
|
+
if (enableFeatureFlags && this.featureFlagsCallback) {
|
|
7682
|
+
ph.onFeatureFlags(() => {
|
|
7683
|
+
const allFlags = this.getAllFeatureFlags();
|
|
7684
|
+
if (allFlags && this.featureFlagsCallback) {
|
|
7685
|
+
this.featureFlagsCallback(allFlags);
|
|
7041
7686
|
}
|
|
7042
|
-
}
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
const eventName = typeof data === "string" ? data : data == null ? void 0 : data.event;
|
|
7047
|
-
const properties = typeof data === "string" ? void 0 : data == null ? void 0 : data.properties;
|
|
7048
|
-
if (typeof eventName === "string") {
|
|
7049
|
-
(_a3 = this.captureCallback) == null ? void 0 : _a3.call(this, eventName, properties);
|
|
7050
|
-
}
|
|
7051
|
-
});
|
|
7687
|
+
});
|
|
7688
|
+
const existingFlags = this.getAllFeatureFlags();
|
|
7689
|
+
if (existingFlags && Object.keys(existingFlags).length > 0) {
|
|
7690
|
+
this.featureFlagsCallback(existingFlags);
|
|
7052
7691
|
}
|
|
7053
7692
|
}
|
|
7054
|
-
|
|
7693
|
+
if (this.captureCallback) {
|
|
7694
|
+
ph.on("eventCaptured", (...args) => {
|
|
7695
|
+
var _a3;
|
|
7696
|
+
const data = args[0];
|
|
7697
|
+
const eventName = typeof data === "string" ? data : data == null ? void 0 : data.event;
|
|
7698
|
+
const properties = typeof data === "string" ? void 0 : data == null ? void 0 : data.properties;
|
|
7699
|
+
if (typeof eventName === "string") {
|
|
7700
|
+
(_a3 = this.captureCallback) == null ? void 0 : _a3.call(this, eventName, properties);
|
|
7701
|
+
}
|
|
7702
|
+
});
|
|
7703
|
+
}
|
|
7704
|
+
}
|
|
7705
|
+
};
|
|
7706
|
+
const result = posthog.init(
|
|
7707
|
+
options.apiKey,
|
|
7708
|
+
initOptions,
|
|
7055
7709
|
instanceName
|
|
7056
7710
|
);
|
|
7711
|
+
if (result) {
|
|
7712
|
+
this.client = result;
|
|
7713
|
+
}
|
|
7714
|
+
if (this.rrwebCallback && this.client) {
|
|
7715
|
+
this.setupRRWebIntercept();
|
|
7716
|
+
}
|
|
7717
|
+
}
|
|
7718
|
+
/**
|
|
7719
|
+
* Set up rrweb event interception on PostHog's session recording.
|
|
7720
|
+
*
|
|
7721
|
+
* PostHog lazy-loads the rrweb recorder. The SessionRecording wrapper has
|
|
7722
|
+
* an `onRRwebEmit` method, but rrweb delivers events directly to the
|
|
7723
|
+
* lazy-loaded recorder instance's `onRRwebEmit`, bypassing the wrapper.
|
|
7724
|
+
* We must find and patch the recorder instance, not the wrapper.
|
|
7725
|
+
*
|
|
7726
|
+
* The recorder instance is stored on a minified property of SessionRecording.
|
|
7727
|
+
* We detect it by looking for an object with both `onRRwebEmit` and `start` methods.
|
|
7728
|
+
*/
|
|
7729
|
+
setupRRWebIntercept(retries = 30) {
|
|
7730
|
+
var _a2;
|
|
7731
|
+
const sr = (_a2 = this.client) == null ? void 0 : _a2.sessionRecording;
|
|
7732
|
+
if (!sr) {
|
|
7733
|
+
if (retries > 0) {
|
|
7734
|
+
setTimeout(() => this.setupRRWebIntercept(retries - 1), 500);
|
|
7735
|
+
}
|
|
7736
|
+
return;
|
|
7737
|
+
}
|
|
7738
|
+
let recorder = null;
|
|
7739
|
+
const srRecord = sr;
|
|
7740
|
+
for (const key of Object.getOwnPropertyNames(srRecord)) {
|
|
7741
|
+
const val = srRecord[key];
|
|
7742
|
+
if (val && typeof val === "object" && typeof val.onRRwebEmit === "function" && typeof val.start === "function" && val !== sr) {
|
|
7743
|
+
recorder = val;
|
|
7744
|
+
break;
|
|
7745
|
+
}
|
|
7746
|
+
}
|
|
7747
|
+
if (!recorder) {
|
|
7748
|
+
if (retries > 0) {
|
|
7749
|
+
setTimeout(() => this.setupRRWebIntercept(retries - 1), 500);
|
|
7750
|
+
}
|
|
7751
|
+
return;
|
|
7752
|
+
}
|
|
7753
|
+
const originalEmit = recorder.onRRwebEmit.bind(recorder);
|
|
7754
|
+
recorder.onRRwebEmit = (rawEvent) => {
|
|
7755
|
+
var _a3;
|
|
7756
|
+
(_a3 = this.rrwebCallback) == null ? void 0 : _a3.call(this, { kind: "rrweb", ...rawEvent });
|
|
7757
|
+
originalEmit(rawEvent);
|
|
7758
|
+
};
|
|
7759
|
+
if (typeof window !== "undefined") {
|
|
7760
|
+
window.__RRWEB_INTERCEPT_READY__ = true;
|
|
7761
|
+
}
|
|
7057
7762
|
}
|
|
7058
7763
|
/**
|
|
7059
7764
|
* Get all feature flags from PostHog.
|
|
7060
7765
|
* Used to extract segment membership flags (in_segment_*).
|
|
7061
7766
|
*/
|
|
7062
7767
|
getAllFeatureFlags() {
|
|
7063
|
-
var _a2, _b
|
|
7064
|
-
|
|
7065
|
-
return flags;
|
|
7768
|
+
var _a2, _b;
|
|
7769
|
+
return (_b = (_a2 = this.client) == null ? void 0 : _a2.featureFlags) == null ? void 0 : _b.getFlagVariants();
|
|
7066
7770
|
}
|
|
7067
7771
|
/**
|
|
7068
7772
|
* Get segment membership flags (in_segment_*) from PostHog.
|
|
@@ -7413,158 +8117,7 @@ function hasExecutor(kind) {
|
|
|
7413
8117
|
return executorRegistry.has(kind);
|
|
7414
8118
|
}
|
|
7415
8119
|
|
|
7416
|
-
// src/actions/validation.ts
|
|
7417
|
-
var DANGEROUS_ATTRS = /* @__PURE__ */ new Set([
|
|
7418
|
-
"onclick",
|
|
7419
|
-
"onerror",
|
|
7420
|
-
"onload",
|
|
7421
|
-
"onmouseover",
|
|
7422
|
-
"onfocus",
|
|
7423
|
-
"onblur",
|
|
7424
|
-
"onchange",
|
|
7425
|
-
"onsubmit",
|
|
7426
|
-
"onkeydown",
|
|
7427
|
-
"onkeyup",
|
|
7428
|
-
"onkeypress"
|
|
7429
|
-
]);
|
|
7430
|
-
var MAX_HTML_LENGTH = 5e4;
|
|
7431
|
-
var MAX_STYLE_COUNT = 50;
|
|
7432
|
-
function validateAction(action) {
|
|
7433
|
-
const errors = [];
|
|
7434
|
-
const warnings = [];
|
|
7435
|
-
if (!action || typeof action !== "object") {
|
|
7436
|
-
errors.push({
|
|
7437
|
-
code: "INVALID_ACTION",
|
|
7438
|
-
message: "Action must be an object"
|
|
7439
|
-
});
|
|
7440
|
-
return { valid: false, errors, warnings };
|
|
7441
|
-
}
|
|
7442
|
-
const { kind } = action;
|
|
7443
|
-
if (!kind || typeof kind !== "string") {
|
|
7444
|
-
errors.push({
|
|
7445
|
-
code: "MISSING_KIND",
|
|
7446
|
-
message: "Action must have a 'kind' property"
|
|
7447
|
-
});
|
|
7448
|
-
return { valid: false, errors, warnings };
|
|
7449
|
-
}
|
|
7450
|
-
if (!hasExecutor(kind) && kind !== "core:mountWidget") {
|
|
7451
|
-
const registered = executorRegistry.list();
|
|
7452
|
-
console.error(
|
|
7453
|
-
`[ActionValidation] Unknown action kind: "${kind}". Registered kinds (${registered.length}): [${registered.join(", ")}]. This usually means the app that provides "${kind}" hasn't been activated yet, or the executor was never registered in ExecutorRegistry.`
|
|
7454
|
-
);
|
|
7455
|
-
errors.push({
|
|
7456
|
-
code: "UNKNOWN_KIND",
|
|
7457
|
-
message: `Unknown action kind: ${kind}`,
|
|
7458
|
-
field: "kind"
|
|
7459
|
-
});
|
|
7460
|
-
return { valid: false, errors, warnings };
|
|
7461
|
-
}
|
|
7462
|
-
switch (kind) {
|
|
7463
|
-
case "overlays:highlight":
|
|
7464
|
-
case "overlays:pulse":
|
|
7465
|
-
case "navigation:scrollTo":
|
|
7466
|
-
validateAnchorAction(action, errors, warnings);
|
|
7467
|
-
break;
|
|
7468
|
-
case "overlays:badge":
|
|
7469
|
-
validateAnchorAction(action, errors, warnings);
|
|
7470
|
-
validateBadgeAction(action, errors, warnings);
|
|
7471
|
-
break;
|
|
7472
|
-
case "overlays:tooltip":
|
|
7473
|
-
validateAnchorAction(action, errors, warnings);
|
|
7474
|
-
validateTooltipAction(action, errors, warnings);
|
|
7475
|
-
break;
|
|
7476
|
-
case "overlays:modal":
|
|
7477
|
-
validateModalAction(action, errors, warnings);
|
|
7478
|
-
break;
|
|
7479
|
-
case "content:insertHtml":
|
|
7480
|
-
validateAnchorAction(action, errors, warnings);
|
|
7481
|
-
validateInsertHtmlAction(action, errors, warnings);
|
|
7482
|
-
break;
|
|
7483
|
-
case "content:setText":
|
|
7484
|
-
validateAnchorAction(action, errors, warnings);
|
|
7485
|
-
validateSetTextAction(action, errors, warnings);
|
|
7486
|
-
break;
|
|
7487
|
-
case "content:setAttr":
|
|
7488
|
-
validateAnchorAction(action, errors, warnings);
|
|
7489
|
-
validateSetAttrAction(action, errors, warnings);
|
|
7490
|
-
break;
|
|
7491
|
-
case "content:addClass":
|
|
7492
|
-
case "content:removeClass":
|
|
7493
|
-
validateAnchorAction(action, errors, warnings);
|
|
7494
|
-
validateClassAction(action, errors, warnings);
|
|
7495
|
-
break;
|
|
7496
|
-
case "content:setStyle":
|
|
7497
|
-
validateAnchorAction(action, errors, warnings);
|
|
7498
|
-
validateSetStyleAction(action, errors, warnings);
|
|
7499
|
-
break;
|
|
7500
|
-
case "core:mountWidget":
|
|
7501
|
-
validateMountWidgetAction(action, errors, warnings);
|
|
7502
|
-
break;
|
|
7503
|
-
case "core:wait":
|
|
7504
|
-
validateWaitAction(action, errors, warnings);
|
|
7505
|
-
break;
|
|
7506
|
-
case "core:sequence":
|
|
7507
|
-
validateSequenceAction(action, errors, warnings);
|
|
7508
|
-
break;
|
|
7509
|
-
case "core:parallel":
|
|
7510
|
-
validateParallelAction(action, errors, warnings);
|
|
7511
|
-
break;
|
|
7512
|
-
case "core:tour":
|
|
7513
|
-
validateTourAction(action, errors, warnings);
|
|
7514
|
-
break;
|
|
7515
|
-
case "navigation:navigate":
|
|
7516
|
-
validateNavigateAction(action, errors, warnings);
|
|
7517
|
-
break;
|
|
7518
|
-
}
|
|
7519
|
-
return {
|
|
7520
|
-
valid: errors.length === 0,
|
|
7521
|
-
errors,
|
|
7522
|
-
warnings
|
|
7523
|
-
};
|
|
7524
|
-
}
|
|
7525
|
-
function validateAnchorAction(action, errors, warnings) {
|
|
7526
|
-
const anchorId = action.anchorId;
|
|
7527
|
-
if (!anchorId || typeof anchorId !== "object") {
|
|
7528
|
-
errors.push({
|
|
7529
|
-
code: "MISSING_ANCHOR_ID",
|
|
7530
|
-
message: "Action requires an 'anchorId' object with a 'selector' string",
|
|
7531
|
-
field: "anchorId"
|
|
7532
|
-
});
|
|
7533
|
-
return;
|
|
7534
|
-
}
|
|
7535
|
-
if (!anchorId.selector || typeof anchorId.selector !== "string") {
|
|
7536
|
-
errors.push({
|
|
7537
|
-
code: "MISSING_ANCHOR_SELECTOR",
|
|
7538
|
-
message: "anchorId requires a 'selector' string",
|
|
7539
|
-
field: "anchorId.selector"
|
|
7540
|
-
});
|
|
7541
|
-
} else if (anchorId.selector.length > 200) {
|
|
7542
|
-
warnings.push({
|
|
7543
|
-
code: "LONG_ANCHOR_ID",
|
|
7544
|
-
message: "Anchor selector is unusually long",
|
|
7545
|
-
suggestion: "Consider using a shorter, more descriptive selector"
|
|
7546
|
-
});
|
|
7547
|
-
}
|
|
7548
|
-
if (anchorId.route === void 0 || anchorId.route === null) {
|
|
7549
|
-
errors.push({
|
|
7550
|
-
code: "MISSING_ANCHOR_ROUTE",
|
|
7551
|
-
message: `anchorId requires a 'route' (string or array of strings). Use "**" for all routes.`,
|
|
7552
|
-
field: "anchorId.route"
|
|
7553
|
-
});
|
|
7554
|
-
} else {
|
|
7555
|
-
const routes = Array.isArray(anchorId.route) ? anchorId.route : [anchorId.route];
|
|
7556
|
-
for (const route of routes) {
|
|
7557
|
-
if (typeof route !== "string") {
|
|
7558
|
-
errors.push({
|
|
7559
|
-
code: "INVALID_ANCHOR_ROUTE",
|
|
7560
|
-
message: "anchorId.route must be a string or array of strings",
|
|
7561
|
-
field: "anchorId.route"
|
|
7562
|
-
});
|
|
7563
|
-
break;
|
|
7564
|
-
}
|
|
7565
|
-
}
|
|
7566
|
-
}
|
|
7567
|
-
}
|
|
8120
|
+
// src/actions/validation-rules.ts
|
|
7568
8121
|
function validateBadgeAction(action, errors, warnings) {
|
|
7569
8122
|
if (!action.content || typeof action.content !== "string") {
|
|
7570
8123
|
errors.push({
|
|
@@ -7951,7 +8504,160 @@ function validateTourAction(action, errors, warnings) {
|
|
|
7951
8504
|
}
|
|
7952
8505
|
}
|
|
7953
8506
|
}
|
|
7954
|
-
|
|
8507
|
+
|
|
8508
|
+
// src/actions/validation-core.ts
|
|
8509
|
+
var DANGEROUS_ATTRS = /* @__PURE__ */ new Set([
|
|
8510
|
+
"onclick",
|
|
8511
|
+
"onerror",
|
|
8512
|
+
"onload",
|
|
8513
|
+
"onmouseover",
|
|
8514
|
+
"onfocus",
|
|
8515
|
+
"onblur",
|
|
8516
|
+
"onchange",
|
|
8517
|
+
"onsubmit",
|
|
8518
|
+
"onkeydown",
|
|
8519
|
+
"onkeyup",
|
|
8520
|
+
"onkeypress"
|
|
8521
|
+
]);
|
|
8522
|
+
var MAX_HTML_LENGTH = 5e4;
|
|
8523
|
+
var MAX_STYLE_COUNT = 50;
|
|
8524
|
+
function validateAction(action) {
|
|
8525
|
+
const errors = [];
|
|
8526
|
+
const warnings = [];
|
|
8527
|
+
if (!action || typeof action !== "object") {
|
|
8528
|
+
errors.push({
|
|
8529
|
+
code: "INVALID_ACTION",
|
|
8530
|
+
message: "Action must be an object"
|
|
8531
|
+
});
|
|
8532
|
+
return { valid: false, errors, warnings };
|
|
8533
|
+
}
|
|
8534
|
+
const { kind } = action;
|
|
8535
|
+
if (!kind || typeof kind !== "string") {
|
|
8536
|
+
errors.push({
|
|
8537
|
+
code: "MISSING_KIND",
|
|
8538
|
+
message: "Action must have a 'kind' property"
|
|
8539
|
+
});
|
|
8540
|
+
return { valid: false, errors, warnings };
|
|
8541
|
+
}
|
|
8542
|
+
if (!hasExecutor(kind) && kind !== "core:mountWidget") {
|
|
8543
|
+
const registered = executorRegistry.list();
|
|
8544
|
+
console.error(
|
|
8545
|
+
`[ActionValidation] Unknown action kind: "${kind}". Registered kinds (${registered.length}): [${registered.join(", ")}]. This usually means the app that provides "${kind}" hasn't been activated yet, or the executor was never registered in ExecutorRegistry.`
|
|
8546
|
+
);
|
|
8547
|
+
errors.push({
|
|
8548
|
+
code: "UNKNOWN_KIND",
|
|
8549
|
+
message: `Unknown action kind: ${kind}`,
|
|
8550
|
+
field: "kind"
|
|
8551
|
+
});
|
|
8552
|
+
return { valid: false, errors, warnings };
|
|
8553
|
+
}
|
|
8554
|
+
switch (kind) {
|
|
8555
|
+
case "overlays:highlight":
|
|
8556
|
+
case "overlays:pulse":
|
|
8557
|
+
case "navigation:scrollTo":
|
|
8558
|
+
validateAnchorAction(action, errors, warnings);
|
|
8559
|
+
break;
|
|
8560
|
+
case "overlays:badge":
|
|
8561
|
+
validateAnchorAction(action, errors, warnings);
|
|
8562
|
+
validateBadgeAction(action, errors, warnings);
|
|
8563
|
+
break;
|
|
8564
|
+
case "overlays:tooltip":
|
|
8565
|
+
validateAnchorAction(action, errors, warnings);
|
|
8566
|
+
validateTooltipAction(action, errors, warnings);
|
|
8567
|
+
break;
|
|
8568
|
+
case "overlays:modal":
|
|
8569
|
+
validateModalAction(action, errors, warnings);
|
|
8570
|
+
break;
|
|
8571
|
+
case "content:insertHtml":
|
|
8572
|
+
validateAnchorAction(action, errors, warnings);
|
|
8573
|
+
validateInsertHtmlAction(action, errors, warnings);
|
|
8574
|
+
break;
|
|
8575
|
+
case "content:setText":
|
|
8576
|
+
validateAnchorAction(action, errors, warnings);
|
|
8577
|
+
validateSetTextAction(action, errors, warnings);
|
|
8578
|
+
break;
|
|
8579
|
+
case "content:setAttr":
|
|
8580
|
+
validateAnchorAction(action, errors, warnings);
|
|
8581
|
+
validateSetAttrAction(action, errors, warnings);
|
|
8582
|
+
break;
|
|
8583
|
+
case "content:addClass":
|
|
8584
|
+
case "content:removeClass":
|
|
8585
|
+
validateAnchorAction(action, errors, warnings);
|
|
8586
|
+
validateClassAction(action, errors, warnings);
|
|
8587
|
+
break;
|
|
8588
|
+
case "content:setStyle":
|
|
8589
|
+
validateAnchorAction(action, errors, warnings);
|
|
8590
|
+
validateSetStyleAction(action, errors, warnings);
|
|
8591
|
+
break;
|
|
8592
|
+
case "core:mountWidget":
|
|
8593
|
+
validateMountWidgetAction(action, errors, warnings);
|
|
8594
|
+
break;
|
|
8595
|
+
case "core:wait":
|
|
8596
|
+
validateWaitAction(action, errors, warnings);
|
|
8597
|
+
break;
|
|
8598
|
+
case "core:sequence":
|
|
8599
|
+
validateSequenceAction(action, errors, warnings);
|
|
8600
|
+
break;
|
|
8601
|
+
case "core:parallel":
|
|
8602
|
+
validateParallelAction(action, errors, warnings);
|
|
8603
|
+
break;
|
|
8604
|
+
case "core:tour":
|
|
8605
|
+
validateTourAction(action, errors, warnings);
|
|
8606
|
+
break;
|
|
8607
|
+
case "navigation:navigate":
|
|
8608
|
+
validateNavigateAction(action, errors, warnings);
|
|
8609
|
+
break;
|
|
8610
|
+
}
|
|
8611
|
+
return {
|
|
8612
|
+
valid: errors.length === 0,
|
|
8613
|
+
errors,
|
|
8614
|
+
warnings
|
|
8615
|
+
};
|
|
8616
|
+
}
|
|
8617
|
+
function validateAnchorAction(action, errors, warnings) {
|
|
8618
|
+
const anchorId = action.anchorId;
|
|
8619
|
+
if (!anchorId || typeof anchorId !== "object") {
|
|
8620
|
+
errors.push({
|
|
8621
|
+
code: "MISSING_ANCHOR_ID",
|
|
8622
|
+
message: "Action requires an 'anchorId' object with a 'selector' string",
|
|
8623
|
+
field: "anchorId"
|
|
8624
|
+
});
|
|
8625
|
+
return;
|
|
8626
|
+
}
|
|
8627
|
+
if (!anchorId.selector || typeof anchorId.selector !== "string") {
|
|
8628
|
+
errors.push({
|
|
8629
|
+
code: "MISSING_ANCHOR_SELECTOR",
|
|
8630
|
+
message: "anchorId requires a 'selector' string",
|
|
8631
|
+
field: "anchorId.selector"
|
|
8632
|
+
});
|
|
8633
|
+
} else if (anchorId.selector.length > 200) {
|
|
8634
|
+
warnings.push({
|
|
8635
|
+
code: "LONG_ANCHOR_ID",
|
|
8636
|
+
message: "Anchor selector is unusually long",
|
|
8637
|
+
suggestion: "Consider using a shorter, more descriptive selector"
|
|
8638
|
+
});
|
|
8639
|
+
}
|
|
8640
|
+
if (anchorId.route === void 0 || anchorId.route === null) {
|
|
8641
|
+
errors.push({
|
|
8642
|
+
code: "MISSING_ANCHOR_ROUTE",
|
|
8643
|
+
message: `anchorId requires a 'route' (string or array of strings). Use "**" for all routes.`,
|
|
8644
|
+
field: "anchorId.route"
|
|
8645
|
+
});
|
|
8646
|
+
} else {
|
|
8647
|
+
const routes = Array.isArray(anchorId.route) ? anchorId.route : [anchorId.route];
|
|
8648
|
+
for (const route of routes) {
|
|
8649
|
+
if (typeof route !== "string") {
|
|
8650
|
+
errors.push({
|
|
8651
|
+
code: "INVALID_ANCHOR_ROUTE",
|
|
8652
|
+
message: "anchorId.route must be a string or array of strings",
|
|
8653
|
+
field: "anchorId.route"
|
|
8654
|
+
});
|
|
8655
|
+
break;
|
|
8656
|
+
}
|
|
8657
|
+
}
|
|
8658
|
+
}
|
|
8659
|
+
}
|
|
8660
|
+
function validateActions(actions) {
|
|
7955
8661
|
var _a2;
|
|
7956
8662
|
const errors = [];
|
|
7957
8663
|
const warnings = [];
|
|
@@ -8097,7 +8803,7 @@ function createActionEngine(options) {
|
|
|
8097
8803
|
}
|
|
8098
8804
|
return executor(action, context);
|
|
8099
8805
|
}
|
|
8100
|
-
function subscribeForReeval(id, action, triggerWhen,
|
|
8806
|
+
function subscribeForReeval(id, action, triggerWhen, _handle) {
|
|
8101
8807
|
if (!runtime3) return;
|
|
8102
8808
|
const unsubs = [];
|
|
8103
8809
|
const onReeval = async () => {
|
|
@@ -8241,13 +8947,9 @@ function createActionEngine(options) {
|
|
|
8241
8947
|
entry2.state = "reverted";
|
|
8242
8948
|
publishEvent("action.reverted", { id, kind: action.kind });
|
|
8243
8949
|
} catch (error2) {
|
|
8244
|
-
|
|
8245
|
-
|
|
8246
|
-
|
|
8247
|
-
kind: action.kind,
|
|
8248
|
-
error: String(error2)
|
|
8249
|
-
});
|
|
8250
|
-
throw error2;
|
|
8950
|
+
console.warn(`[ActionEngine] Cleanup error for ${action.kind} (${id}), ignoring:`, error2);
|
|
8951
|
+
entry2.state = "reverted";
|
|
8952
|
+
publishEvent("action.reverted", { id, kind: action.kind });
|
|
8251
8953
|
} finally {
|
|
8252
8954
|
activeActions.delete(id);
|
|
8253
8955
|
}
|
|
@@ -8291,7 +8993,7 @@ function createActionEngine(options) {
|
|
|
8291
8993
|
errorMessages,
|
|
8292
8994
|
"\nActions:",
|
|
8293
8995
|
actions.map(
|
|
8294
|
-
(a, i) => ` [${i}] ${a.kind} ${a.anchorId ? `anchor="${
|
|
8996
|
+
(a, i) => ` [${i}] ${a.kind} ${a.anchorId ? `anchor="${a.anchorId.selector}"` : ""} ${a.label ? `label="${a.label}"` : ""}`
|
|
8295
8997
|
).join("\n")
|
|
8296
8998
|
);
|
|
8297
8999
|
throw new Error(`Batch validation failed: ${errorMessages}`);
|
|
@@ -8391,6 +9093,7 @@ function createAnchorResolver(opts) {
|
|
|
8391
9093
|
function resolve(selector) {
|
|
8392
9094
|
if (!root) return null;
|
|
8393
9095
|
try {
|
|
9096
|
+
if (root.matches(selector)) return root;
|
|
8394
9097
|
return root.querySelector(selector);
|
|
8395
9098
|
} catch {
|
|
8396
9099
|
return null;
|
|
@@ -8736,7 +9439,7 @@ function createContextManager(options) {
|
|
|
8736
9439
|
|
|
8737
9440
|
// src/decisions/strategies/rules.ts
|
|
8738
9441
|
function evaluateCondition(condition, evalContext) {
|
|
8739
|
-
var _a2, _b, _c, _d, _e
|
|
9442
|
+
var _a2, _b, _c, _d, _e;
|
|
8740
9443
|
const { context, state, events } = evalContext;
|
|
8741
9444
|
switch (condition.type) {
|
|
8742
9445
|
case "page_url": {
|
|
@@ -8750,8 +9453,7 @@ function evaluateCondition(condition, evalContext) {
|
|
|
8750
9453
|
return context.page.routeId === condition.routeId;
|
|
8751
9454
|
}
|
|
8752
9455
|
case "anchor_visible": {
|
|
8753
|
-
const
|
|
8754
|
-
const anchor = (_c = context.anchors) == null ? void 0 : _c.find((a) => a.anchorId === condSelector);
|
|
9456
|
+
const anchor = (_a2 = context.anchors) == null ? void 0 : _a2.find((a) => a.anchorId === condition.anchorId);
|
|
8755
9457
|
switch (condition.state) {
|
|
8756
9458
|
case "visible":
|
|
8757
9459
|
return (anchor == null ? void 0 : anchor.visible) === true;
|
|
@@ -8765,7 +9467,7 @@ function evaluateCondition(condition, evalContext) {
|
|
|
8765
9467
|
}
|
|
8766
9468
|
case "event_occurred": {
|
|
8767
9469
|
if (!events) return false;
|
|
8768
|
-
const withinMs = (
|
|
9470
|
+
const withinMs = (_b = condition.withinMs) != null ? _b : 6e4;
|
|
8769
9471
|
return events.hasRecentEvent(condition.eventName, withinMs);
|
|
8770
9472
|
}
|
|
8771
9473
|
case "state_equals": {
|
|
@@ -8801,17 +9503,17 @@ function evaluateCondition(condition, evalContext) {
|
|
|
8801
9503
|
}
|
|
8802
9504
|
}
|
|
8803
9505
|
case "dismissed": {
|
|
8804
|
-
if (!state) return (
|
|
9506
|
+
if (!state) return (_c = condition.inverted) != null ? _c : false;
|
|
8805
9507
|
const isDismissed = state.isDismissed(condition.key);
|
|
8806
9508
|
return condition.inverted ? !isDismissed : isDismissed;
|
|
8807
9509
|
}
|
|
8808
9510
|
case "cooldown_active": {
|
|
8809
|
-
if (!state) return (
|
|
9511
|
+
if (!state) return (_d = condition.inverted) != null ? _d : false;
|
|
8810
9512
|
const isActive = state.isCooldownActive(condition.key);
|
|
8811
9513
|
return condition.inverted ? !isActive : isActive;
|
|
8812
9514
|
}
|
|
8813
9515
|
case "frequency_limit": {
|
|
8814
|
-
if (!state) return (
|
|
9516
|
+
if (!state) return (_e = condition.inverted) != null ? _e : false;
|
|
8815
9517
|
const count = state.getFrequencyCount(condition.key);
|
|
8816
9518
|
const limitReached = count >= condition.limit;
|
|
8817
9519
|
return condition.inverted ? !limitReached : limitReached;
|
|
@@ -9071,6 +9773,66 @@ function createEventAccumulator(options) {
|
|
|
9071
9773
|
};
|
|
9072
9774
|
}
|
|
9073
9775
|
|
|
9776
|
+
// src/events/validation.ts
|
|
9777
|
+
var APP_PREFIX = "app:";
|
|
9778
|
+
var RESERVED_PREFIX = "syntro:";
|
|
9779
|
+
var SEGMENT_PATTERN = /^[a-z][a-z0-9_]*$/;
|
|
9780
|
+
function validateEventName(name) {
|
|
9781
|
+
if (!name) {
|
|
9782
|
+
return { valid: false, reason: "Event name cannot be empty" };
|
|
9783
|
+
}
|
|
9784
|
+
if (name.startsWith(RESERVED_PREFIX)) {
|
|
9785
|
+
return { valid: false, reason: '"syntro:" prefix is reserved for internal SDK events' };
|
|
9786
|
+
}
|
|
9787
|
+
if (!name.startsWith(APP_PREFIX)) {
|
|
9788
|
+
return { valid: false, reason: `Custom events must start with "app:" prefix. Got: "${name}"` };
|
|
9789
|
+
}
|
|
9790
|
+
const segments = name.slice(APP_PREFIX.length).split(":");
|
|
9791
|
+
if (segments.length < 2) {
|
|
9792
|
+
return {
|
|
9793
|
+
valid: false,
|
|
9794
|
+
reason: `Event name must have at least 2 segments after "app:" (app:{category}:{action}). Got: "${name}"`
|
|
9795
|
+
};
|
|
9796
|
+
}
|
|
9797
|
+
for (const segment of segments) {
|
|
9798
|
+
if (!SEGMENT_PATTERN.test(segment)) {
|
|
9799
|
+
return {
|
|
9800
|
+
valid: false,
|
|
9801
|
+
reason: `Segment "${segment}" must be lowercase alphanumeric + underscores. Got: "${name}"`
|
|
9802
|
+
};
|
|
9803
|
+
}
|
|
9804
|
+
}
|
|
9805
|
+
return { valid: true };
|
|
9806
|
+
}
|
|
9807
|
+
function isSerializable(value) {
|
|
9808
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null;
|
|
9809
|
+
}
|
|
9810
|
+
function checkDepth(obj, maxDepth, current = 0) {
|
|
9811
|
+
if (current >= maxDepth) return false;
|
|
9812
|
+
for (const value of Object.values(obj)) {
|
|
9813
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
9814
|
+
if (!checkDepth(value, maxDepth, current + 1)) return false;
|
|
9815
|
+
}
|
|
9816
|
+
}
|
|
9817
|
+
return true;
|
|
9818
|
+
}
|
|
9819
|
+
function validateProps(props) {
|
|
9820
|
+
if (props === void 0) return { valid: true };
|
|
9821
|
+
if (props === null || typeof props !== "object" || Array.isArray(props)) {
|
|
9822
|
+
return { valid: false, reason: "Props must be a plain object" };
|
|
9823
|
+
}
|
|
9824
|
+
if (!checkDepth(props, 2)) {
|
|
9825
|
+
return { valid: false, reason: "Props nesting depth exceeds 2 levels" };
|
|
9826
|
+
}
|
|
9827
|
+
const stripped = [];
|
|
9828
|
+
for (const [key, value] of Object.entries(props)) {
|
|
9829
|
+
if (value !== null && typeof value === "object") continue;
|
|
9830
|
+
if (!isSerializable(value)) stripped.push(key);
|
|
9831
|
+
}
|
|
9832
|
+
if (stripped.length > 0) return { valid: true, stripped };
|
|
9833
|
+
return { valid: true };
|
|
9834
|
+
}
|
|
9835
|
+
|
|
9074
9836
|
// src/events/EventBus.ts
|
|
9075
9837
|
function matchesFilter(event, filter) {
|
|
9076
9838
|
if (!filter) return true;
|
|
@@ -9102,8 +9864,16 @@ var EventBus = class {
|
|
|
9102
9864
|
__publicField(this, "subscriptions", /* @__PURE__ */ new Set());
|
|
9103
9865
|
__publicField(this, "history", []);
|
|
9104
9866
|
__publicField(this, "maxHistorySize");
|
|
9105
|
-
|
|
9867
|
+
__publicField(this, "debug");
|
|
9868
|
+
__publicField(this, "emitHistory");
|
|
9869
|
+
__publicField(this, "posthogCapture");
|
|
9870
|
+
__publicField(this, "testMode");
|
|
9871
|
+
var _a2, _b, _c, _d, _e;
|
|
9106
9872
|
this.maxHistorySize = (_a2 = options.maxHistorySize) != null ? _a2 : 100;
|
|
9873
|
+
this.debug = (_b = options.debug) != null ? _b : false;
|
|
9874
|
+
this.emitHistory = (_c = options.history) != null ? _c : null;
|
|
9875
|
+
this.posthogCapture = (_d = options.posthogCapture) != null ? _d : null;
|
|
9876
|
+
this.testMode = (_e = options.testMode) != null ? _e : false;
|
|
9107
9877
|
}
|
|
9108
9878
|
/**
|
|
9109
9879
|
* Subscribe to events matching an optional filter.
|
|
@@ -9156,6 +9926,83 @@ var EventBus = class {
|
|
|
9156
9926
|
}
|
|
9157
9927
|
}
|
|
9158
9928
|
}
|
|
9929
|
+
/**
|
|
9930
|
+
* Emit a validated custom event from the host application.
|
|
9931
|
+
*
|
|
9932
|
+
* Custom events must use the `app:` prefix (e.g. `app:cart:abandoned`).
|
|
9933
|
+
* In debug mode, returns an EmitResult with delivery details.
|
|
9934
|
+
* In production mode, returns undefined.
|
|
9935
|
+
*/
|
|
9936
|
+
emit(name, props) {
|
|
9937
|
+
const nameResult = validateEventName(name);
|
|
9938
|
+
if (!nameResult.valid) {
|
|
9939
|
+
console.warn(`[EventBus] emit() rejected: ${nameResult.reason}`);
|
|
9940
|
+
return this.debug ? { delivered: false, matchedRules: [], posthogCaptured: false, listenersNotified: 0 } : void 0;
|
|
9941
|
+
}
|
|
9942
|
+
const propsResult = validateProps(props);
|
|
9943
|
+
if (!propsResult.valid) {
|
|
9944
|
+
console.warn(`[EventBus] emit() rejected props: ${propsResult.reason}`);
|
|
9945
|
+
return this.debug ? { delivered: false, matchedRules: [], posthogCaptured: false, listenersNotified: 0 } : void 0;
|
|
9946
|
+
}
|
|
9947
|
+
const event = {
|
|
9948
|
+
ts: Date.now(),
|
|
9949
|
+
name,
|
|
9950
|
+
source: "custom",
|
|
9951
|
+
props,
|
|
9952
|
+
schemaVersion: EVENT_SCHEMA_VERSION
|
|
9953
|
+
};
|
|
9954
|
+
this.history.push(event);
|
|
9955
|
+
if (this.history.length > this.maxHistorySize) {
|
|
9956
|
+
this.history.shift();
|
|
9957
|
+
}
|
|
9958
|
+
let listenersNotified = 0;
|
|
9959
|
+
for (const subscription of this.subscriptions) {
|
|
9960
|
+
if (matchesFilter(event, subscription.filter)) {
|
|
9961
|
+
try {
|
|
9962
|
+
subscription.callback(event);
|
|
9963
|
+
listenersNotified++;
|
|
9964
|
+
} catch (err) {
|
|
9965
|
+
console.error("[EventBus] Subscriber error:", err);
|
|
9966
|
+
listenersNotified++;
|
|
9967
|
+
}
|
|
9968
|
+
}
|
|
9969
|
+
}
|
|
9970
|
+
let posthogCaptured = false;
|
|
9971
|
+
if (this.posthogCapture && !this.testMode) {
|
|
9972
|
+
try {
|
|
9973
|
+
this.posthogCapture(name, props);
|
|
9974
|
+
posthogCaptured = true;
|
|
9975
|
+
} catch (err) {
|
|
9976
|
+
console.error("[EventBus] PostHog capture error:", err);
|
|
9977
|
+
}
|
|
9978
|
+
}
|
|
9979
|
+
if (this.emitHistory) {
|
|
9980
|
+
this.emitHistory.record({
|
|
9981
|
+
name,
|
|
9982
|
+
props,
|
|
9983
|
+
source: "custom",
|
|
9984
|
+
timestamp: event.ts,
|
|
9985
|
+
matchedRules: []
|
|
9986
|
+
});
|
|
9987
|
+
}
|
|
9988
|
+
if (this.debug) {
|
|
9989
|
+
console.debug("[EventBus] emit()", { name, props, listenersNotified, posthogCaptured });
|
|
9990
|
+
return {
|
|
9991
|
+
delivered: true,
|
|
9992
|
+
matchedRules: [],
|
|
9993
|
+
posthogCaptured,
|
|
9994
|
+
listenersNotified
|
|
9995
|
+
};
|
|
9996
|
+
}
|
|
9997
|
+
return void 0;
|
|
9998
|
+
}
|
|
9999
|
+
/**
|
|
10000
|
+
* Set the PostHog capture function after construction.
|
|
10001
|
+
* Used by bootstrap to wire PostHog after the EventBus is created.
|
|
10002
|
+
*/
|
|
10003
|
+
setPosthogCapture(fn) {
|
|
10004
|
+
this.posthogCapture = fn;
|
|
10005
|
+
}
|
|
9159
10006
|
/**
|
|
9160
10007
|
* Get recent events matching an optional filter.
|
|
9161
10008
|
*/
|
|
@@ -9199,132 +10046,34 @@ var EventBus = class {
|
|
|
9199
10046
|
* Get the number of current subscribers.
|
|
9200
10047
|
*/
|
|
9201
10048
|
getSubscriberCount() {
|
|
9202
|
-
return this.subscriptions.size;
|
|
9203
|
-
}
|
|
9204
|
-
};
|
|
9205
|
-
function createEventBus(options = {}) {
|
|
9206
|
-
return new EventBus(options);
|
|
9207
|
-
}
|
|
9208
|
-
|
|
9209
|
-
// src/events/normalizers/posthog.ts
|
|
9210
|
-
var POSTHOG_EVENT_MAP = {
|
|
9211
|
-
// Autocapture events
|
|
9212
|
-
$autocapture: "ui.click",
|
|
9213
|
-
// Default autocapture is usually clicks
|
|
9214
|
-
$click: StandardEvents.UI_CLICK,
|
|
9215
|
-
$scroll: StandardEvents.UI_SCROLL,
|
|
9216
|
-
$input: StandardEvents.UI_INPUT,
|
|
9217
|
-
$change: StandardEvents.UI_CHANGE,
|
|
9218
|
-
$submit: StandardEvents.UI_SUBMIT,
|
|
9219
|
-
// Navigation events
|
|
9220
|
-
$pageview: StandardEvents.NAV_PAGE_VIEW,
|
|
9221
|
-
$pageleave: StandardEvents.NAV_PAGE_LEAVE,
|
|
9222
|
-
// Session events
|
|
9223
|
-
$session_start: "session.start",
|
|
9224
|
-
// Identify events
|
|
9225
|
-
$identify: "user.identify"
|
|
9226
|
-
};
|
|
9227
|
-
function getEventName(phEvent) {
|
|
9228
|
-
var _a2, _b;
|
|
9229
|
-
const eventName = phEvent.event;
|
|
9230
|
-
if (typeof eventName !== "string") {
|
|
9231
|
-
return "posthog.unknown";
|
|
9232
|
-
}
|
|
9233
|
-
if (POSTHOG_EVENT_MAP[eventName]) {
|
|
9234
|
-
return POSTHOG_EVENT_MAP[eventName];
|
|
9235
|
-
}
|
|
9236
|
-
if (eventName === "$autocapture") {
|
|
9237
|
-
const tagName = (_a2 = phEvent.properties) == null ? void 0 : _a2.$tag_name;
|
|
9238
|
-
const eventType = (_b = phEvent.properties) == null ? void 0 : _b.$event_type;
|
|
9239
|
-
if (eventType === "submit") return StandardEvents.UI_SUBMIT;
|
|
9240
|
-
if (eventType === "change") return StandardEvents.UI_CHANGE;
|
|
9241
|
-
if (tagName === "input" || tagName === "textarea") return StandardEvents.UI_INPUT;
|
|
9242
|
-
return StandardEvents.UI_CLICK;
|
|
9243
|
-
}
|
|
9244
|
-
if (!eventName.startsWith("$")) {
|
|
9245
|
-
return `posthog.${eventName}`;
|
|
9246
|
-
}
|
|
9247
|
-
return eventName.replace("$", "posthog.");
|
|
9248
|
-
}
|
|
9249
|
-
function extractProps(phEvent) {
|
|
9250
|
-
var _a2;
|
|
9251
|
-
const props = {};
|
|
9252
|
-
const phProps = phEvent.properties || {};
|
|
9253
|
-
const elements = phProps.$elements;
|
|
9254
|
-
if (phProps.$tag_name) {
|
|
9255
|
-
props.tagName = phProps.$tag_name;
|
|
9256
|
-
} else if ((_a2 = elements == null ? void 0 : elements[0]) == null ? void 0 : _a2.tag_name) {
|
|
9257
|
-
props.tagName = elements[0].tag_name;
|
|
9258
|
-
}
|
|
9259
|
-
if (phProps.$el_text) props.elementText = phProps.$el_text;
|
|
9260
|
-
if (elements) props.elements = elements;
|
|
9261
|
-
if (phProps.$current_url) props.url = phProps.$current_url;
|
|
9262
|
-
if (phProps.$pathname) props.pathname = phProps.$pathname;
|
|
9263
|
-
if (phProps.$host) props.host = phProps.$host;
|
|
9264
|
-
if (phProps.$viewport_width) props.viewportWidth = phProps.$viewport_width;
|
|
9265
|
-
if (phProps.$viewport_height) props.viewportHeight = phProps.$viewport_height;
|
|
9266
|
-
if (phProps.$session_id) props.sessionId = phProps.$session_id;
|
|
9267
|
-
if (phProps.$scroll_depth) props.scrollDepth = phProps.$scroll_depth;
|
|
9268
|
-
if (phProps.$scroll_percentage) props.scrollPercentage = phProps.$scroll_percentage;
|
|
9269
|
-
props.originalEvent = phEvent.event;
|
|
9270
|
-
return props;
|
|
9271
|
-
}
|
|
9272
|
-
function normalizePostHogEvent(phEvent) {
|
|
9273
|
-
let ts;
|
|
9274
|
-
if (typeof phEvent.timestamp === "number") {
|
|
9275
|
-
ts = phEvent.timestamp;
|
|
9276
|
-
} else if (typeof phEvent.timestamp === "string") {
|
|
9277
|
-
ts = new Date(phEvent.timestamp).getTime();
|
|
9278
|
-
} else {
|
|
9279
|
-
ts = Date.now();
|
|
9280
|
-
}
|
|
9281
|
-
return {
|
|
9282
|
-
ts,
|
|
9283
|
-
name: getEventName(phEvent),
|
|
9284
|
-
source: "posthog",
|
|
9285
|
-
props: extractProps(phEvent),
|
|
9286
|
-
schemaVersion: EVENT_SCHEMA_VERSION
|
|
9287
|
-
};
|
|
9288
|
-
}
|
|
9289
|
-
function shouldNormalizeEvent(phEvent) {
|
|
9290
|
-
const eventName = phEvent.event;
|
|
9291
|
-
if (typeof eventName !== "string") return false;
|
|
9292
|
-
const skipEvents = [
|
|
9293
|
-
"$feature_flag_called",
|
|
9294
|
-
"$feature_flags",
|
|
9295
|
-
"$groups",
|
|
9296
|
-
"$groupidentify",
|
|
9297
|
-
"$set",
|
|
9298
|
-
"$set_once",
|
|
9299
|
-
"$unset",
|
|
9300
|
-
"$create_alias",
|
|
9301
|
-
"$capture_metrics",
|
|
9302
|
-
"$performance_event",
|
|
9303
|
-
"$web_vitals",
|
|
9304
|
-
"$exception",
|
|
9305
|
-
"$dead_click",
|
|
9306
|
-
"$heatmap"
|
|
9307
|
-
];
|
|
9308
|
-
if (skipEvents.includes(eventName)) {
|
|
9309
|
-
return false;
|
|
9310
|
-
}
|
|
9311
|
-
return true;
|
|
9312
|
-
}
|
|
9313
|
-
function createPostHogNormalizer(publishFn) {
|
|
9314
|
-
return (eventName, properties) => {
|
|
9315
|
-
if (typeof eventName !== "string") return;
|
|
9316
|
-
const phEvent = {
|
|
9317
|
-
event: eventName,
|
|
9318
|
-
properties,
|
|
9319
|
-
timestamp: Date.now()
|
|
9320
|
-
};
|
|
9321
|
-
if (shouldNormalizeEvent(phEvent)) {
|
|
9322
|
-
const normalizedEvent = normalizePostHogEvent(phEvent);
|
|
9323
|
-
publishFn(normalizedEvent);
|
|
9324
|
-
}
|
|
9325
|
-
};
|
|
10049
|
+
return this.subscriptions.size;
|
|
10050
|
+
}
|
|
10051
|
+
};
|
|
10052
|
+
function createEventBus(options = {}) {
|
|
10053
|
+
return new EventBus(options);
|
|
9326
10054
|
}
|
|
9327
10055
|
|
|
10056
|
+
// src/events/history.ts
|
|
10057
|
+
var EventHistory = class {
|
|
10058
|
+
constructor(maxSize = 100) {
|
|
10059
|
+
__publicField(this, "entries", []);
|
|
10060
|
+
__publicField(this, "maxSize");
|
|
10061
|
+
this.maxSize = maxSize;
|
|
10062
|
+
}
|
|
10063
|
+
record(entry) {
|
|
10064
|
+
this.entries.push(entry);
|
|
10065
|
+
if (this.maxSize > 0 && this.entries.length > this.maxSize) {
|
|
10066
|
+
this.entries.shift();
|
|
10067
|
+
}
|
|
10068
|
+
}
|
|
10069
|
+
getAll() {
|
|
10070
|
+
return [...this.entries];
|
|
10071
|
+
}
|
|
10072
|
+
clear() {
|
|
10073
|
+
this.entries = [];
|
|
10074
|
+
}
|
|
10075
|
+
};
|
|
10076
|
+
|
|
9328
10077
|
// src/navigation/NavigationMonitor.ts
|
|
9329
10078
|
var NavigationMonitor = class {
|
|
9330
10079
|
constructor() {
|
|
@@ -10124,9 +10873,18 @@ function createSurfaces(options) {
|
|
|
10124
10873
|
}
|
|
10125
10874
|
async function unmountEntry(entry) {
|
|
10126
10875
|
var _a2;
|
|
10127
|
-
|
|
10128
|
-
|
|
10129
|
-
|
|
10876
|
+
if (entry.container.isConnected) {
|
|
10877
|
+
await playExitAnimation(entry.container, entry.options.animation);
|
|
10878
|
+
}
|
|
10879
|
+
try {
|
|
10880
|
+
(_a2 = entry.cleanup) == null ? void 0 : _a2.call(entry);
|
|
10881
|
+
} catch (error2) {
|
|
10882
|
+
console.warn("[Surfaces] Cleanup error during unmount, ignoring:", error2);
|
|
10883
|
+
}
|
|
10884
|
+
try {
|
|
10885
|
+
entry.container.remove();
|
|
10886
|
+
} catch {
|
|
10887
|
+
}
|
|
10130
10888
|
mounts.delete(entry.slot);
|
|
10131
10889
|
publishEvent("surface.unmounted", {
|
|
10132
10890
|
slot: entry.slot,
|
|
@@ -10309,7 +11067,9 @@ var WidgetRegistry = class {
|
|
|
10309
11067
|
var _a2;
|
|
10310
11068
|
const mounted = this.mountedWidgets.get(mountId);
|
|
10311
11069
|
if (mounted) {
|
|
10312
|
-
(
|
|
11070
|
+
if (container.isConnected) {
|
|
11071
|
+
(_a2 = mounted.cleanup) == null ? void 0 : _a2.call(mounted);
|
|
11072
|
+
}
|
|
10313
11073
|
this.mountedWidgets.delete(mountId);
|
|
10314
11074
|
container.removeAttribute("data-widget-mount-id");
|
|
10315
11075
|
container.removeAttribute("data-widget-id");
|
|
@@ -10425,7 +11185,16 @@ function matchesAnchorRoute(anchorId) {
|
|
|
10425
11185
|
const pathname = typeof window !== "undefined" ? window.location.pathname : "/";
|
|
10426
11186
|
const normalizedPath = pathname.replace(/\/$/, "") || "/";
|
|
10427
11187
|
const routes = Array.isArray(anchorId.route) ? anchorId.route : [anchorId.route];
|
|
10428
|
-
return routes.some((pattern) =>
|
|
11188
|
+
return routes.some((pattern) => {
|
|
11189
|
+
let normalized = pattern;
|
|
11190
|
+
if (/^https?:\/\//.test(normalized)) {
|
|
11191
|
+
try {
|
|
11192
|
+
normalized = new URL(normalized).pathname;
|
|
11193
|
+
} catch {
|
|
11194
|
+
}
|
|
11195
|
+
}
|
|
11196
|
+
return matchRoutePattern(normalizedPath, normalized);
|
|
11197
|
+
});
|
|
10429
11198
|
}
|
|
10430
11199
|
function createSmartCanvasRuntime(options = {}) {
|
|
10431
11200
|
var _a2, _b, _c, _d;
|
|
@@ -10597,6 +11366,142 @@ function encodeToken(payload) {
|
|
|
10597
11366
|
return TOKEN_PREFIX + base64;
|
|
10598
11367
|
}
|
|
10599
11368
|
|
|
11369
|
+
// src/bootstrap-init.ts
|
|
11370
|
+
function getEnvVar(name) {
|
|
11371
|
+
if (typeof process !== "undefined" && process.env) {
|
|
11372
|
+
return process.env[name];
|
|
11373
|
+
}
|
|
11374
|
+
try {
|
|
11375
|
+
const meta = (0, eval)("import.meta");
|
|
11376
|
+
if (meta == null ? void 0 : meta.env) {
|
|
11377
|
+
return meta.env[name];
|
|
11378
|
+
}
|
|
11379
|
+
} catch {
|
|
11380
|
+
}
|
|
11381
|
+
return void 0;
|
|
11382
|
+
}
|
|
11383
|
+
var SEGMENT_CACHE_KEY = "syntro_segment_attributes";
|
|
11384
|
+
function loadCachedSegmentAttributes() {
|
|
11385
|
+
if (typeof window === "undefined") return {};
|
|
11386
|
+
try {
|
|
11387
|
+
const cached = localStorage.getItem(SEGMENT_CACHE_KEY);
|
|
11388
|
+
if (cached) {
|
|
11389
|
+
const attrs = JSON.parse(cached);
|
|
11390
|
+
debug("Syntro Bootstrap", "Loaded cached segment attributes:", attrs);
|
|
11391
|
+
return attrs;
|
|
11392
|
+
}
|
|
11393
|
+
} catch (err) {
|
|
11394
|
+
warn("Syntro Bootstrap", "Failed to load cached segment attributes:", err);
|
|
11395
|
+
}
|
|
11396
|
+
return {};
|
|
11397
|
+
}
|
|
11398
|
+
function cacheSegmentAttributes(attrs) {
|
|
11399
|
+
if (typeof window === "undefined") return;
|
|
11400
|
+
try {
|
|
11401
|
+
localStorage.setItem(SEGMENT_CACHE_KEY, JSON.stringify(attrs));
|
|
11402
|
+
debug("Syntro Bootstrap", "Cached segment attributes:", attrs);
|
|
11403
|
+
} catch (err) {
|
|
11404
|
+
warn("Syntro Bootstrap", "Failed to cache segment attributes:", err);
|
|
11405
|
+
}
|
|
11406
|
+
}
|
|
11407
|
+
function extractSegmentFlags(allFlags) {
|
|
11408
|
+
if (!allFlags) return {};
|
|
11409
|
+
const segmentFlags = {};
|
|
11410
|
+
for (const [key, value] of Object.entries(allFlags)) {
|
|
11411
|
+
if (key.startsWith("in_segment_")) {
|
|
11412
|
+
segmentFlags[key] = value === true;
|
|
11413
|
+
}
|
|
11414
|
+
}
|
|
11415
|
+
return segmentFlags;
|
|
11416
|
+
}
|
|
11417
|
+
function collectBrowserMetadata() {
|
|
11418
|
+
var _a2;
|
|
11419
|
+
if (typeof window === "undefined") return {};
|
|
11420
|
+
const attrs = {};
|
|
11421
|
+
try {
|
|
11422
|
+
const params = new URLSearchParams(window.location.search);
|
|
11423
|
+
for (const key of ["utm_source", "utm_medium", "utm_campaign", "utm_content", "utm_term"]) {
|
|
11424
|
+
const val = params.get(key);
|
|
11425
|
+
if (val) attrs[key] = val;
|
|
11426
|
+
}
|
|
11427
|
+
} catch {
|
|
11428
|
+
}
|
|
11429
|
+
try {
|
|
11430
|
+
if (navigator.language) attrs.browser_language = navigator.language;
|
|
11431
|
+
if ((_a2 = navigator.languages) == null ? void 0 : _a2.length) attrs.browser_languages = [...navigator.languages];
|
|
11432
|
+
} catch {
|
|
11433
|
+
}
|
|
11434
|
+
try {
|
|
11435
|
+
const w = window.innerWidth;
|
|
11436
|
+
attrs.device_type = w < 768 ? "mobile" : w < 1024 ? "tablet" : "desktop";
|
|
11437
|
+
} catch {
|
|
11438
|
+
}
|
|
11439
|
+
try {
|
|
11440
|
+
if (document.referrer) {
|
|
11441
|
+
attrs.referrer = document.referrer;
|
|
11442
|
+
try {
|
|
11443
|
+
attrs.referrer_hostname = new URL(document.referrer).hostname;
|
|
11444
|
+
} catch {
|
|
11445
|
+
}
|
|
11446
|
+
}
|
|
11447
|
+
} catch {
|
|
11448
|
+
}
|
|
11449
|
+
try {
|
|
11450
|
+
const ua = navigator.userAgent;
|
|
11451
|
+
if (ua.includes("Edg/")) attrs.browser = "Edge";
|
|
11452
|
+
else if (ua.includes("OPR/") || ua.includes("Opera")) attrs.browser = "Opera";
|
|
11453
|
+
else if (ua.includes("Chrome/") && !ua.includes("Chromium")) attrs.browser = "Chrome";
|
|
11454
|
+
else if (ua.includes("Safari/") && !ua.includes("Chrome")) attrs.browser = "Safari";
|
|
11455
|
+
else if (ua.includes("Firefox/")) attrs.browser = "Firefox";
|
|
11456
|
+
if (ua.includes("Windows")) attrs.os = "Windows";
|
|
11457
|
+
else if (ua.includes("iPhone") || ua.includes("iPad")) attrs.os = "iOS";
|
|
11458
|
+
else if (ua.includes("Mac OS X") || ua.includes("Macintosh")) attrs.os = "macOS";
|
|
11459
|
+
else if (ua.includes("Android")) attrs.os = "Android";
|
|
11460
|
+
else if (ua.includes("Linux")) attrs.os = "Linux";
|
|
11461
|
+
} catch {
|
|
11462
|
+
}
|
|
11463
|
+
try {
|
|
11464
|
+
attrs.page_url = window.location.href;
|
|
11465
|
+
attrs.page_path = window.location.pathname;
|
|
11466
|
+
attrs.page_host = window.location.hostname;
|
|
11467
|
+
if (window.location.search) attrs.page_query = window.location.search;
|
|
11468
|
+
} catch {
|
|
11469
|
+
}
|
|
11470
|
+
return attrs;
|
|
11471
|
+
}
|
|
11472
|
+
var GEO_CACHE_KEY = "syntro_geo";
|
|
11473
|
+
var GEO_DEFAULT_HOST = "https://geo.syntrologie.com";
|
|
11474
|
+
async function fetchGeo(geoHost) {
|
|
11475
|
+
if (typeof window === "undefined") return {};
|
|
11476
|
+
try {
|
|
11477
|
+
const cached = localStorage.getItem(GEO_CACHE_KEY);
|
|
11478
|
+
if (cached) {
|
|
11479
|
+
const parsed = JSON.parse(cached);
|
|
11480
|
+
debug("Syntro Bootstrap", "Geo: using cached data:", parsed);
|
|
11481
|
+
return parsed;
|
|
11482
|
+
}
|
|
11483
|
+
} catch {
|
|
11484
|
+
}
|
|
11485
|
+
try {
|
|
11486
|
+
const res = await fetch(geoHost, { signal: AbortSignal.timeout(2e3) });
|
|
11487
|
+
if (res.ok) {
|
|
11488
|
+
const geo = await res.json();
|
|
11489
|
+
const cleaned = {};
|
|
11490
|
+
for (const [k, v] of Object.entries(geo)) {
|
|
11491
|
+
if (typeof v === "string" && v) cleaned[k] = v;
|
|
11492
|
+
}
|
|
11493
|
+
try {
|
|
11494
|
+
localStorage.setItem(GEO_CACHE_KEY, JSON.stringify(cleaned));
|
|
11495
|
+
} catch {
|
|
11496
|
+
}
|
|
11497
|
+
debug("Syntro Bootstrap", "Geo: fetched from worker:", cleaned);
|
|
11498
|
+
return cleaned;
|
|
11499
|
+
}
|
|
11500
|
+
} catch {
|
|
11501
|
+
}
|
|
11502
|
+
return {};
|
|
11503
|
+
}
|
|
11504
|
+
|
|
10600
11505
|
// src/experiments/registry.ts
|
|
10601
11506
|
var adapters = {
|
|
10602
11507
|
growthbook: (config) => createGrowthBookClient({
|
|
@@ -10845,95 +11750,9 @@ function createTelemetryClient(provider, config) {
|
|
|
10845
11750
|
return factory(config);
|
|
10846
11751
|
}
|
|
10847
11752
|
|
|
10848
|
-
// src/bootstrap.ts
|
|
10849
|
-
function
|
|
10850
|
-
|
|
10851
|
-
return process.env[name];
|
|
10852
|
-
}
|
|
10853
|
-
try {
|
|
10854
|
-
const meta = (0, eval)("import.meta");
|
|
10855
|
-
if (meta == null ? void 0 : meta.env) {
|
|
10856
|
-
return meta.env[name];
|
|
10857
|
-
}
|
|
10858
|
-
} catch {
|
|
10859
|
-
}
|
|
10860
|
-
return void 0;
|
|
10861
|
-
}
|
|
10862
|
-
var SEGMENT_CACHE_KEY = "syntro_segment_attributes";
|
|
10863
|
-
function loadCachedSegmentAttributes() {
|
|
10864
|
-
if (typeof window === "undefined") return {};
|
|
10865
|
-
try {
|
|
10866
|
-
const cached = localStorage.getItem(SEGMENT_CACHE_KEY);
|
|
10867
|
-
if (cached) {
|
|
10868
|
-
const attrs = JSON.parse(cached);
|
|
10869
|
-
debug("Syntro Bootstrap", "Loaded cached segment attributes:", attrs);
|
|
10870
|
-
return attrs;
|
|
10871
|
-
}
|
|
10872
|
-
} catch (err) {
|
|
10873
|
-
warn("Syntro Bootstrap", "Failed to load cached segment attributes:", err);
|
|
10874
|
-
}
|
|
10875
|
-
return {};
|
|
10876
|
-
}
|
|
10877
|
-
function cacheSegmentAttributes(attrs) {
|
|
10878
|
-
if (typeof window === "undefined") return;
|
|
10879
|
-
try {
|
|
10880
|
-
localStorage.setItem(SEGMENT_CACHE_KEY, JSON.stringify(attrs));
|
|
10881
|
-
debug("Syntro Bootstrap", "Cached segment attributes:", attrs);
|
|
10882
|
-
} catch (err) {
|
|
10883
|
-
warn("Syntro Bootstrap", "Failed to cache segment attributes:", err);
|
|
10884
|
-
}
|
|
10885
|
-
}
|
|
10886
|
-
function extractSegmentFlags(allFlags) {
|
|
10887
|
-
if (!allFlags) return {};
|
|
10888
|
-
const segmentFlags = {};
|
|
10889
|
-
for (const [key, value] of Object.entries(allFlags)) {
|
|
10890
|
-
if (key.startsWith("in_segment_")) {
|
|
10891
|
-
segmentFlags[key] = value === true;
|
|
10892
|
-
}
|
|
10893
|
-
}
|
|
10894
|
-
return segmentFlags;
|
|
10895
|
-
}
|
|
10896
|
-
function collectBrowserMetadata() {
|
|
10897
|
-
var _a2;
|
|
10898
|
-
if (typeof window === "undefined") return {};
|
|
10899
|
-
const attrs = {};
|
|
10900
|
-
try {
|
|
10901
|
-
const params = new URLSearchParams(window.location.search);
|
|
10902
|
-
for (const key of ["utm_source", "utm_medium", "utm_campaign", "utm_content", "utm_term"]) {
|
|
10903
|
-
const val = params.get(key);
|
|
10904
|
-
if (val) attrs[key] = val;
|
|
10905
|
-
}
|
|
10906
|
-
} catch {
|
|
10907
|
-
}
|
|
10908
|
-
try {
|
|
10909
|
-
if (navigator.language) attrs.browser_language = navigator.language;
|
|
10910
|
-
if ((_a2 = navigator.languages) == null ? void 0 : _a2.length) attrs.browser_languages = [...navigator.languages];
|
|
10911
|
-
} catch {
|
|
10912
|
-
}
|
|
10913
|
-
try {
|
|
10914
|
-
const w = window.innerWidth;
|
|
10915
|
-
attrs.device_type = w < 768 ? "mobile" : w < 1024 ? "tablet" : "desktop";
|
|
10916
|
-
} catch {
|
|
10917
|
-
}
|
|
10918
|
-
try {
|
|
10919
|
-
if (document.referrer) {
|
|
10920
|
-
attrs.referrer = document.referrer;
|
|
10921
|
-
try {
|
|
10922
|
-
attrs.referrer_hostname = new URL(document.referrer).hostname;
|
|
10923
|
-
} catch {
|
|
10924
|
-
}
|
|
10925
|
-
}
|
|
10926
|
-
} catch {
|
|
10927
|
-
}
|
|
10928
|
-
try {
|
|
10929
|
-
attrs.page_url = window.location.href;
|
|
10930
|
-
attrs.page_path = window.location.pathname;
|
|
10931
|
-
} catch {
|
|
10932
|
-
}
|
|
10933
|
-
return attrs;
|
|
10934
|
-
}
|
|
10935
|
-
async function init(options) {
|
|
10936
|
-
var _a2, _b, _c, _d, _e, _f;
|
|
11753
|
+
// src/bootstrap-runtime.ts
|
|
11754
|
+
async function _initCore(options) {
|
|
11755
|
+
var _a2, _b, _c, _d, _e, _f, _g;
|
|
10937
11756
|
initLogger();
|
|
10938
11757
|
debug("Syntro Bootstrap", "====== INIT ======");
|
|
10939
11758
|
debug("Syntro Bootstrap", "Options:", {
|
|
@@ -10998,17 +11817,59 @@ async function init(options) {
|
|
|
10998
11817
|
const experimentHost = getEnvVar("NEXT_PUBLIC_SYNTRO_EXPERIMENT_HOST") || getEnvVar("VITE_SYNTRO_EXPERIMENT_HOST") || (payload == null ? void 0 : payload.eh);
|
|
10999
11818
|
const telemetryHost = getEnvVar("NEXT_PUBLIC_SYNTRO_TELEMETRY_HOST") || getEnvVar("VITE_SYNTRO_TELEMETRY_HOST") || (payload == null ? void 0 : payload.th);
|
|
11000
11819
|
const editorUrl = getEnvVar("NEXT_PUBLIC_SYNTRO_EDITOR_URL") || getEnvVar("VITE_SYNTRO_EDITOR_URL") || ((_b = options.canvas) == null ? void 0 : _b.editorUrl);
|
|
11820
|
+
const geoHost = (payload == null ? void 0 : payload.g) || getEnvVar("NEXT_PUBLIC_SYNTRO_GEO_HOST") || getEnvVar("VITE_SYNTRO_GEO_HOST") || GEO_DEFAULT_HOST;
|
|
11001
11821
|
const cachedSegmentAttrs = loadCachedSegmentAttributes();
|
|
11002
11822
|
const browserMetadata = collectBrowserMetadata();
|
|
11003
11823
|
const phaseOneAttrs = { ...browserMetadata, ...cachedSegmentAttrs };
|
|
11004
11824
|
debug("Syntro Bootstrap", "Phase 1: Browser metadata:", browserMetadata);
|
|
11005
11825
|
debug("Syntro Bootstrap", "Phase 1: Cached segment attributes:", cachedSegmentAttrs);
|
|
11826
|
+
const geoPromise = fetchGeo(geoHost);
|
|
11006
11827
|
let experiments;
|
|
11007
|
-
const
|
|
11828
|
+
const isDebugOrTest = options.debug || options.testMode;
|
|
11829
|
+
const events = createEventBus({
|
|
11830
|
+
debug: options.debug,
|
|
11831
|
+
history: isDebugOrTest ? new EventHistory(options.testMode ? 0 : 100) : void 0,
|
|
11832
|
+
testMode: options.testMode
|
|
11833
|
+
});
|
|
11008
11834
|
console.log("[Syntro Bootstrap] EventBus created");
|
|
11009
|
-
const
|
|
11010
|
-
|
|
11835
|
+
const processor = createEventProcessor({
|
|
11836
|
+
elementResolver: typeof window !== "undefined" ? (x, y) => {
|
|
11837
|
+
const el = document.elementFromPoint(x, y);
|
|
11838
|
+
if (!el) return null;
|
|
11839
|
+
const info = { tag_name: el.tagName.toLowerCase() };
|
|
11840
|
+
if (el.id) info.attr__id = el.id;
|
|
11841
|
+
if (el.className && typeof el.className === "string") {
|
|
11842
|
+
info.classes = el.className.split(" ").filter(Boolean);
|
|
11843
|
+
}
|
|
11844
|
+
for (const attr of el.attributes) {
|
|
11845
|
+
if (attr.name.startsWith("data-")) info[`attr__${attr.name}`] = attr.value;
|
|
11846
|
+
}
|
|
11847
|
+
return info;
|
|
11848
|
+
} : void 0
|
|
11011
11849
|
});
|
|
11850
|
+
processor.onEvent((event) => events.publishEvent(event));
|
|
11851
|
+
if (typeof window !== "undefined") {
|
|
11852
|
+
setInterval(() => processor.tick(Date.now()), 1e3);
|
|
11853
|
+
document.addEventListener(
|
|
11854
|
+
"click",
|
|
11855
|
+
(e) => {
|
|
11856
|
+
const chain = [];
|
|
11857
|
+
let el = e.target;
|
|
11858
|
+
while (el && el !== document.body) {
|
|
11859
|
+
const info = { tag_name: el.tagName.toLowerCase() };
|
|
11860
|
+
for (const attr of el.attributes) {
|
|
11861
|
+
if (attr.name.startsWith("data-") || attr.name === "id" || attr.name === "class" || attr.name === "aria-label") {
|
|
11862
|
+
info[`attr__${attr.name}`] = attr.value;
|
|
11863
|
+
}
|
|
11864
|
+
}
|
|
11865
|
+
chain.push(info);
|
|
11866
|
+
el = el.parentElement;
|
|
11867
|
+
}
|
|
11868
|
+
processor.enrichClickAttributes(Date.now(), chain);
|
|
11869
|
+
},
|
|
11870
|
+
true
|
|
11871
|
+
);
|
|
11872
|
+
}
|
|
11012
11873
|
const onFeatureFlagsLoaded = (allFlags) => {
|
|
11013
11874
|
var _a3, _b2, _c2;
|
|
11014
11875
|
debug("Syntro Bootstrap", "Phase 2: PostHog feature flags loaded");
|
|
@@ -11031,12 +11892,26 @@ async function init(options) {
|
|
|
11031
11892
|
// undefined falls back to adapter default
|
|
11032
11893
|
// Enable PostHog feature flags for segment membership
|
|
11033
11894
|
enableFeatureFlags: true,
|
|
11895
|
+
// Disable session recording in debug/dev mode (mock telemetry doesn't
|
|
11896
|
+
// support the PostHog recorder extension, causing console errors)
|
|
11897
|
+
sessionRecording: !payload.d,
|
|
11034
11898
|
// Wire up callback for when flags are loaded (Phase 2)
|
|
11035
11899
|
onFeatureFlagsLoaded,
|
|
11036
|
-
// Wire up event capture to feed into
|
|
11037
|
-
onCapture:
|
|
11900
|
+
// Wire up event capture to feed into event processor
|
|
11901
|
+
onCapture: (eventName, properties) => {
|
|
11902
|
+
processor.ingest({ kind: "posthog", event: eventName, properties, timestamp: Date.now() });
|
|
11903
|
+
},
|
|
11904
|
+
// Wire rrweb events for behavioral signal detection
|
|
11905
|
+
onRRWebEvent: (event) => {
|
|
11906
|
+
processor.ingest(event);
|
|
11907
|
+
}
|
|
11038
11908
|
});
|
|
11039
11909
|
console.log(`[Syntro Bootstrap] Telemetry client created (${provider}) with EventBus wiring`);
|
|
11910
|
+
const telemetryForCapture = telemetry;
|
|
11911
|
+
events.setPosthogCapture((name, props) => {
|
|
11912
|
+
var _a3;
|
|
11913
|
+
(_a3 = telemetryForCapture.track) == null ? void 0 : _a3.call(telemetryForCapture, name, props);
|
|
11914
|
+
});
|
|
11040
11915
|
}
|
|
11041
11916
|
let sessionMetrics;
|
|
11042
11917
|
if (payload == null ? void 0 : payload.e) {
|
|
@@ -11129,11 +12004,17 @@ async function init(options) {
|
|
|
11129
12004
|
warn("Syntro Bootstrap", "Failed to load GrowthBook features:", err);
|
|
11130
12005
|
}
|
|
11131
12006
|
}
|
|
12007
|
+
const geoData = await geoPromise;
|
|
12008
|
+
if (experiments && Object.keys(geoData).length > 0) {
|
|
12009
|
+
const mergedAttrs = { ...browserMetadata, ...geoData };
|
|
12010
|
+
debug("Syntro Bootstrap", "Merging geo data into GrowthBook attributes:", geoData);
|
|
12011
|
+
(_f = experiments.setAttributes) == null ? void 0 : _f.call(experiments, mergedAttrs);
|
|
12012
|
+
}
|
|
11132
12013
|
let baseFetcher;
|
|
11133
12014
|
if (options.fetcher) {
|
|
11134
12015
|
baseFetcher = options.fetcher;
|
|
11135
12016
|
} else if (payload == null ? void 0 : payload.f) {
|
|
11136
|
-
const configFetcher = createConfigFetcher(payload.f, (
|
|
12017
|
+
const configFetcher = createConfigFetcher(payload.f, (_g = payload.o) != null ? _g : {});
|
|
11137
12018
|
baseFetcher = async () => {
|
|
11138
12019
|
var _a3;
|
|
11139
12020
|
const result = await configFetcher.fetch();
|
|
@@ -11147,7 +12028,7 @@ async function init(options) {
|
|
|
11147
12028
|
}
|
|
11148
12029
|
const warnedAppFailures = /* @__PURE__ */ new Set();
|
|
11149
12030
|
const appLoadingFetcher = baseFetcher ? async () => {
|
|
11150
|
-
var _a3, _b2, _c2, _d2, _e2, _f2,
|
|
12031
|
+
var _a3, _b2, _c2, _d2, _e2, _f2, _g2;
|
|
11151
12032
|
const config = await baseFetcher();
|
|
11152
12033
|
console.log(
|
|
11153
12034
|
"[Syntro Bootstrap] Config fetched:",
|
|
@@ -11155,11 +12036,11 @@ async function init(options) {
|
|
|
11155
12036
|
`actions=${(_d2 = (_c2 = config.actions) == null ? void 0 : _c2.length) != null ? _d2 : 0},`,
|
|
11156
12037
|
`theme=${(_f2 = (_e2 = config.theme) == null ? void 0 : _e2.name) != null ? _f2 : "none"}`
|
|
11157
12038
|
);
|
|
11158
|
-
if (((
|
|
12039
|
+
if (((_g2 = config.actions) == null ? void 0 : _g2.length) > 0) {
|
|
11159
12040
|
console.log(
|
|
11160
12041
|
"[Syntro Bootstrap] Actions in config:",
|
|
11161
12042
|
config.actions.map(
|
|
11162
|
-
(a, i) => `[${i}] ${a.kind}${a.anchorId ? ` anchor="${
|
|
12043
|
+
(a, i) => `[${i}] ${a.kind}${a.anchorId ? ` anchor="${a.anchorId.selector}"` : ""}${a.label ? ` "${a.label}"` : ""}`
|
|
11163
12044
|
).join(", ")
|
|
11164
12045
|
);
|
|
11165
12046
|
}
|
|
@@ -11218,10 +12099,33 @@ async function init(options) {
|
|
|
11218
12099
|
});
|
|
11219
12100
|
return { canvas, runtime: runtime3, experiments, telemetry, sessionMetrics, appLoader };
|
|
11220
12101
|
}
|
|
12102
|
+
|
|
12103
|
+
// src/bootstrap.ts
|
|
12104
|
+
async function init(options) {
|
|
12105
|
+
var _a2;
|
|
12106
|
+
try {
|
|
12107
|
+
return await _initCore(options);
|
|
12108
|
+
} catch (err) {
|
|
12109
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
12110
|
+
console.warn("[Syntrologie] SDK initialization failed:", message);
|
|
12111
|
+
if (typeof document !== "undefined") {
|
|
12112
|
+
(_a2 = document.getElementById("syntrologie-anti-flicker")) == null ? void 0 : _a2.remove();
|
|
12113
|
+
}
|
|
12114
|
+
return void 0;
|
|
12115
|
+
}
|
|
12116
|
+
}
|
|
12117
|
+
function emit(eventName, props = {}) {
|
|
12118
|
+
var _a2, _b;
|
|
12119
|
+
if (typeof window === "undefined") return;
|
|
12120
|
+
const runtime3 = (_a2 = window.SynOS) == null ? void 0 : _a2.runtime;
|
|
12121
|
+
if (!((_b = runtime3 == null ? void 0 : runtime3.events) == null ? void 0 : _b.publish)) return;
|
|
12122
|
+
runtime3.events.publish({ name: eventName, source: "custom", props });
|
|
12123
|
+
}
|
|
11221
12124
|
var Syntro = {
|
|
11222
12125
|
init,
|
|
11223
12126
|
encodeToken,
|
|
11224
|
-
decodeToken
|
|
12127
|
+
decodeToken,
|
|
12128
|
+
events: { emit }
|
|
11225
12129
|
};
|
|
11226
12130
|
if (typeof window !== "undefined") {
|
|
11227
12131
|
window.Syntro = Syntro;
|
|
@@ -11252,8 +12156,11 @@ export {
|
|
|
11252
12156
|
createSmartCanvasController,
|
|
11253
12157
|
ShadowRootProvider,
|
|
11254
12158
|
useShadowRoot,
|
|
11255
|
-
StandardEvents,
|
|
11256
12159
|
EVENT_SCHEMA_VERSION,
|
|
12160
|
+
normalizePostHogEvent,
|
|
12161
|
+
shouldNormalizeEvent,
|
|
12162
|
+
createPostHogNormalizer,
|
|
12163
|
+
StandardEvents2 as StandardEvents,
|
|
11257
12164
|
CanvasEvents,
|
|
11258
12165
|
NotificationToastStack,
|
|
11259
12166
|
MAX_VISIBLE_TOASTS,
|
|
@@ -11302,11 +12209,11 @@ export {
|
|
|
11302
12209
|
evaluateSync,
|
|
11303
12210
|
createDecisionEngine,
|
|
11304
12211
|
createEventAccumulator,
|
|
12212
|
+
validateEventName,
|
|
12213
|
+
validateProps,
|
|
11305
12214
|
EventBus,
|
|
11306
12215
|
createEventBus,
|
|
11307
|
-
|
|
11308
|
-
shouldNormalizeEvent,
|
|
11309
|
-
createPostHogNormalizer,
|
|
12216
|
+
EventHistory,
|
|
11310
12217
|
NavigationMonitor,
|
|
11311
12218
|
StateStore,
|
|
11312
12219
|
createStateStore,
|
|
@@ -11330,4 +12237,4 @@ export {
|
|
|
11330
12237
|
encodeToken,
|
|
11331
12238
|
Syntro
|
|
11332
12239
|
};
|
|
11333
|
-
//# sourceMappingURL=chunk-
|
|
12240
|
+
//# sourceMappingURL=chunk-X2XEU6KD.js.map
|