Skip to content

Commit ae94efb

Browse files
chore: sync Surface Tag from surface-forms main @ f9e07349877e7b5814ed6aab84a81476bea7994f (packages/surface-scripts)
1 parent 172bcbc commit ae94efb

2 files changed

Lines changed: 154 additions & 60 deletions

File tree

‎surface_embed_v1.js‎

Lines changed: 77 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@
467467
var VALID_PROVIDERS = ["x", "meta", "openai", "ga4", "linkedin"];
468468
var firedIds = /* @__PURE__ */ new Set();
469469
var isConversionMessage = (data) => !!data && data.type === CONVERSION_MESSAGE_TYPE && typeof data.id === "string" && VALID_PROVIDERS.includes(data.provider) && !!data.event && typeof data.response_id === "string";
470-
var handleConversionMessage = (event, log2) => {
470+
var handleConversionMessage = (event, log3) => {
471471
const data = event.data;
472472
if (!isConversionMessage(data)) return;
473473
const ack = () => {
@@ -492,7 +492,7 @@
492492
gclid: data.gclid,
493493
li_fat_id: data.li_fat_id
494494
});
495-
log2.info({
495+
log3.info({
496496
message: "Conversion handled",
497497
response: { provider: data.provider, responseId: data.response_id, fired }
498498
});
@@ -578,21 +578,21 @@
578578
}
579579
};
580580
}
581-
function initializeUserJourneyTracking(environmentId3, log2, getJourneyId, setJourneyId, config = getSurfaceRuntimeConfig()) {
581+
function initializeUserJourneyTracking(environmentId3, log3, getJourneyId, setJourneyId, config = getSurfaceRuntimeConfig()) {
582582
try {
583583
if (typeof window === "undefined") return;
584584
const existingId = getExistingJourneyId();
585585
setJourneyId(existingId);
586-
log2.info({ message: "Existing journey ID", response: { id: existingId || "none" } });
586+
log3.info({ message: "Existing journey ID", response: { id: existingId || "none" } });
587587
const currentUrl2 = window.location.href;
588588
const recentVisit = getCookie(SURFACE_USER_JOURNEY_RECENT_VISIT_COOKIE_NAME);
589589
if (recentVisit === currentUrl2) {
590-
log2.info({ message: "Skipping duplicate page view (same as recent visit)" });
590+
log3.info({ message: "Skipping duplicate page view (same as recent visit)" });
591591
return;
592592
}
593593
trackToRedis(
594594
createPageViewEvent(currentUrl2, environmentId3),
595-
log2,
595+
log3,
596596
getJourneyId,
597597
setJourneyId,
598598
config
@@ -602,62 +602,62 @@
602602
sameSite: "lax",
603603
domain: getJourneyCookieDomain()
604604
});
605-
log2.info({ message: "User journey tracking initialized" });
605+
log3.info({ message: "User journey tracking initialized" });
606606
} catch (error) {
607-
log2.error({ message: "Error initializing user journey tracking", error });
607+
log3.error({ message: "Error initializing user journey tracking", error });
608608
}
609609
}
610-
async function trackToRedis(event, log2, getJourneyId, setJourneyId, config = getSurfaceRuntimeConfig()) {
610+
async function trackToRedis(event, log3, getJourneyId, setJourneyId, config = getSurfaceRuntimeConfig()) {
611611
try {
612612
const journeyId = getJourneyId();
613613
const payload = { ...event };
614614
if (journeyId) payload.id = journeyId;
615-
log2.info({ message: "Tracking to Redis", response: payload });
615+
log3.info({ message: "Tracking to Redis", response: payload });
616616
if (journeyId && typeof navigator !== "undefined" && navigator.sendBeacon) {
617617
const blob = new Blob([JSON.stringify(payload)], {
618618
type: "application/json"
619619
});
620620
const sent = navigator.sendBeacon(config.userJourneyTrackingApi, blob);
621621
if (sent) {
622622
refreshJourneyCookie(journeyId);
623-
log2.info({ message: "Tracking sent via sendBeacon", response: { sent } });
623+
log3.info({ message: "Tracking sent via sendBeacon", response: { sent } });
624624
return { success: true };
625625
}
626-
log2.warn({ message: "sendBeacon failed, falling back to fetch" });
626+
log3.warn({ message: "sendBeacon failed, falling back to fetch" });
627627
}
628628
const response = await fetch(config.userJourneyTrackingApi, {
629629
method: "POST",
630630
headers: { "Content-Type": "application/json" },
631631
body: JSON.stringify(payload)
632632
});
633633
if (!response.ok) {
634-
log2.warn({ message: "Tracking API returned status", response: { status: response.status } });
634+
log3.warn({ message: "Tracking API returned status", response: { status: response.status } });
635635
return null;
636636
}
637637
const data = await response.json();
638638
if (data?.data?.id) {
639639
setJourneyId(data.data.id);
640-
log2.info({ message: "Journey ID stored", response: { id: data.data.id } });
640+
log3.info({ message: "Journey ID stored", response: { id: data.data.id } });
641641
}
642642
refreshJourneyCookie(getJourneyId());
643643
return data;
644644
} catch (error) {
645-
log2.error({ message: "Error tracking to Redis", error });
645+
log3.error({ message: "Error tracking to Redis", error });
646646
return null;
647647
}
648648
}
649-
function updateUserJourneyOnRouteChange(environmentId3, newUrl, log2, getJourneyId, setJourneyId, config = getSurfaceRuntimeConfig()) {
649+
function updateUserJourneyOnRouteChange(environmentId3, newUrl, log3, getJourneyId, setJourneyId, config = getSurfaceRuntimeConfig()) {
650650
try {
651651
if (typeof window === "undefined") return;
652652
const currentUrl2 = newUrl || window.location.href;
653653
const recentVisit = getCookie(SURFACE_USER_JOURNEY_RECENT_VISIT_COOKIE_NAME);
654654
if (recentVisit === currentUrl2) {
655-
log2.info({ message: "Skipping duplicate page view on route change" });
655+
log3.info({ message: "Skipping duplicate page view on route change" });
656656
return;
657657
}
658658
trackToRedis(
659659
createPageViewEvent(currentUrl2, environmentId3),
660-
log2,
660+
log3,
661661
getJourneyId,
662662
setJourneyId,
663663
config
@@ -667,17 +667,17 @@
667667
sameSite: "lax",
668668
domain: getJourneyCookieDomain()
669669
});
670-
log2.info({ message: "User journey updated on route change", response: { url: currentUrl2 } });
670+
log3.info({ message: "User journey updated on route change", response: { url: currentUrl2 } });
671671
} catch (error) {
672-
log2.error({ message: "Error updating user journey on route change", error });
672+
log3.error({ message: "Error updating user journey on route change", error });
673673
}
674674
}
675-
function clearUserJourney(log2, setJourneyId) {
675+
function clearUserJourney(log3, setJourneyId) {
676676
const domain = getJourneyCookieDomain();
677677
deleteCookie(SURFACE_USER_JOURNEY_COOKIE_NAME, { domain });
678678
deleteCookie(SURFACE_USER_JOURNEY_RECENT_VISIT_COOKIE_NAME, { domain });
679679
setJourneyId(null);
680-
log2.info({ message: "User journey cleared" });
680+
log3.info({ message: "User journey cleared" });
681681
}
682682

683683
// src/store/store.ts
@@ -1052,25 +1052,25 @@
10521052
{ name: "md", min: 768 },
10531053
{ name: "sm", min: 0 }
10541054
];
1055-
function resolveEmbedType(input, log2) {
1055+
function resolveEmbedType(input, log3) {
10561056
if (typeof input === "string") return input;
1057-
if (typeof input === "object") return resolveResponsiveType(input, log2);
1058-
log2.error({ message: "Invalid embed type: must be string or object" });
1057+
if (typeof input === "object") return resolveResponsiveType(input, log3);
1058+
log3.error({ message: "Invalid embed type: must be string or object" });
10591059
return null;
10601060
}
1061-
function resolveResponsiveType(config, log2) {
1061+
function resolveResponsiveType(config, log3) {
10621062
const withDefault = ensureDefault(config);
10631063
const breakpoint = getCurrentBreakpoint();
10641064
if (!breakpoint) {
1065-
log2.info({ message: "No matching breakpoint, using default embed type" });
1065+
log3.info({ message: "No matching breakpoint, using default embed type" });
10661066
return withDefault.default;
10671067
}
10681068
const embedType = withDefault[breakpoint];
10691069
if (embedType) {
1070-
log2.info({ message: "Using breakpoint embed type", response: { breakpoint, embedType } });
1070+
log3.info({ message: "Using breakpoint embed type", response: { breakpoint, embedType } });
10711071
return embedType;
10721072
}
1073-
log2.warn({ message: "No embed type for breakpoint, using default", response: { breakpoint } });
1073+
log3.warn({ message: "No embed type for breakpoint, using default", response: { breakpoint } });
10741074
return withDefault.default;
10751075
}
10761076
function ensureDefault(config) {
@@ -1947,7 +1947,7 @@
19471947
this.src = new URL(src);
19481948
this.log = createLogger("Surface Embed");
19491949
this.store = window.SurfaceTagStore;
1950-
this.currentQuestionId = document.currentScript?.getAttribute("data-question-id") || null;
1950+
this.currentQuestionId = options.questionId || document.currentScript?.getAttribute("data-question-id") || null;
19511951
_SurfaceEmbed._instances.push(this);
19521952
if (this._isFormPreviewMode()) {
19531953
this.log.info({ message: "Form is in preview mode" });
@@ -2494,6 +2494,52 @@
24942494
window.addEventListener("message", onMessage);
24952495
}
24962496

2497+
// src/stub-queue.ts
2498+
var RELAYED_METHODS = [
2499+
"showSurfaceForm",
2500+
"hideSurfaceForm",
2501+
"initializeEmbed"
2502+
];
2503+
var log2 = createLogger("Surface Stub Queue");
2504+
function drainStubQueue() {
2505+
const w3 = window;
2506+
if (!Array.isArray(w3.SurfaceTagQueue)) return;
2507+
const entries = w3.SurfaceTagQueue;
2508+
w3.SurfaceTagQueue = { push: processEntry };
2509+
entries.forEach(processEntry);
2510+
}
2511+
function processEntry(entry) {
2512+
try {
2513+
if (entry?.type === "consent") {
2514+
setSurfaceConsent(entry.args?.[0] ?? {});
2515+
return;
2516+
}
2517+
if (entry?.type !== "embed") return;
2518+
const [src, embedType, targetClass, options] = Array.from(entry.args ?? []);
2519+
const embed = new SurfaceEmbed(
2520+
src,
2521+
embedType,
2522+
targetClass,
2523+
{
2524+
// The captured script attribute only fills in when the caller didn't
2525+
// pass questionId explicitly — same precedence as direct construction.
2526+
...entry.questionId ? { questionId: entry.questionId } : {},
2527+
...options ?? {}
2528+
}
2529+
);
2530+
for (const method of entry.calls ?? []) {
2531+
if (RELAYED_METHODS.includes(method)) embed[method]();
2532+
}
2533+
if (entry.stub && typeof entry.stub === "object") {
2534+
for (const method of RELAYED_METHODS) {
2535+
entry.stub[method] = () => embed[method]();
2536+
}
2537+
}
2538+
} catch (error) {
2539+
log2.error({ message: "Failed to replay queued call", error });
2540+
}
2541+
}
2542+
24972543
// src/index.ts
24982544
var scriptTag = document.currentScript;
24992545
var runtimeConfig2 = initializeSurfaceRuntimeConfig(scriptTag);
@@ -2515,4 +2561,5 @@
25152561
});
25162562
void resolveOpenTriggersOnLoad(environmentId2, runtimeConfig2);
25172563
initReview();
2564+
drainStubQueue();
25182565
})();

0 commit comments

Comments
 (0)