flowgrid-sdk 1.6.9 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.d.ts +9 -1
- package/dist/browser.js +91 -2
- package/dist/browser.js.map +1 -1
- package/dist/flowgrid.min.js +1 -1
- package/dist/flowgrid.min.js.map +1 -1
- package/dist/lib/features/analytics/identify.js +29 -1
- package/dist/lib/features/analytics/identify.js.map +1 -1
- package/dist/lib/features/core/declarativeExperiments.d.ts +57 -0
- package/dist/lib/features/core/declarativeExperiments.js +198 -0
- package/dist/lib/features/core/declarativeExperiments.js.map +1 -0
- package/dist/lib/features/core/experiment.d.ts +71 -0
- package/dist/lib/features/core/experiment.js +164 -2
- package/dist/lib/features/core/experiment.js.map +1 -1
- package/dist/lib/flowgrid.d.ts +7 -2
- package/dist/lib/flowgrid.js +3 -3
- package/dist/lib/flowgrid.js.map +1 -1
- package/dist/lib/tracking/core/experiment.d.ts +12 -0
- package/dist/lib/tracking/core/experiment.js +14 -0
- package/dist/lib/tracking/core/experiment.js.map +1 -1
- package/dist/umd/index.js +1 -1
- package/dist/umd/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -298,11 +298,14 @@ class Identify extends transport_1.FlowGridTransport {
|
|
|
298
298
|
const visitorId = resolveVisitorId();
|
|
299
299
|
if (!this.webId || !visitorId)
|
|
300
300
|
return;
|
|
301
|
-
if (!captured.email && !captured.emailHash && !captured.firstName && !captured.lastName)
|
|
301
|
+
if (!captured.email && !captured.emailHash && !captured.firstName && !captured.lastName && !captured.phone)
|
|
302
302
|
return;
|
|
303
303
|
const traits = {
|
|
304
304
|
email: captured.email ?? null,
|
|
305
305
|
email_hash: captured.emailHash ?? null,
|
|
306
|
+
// Raw phone is only populated on an explicit form submit (consent);
|
|
307
|
+
// passive blur/input keeps phone hash-only.
|
|
308
|
+
phone: captured.phone ?? null,
|
|
306
309
|
phone_hash: captured.phoneHash ?? null,
|
|
307
310
|
first_name: captured.firstName ?? null,
|
|
308
311
|
last_name: captured.lastName ?? null,
|
|
@@ -382,6 +385,31 @@ class Identify extends transport_1.FlowGridTransport {
|
|
|
382
385
|
return;
|
|
383
386
|
doc.querySelectorAll("input, textarea, select").forEach(attach);
|
|
384
387
|
};
|
|
388
|
+
// Explicit submit is treated as consent — capture the RAW phone (the one
|
|
389
|
+
// identity field passive tracking keeps hash-only) so the CRM cascade can
|
|
390
|
+
// match by phone, then flush. All other fields are already captured passively.
|
|
391
|
+
const onSubmit = (e) => {
|
|
392
|
+
const form = e.target;
|
|
393
|
+
if (!form || form.tagName !== "FORM")
|
|
394
|
+
return;
|
|
395
|
+
if (EXCLUDED_PATH_RE.test(win.location.pathname))
|
|
396
|
+
return;
|
|
397
|
+
let phoneOnSubmit = false;
|
|
398
|
+
form.querySelectorAll("input, textarea, select").forEach((el) => {
|
|
399
|
+
const cls = classify(el);
|
|
400
|
+
if (!cls || "blocked" in cls || cls.trait !== "phone")
|
|
401
|
+
return;
|
|
402
|
+
const raw = (fieldEl(el).value || "").trim();
|
|
403
|
+
if (raw) {
|
|
404
|
+
captured.phone = raw;
|
|
405
|
+
phoneOnSubmit = true;
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
if (phoneOnSubmit)
|
|
409
|
+
sendIdentity();
|
|
410
|
+
};
|
|
411
|
+
doc.addEventListener("submit", onSubmit, true);
|
|
412
|
+
teardowns.push(() => doc.removeEventListener("submit", onSubmit, true));
|
|
385
413
|
scanPage();
|
|
386
414
|
let mo = null;
|
|
387
415
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identify.js","sourceRoot":"","sources":["../../../../src/lib/features/analytics/identify.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"identify.js","sourceRoot":"","sources":["../../../../src/lib/features/analytics/identify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Declarative, attribute-driven experiment tracking (no-code).
|
|
3
|
+
* @module features/core/declarativeExperiments
|
|
4
|
+
*
|
|
5
|
+
* @description
|
|
6
|
+
* Lets a non-technical user (WordPress / Wix / Squarespace marketer) wire
|
|
7
|
+
* experiment conversions, page-level goals, and exposures using ONLY HTML
|
|
8
|
+
* attributes — no JavaScript. It does not contain any experiment logic itself:
|
|
9
|
+
* it reads the visitor's already-assigned variant from the real engine
|
|
10
|
+
* (`Experiment` in `experiment.ts`) and calls its public tracking methods, so
|
|
11
|
+
* the deterministic assignment, anti-flicker, holdout and exposure semantics
|
|
12
|
+
* ("dynamic integrity") are untouched. This is purely the wiring layer.
|
|
13
|
+
*
|
|
14
|
+
* @attributes
|
|
15
|
+
* data-fg-goal="<experimentId>" Mark an element as a conversion trigger for
|
|
16
|
+
* that experiment. Use "*" for every experiment
|
|
17
|
+
* the visitor is currently bucketed into.
|
|
18
|
+
* data-fg-metric="signup" Metric name recorded (default "conversion").
|
|
19
|
+
* data-fg-value="49" Numeric value, e.g. order total (default 1).
|
|
20
|
+
* data-fg-on="click" Trigger: click (default) | load | submit | view.
|
|
21
|
+
* click — on element click
|
|
22
|
+
* load — once on page load (e.g. thank-you page)
|
|
23
|
+
* submit — on the element's (or nearest) form submit
|
|
24
|
+
* view — once when scrolled into view
|
|
25
|
+
* data-fg-event="<name>" Fire a generic `track(name)` event on the same
|
|
26
|
+
* trigger (page-level/interaction tracking). Can be
|
|
27
|
+
* combined with or used instead of data-fg-goal.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```html
|
|
31
|
+
* <!-- count a click on the signup button as a conversion for the hero test -->
|
|
32
|
+
* <button data-fg-goal="homepage-hero-headline" data-fg-metric="signup">Start free</button>
|
|
33
|
+
*
|
|
34
|
+
* <!-- a thank-you page: count the visit as a conversion for every active test -->
|
|
35
|
+
* <body data-fg-goal="*" data-fg-on="load" data-fg-metric="purchase">
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* Robust to dynamically-injected DOM: a MutationObserver re-scans on changes, so
|
|
39
|
+
* page builders and SPA route changes keep working with zero extra calls.
|
|
40
|
+
*/
|
|
41
|
+
/** Minimal surface of the FlowGrid instance this layer depends on. */
|
|
42
|
+
export interface DeclarativeExperimentHost {
|
|
43
|
+
experiments: {
|
|
44
|
+
trackLocalConversion(experimentId: string, metricName?: string, value?: number): Promise<void> | void;
|
|
45
|
+
getAssignments(): Record<string, string>;
|
|
46
|
+
};
|
|
47
|
+
track(eventName: string, properties?: Record<string, unknown>): unknown;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Wire every `[data-fg-goal]` / `[data-fg-event]` element under `root` that
|
|
51
|
+
* isn't already wired, according to its trigger. Idempotent per element.
|
|
52
|
+
*/
|
|
53
|
+
export declare function wireDeclarativeExperiments(host: DeclarativeExperimentHost): {
|
|
54
|
+
rescan: () => void;
|
|
55
|
+
flushLoad: () => void;
|
|
56
|
+
disconnect: () => void;
|
|
57
|
+
};
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Declarative, attribute-driven experiment tracking (no-code).
|
|
4
|
+
* @module features/core/declarativeExperiments
|
|
5
|
+
*
|
|
6
|
+
* @description
|
|
7
|
+
* Lets a non-technical user (WordPress / Wix / Squarespace marketer) wire
|
|
8
|
+
* experiment conversions, page-level goals, and exposures using ONLY HTML
|
|
9
|
+
* attributes — no JavaScript. It does not contain any experiment logic itself:
|
|
10
|
+
* it reads the visitor's already-assigned variant from the real engine
|
|
11
|
+
* (`Experiment` in `experiment.ts`) and calls its public tracking methods, so
|
|
12
|
+
* the deterministic assignment, anti-flicker, holdout and exposure semantics
|
|
13
|
+
* ("dynamic integrity") are untouched. This is purely the wiring layer.
|
|
14
|
+
*
|
|
15
|
+
* @attributes
|
|
16
|
+
* data-fg-goal="<experimentId>" Mark an element as a conversion trigger for
|
|
17
|
+
* that experiment. Use "*" for every experiment
|
|
18
|
+
* the visitor is currently bucketed into.
|
|
19
|
+
* data-fg-metric="signup" Metric name recorded (default "conversion").
|
|
20
|
+
* data-fg-value="49" Numeric value, e.g. order total (default 1).
|
|
21
|
+
* data-fg-on="click" Trigger: click (default) | load | submit | view.
|
|
22
|
+
* click — on element click
|
|
23
|
+
* load — once on page load (e.g. thank-you page)
|
|
24
|
+
* submit — on the element's (or nearest) form submit
|
|
25
|
+
* view — once when scrolled into view
|
|
26
|
+
* data-fg-event="<name>" Fire a generic `track(name)` event on the same
|
|
27
|
+
* trigger (page-level/interaction tracking). Can be
|
|
28
|
+
* combined with or used instead of data-fg-goal.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```html
|
|
32
|
+
* <!-- count a click on the signup button as a conversion for the hero test -->
|
|
33
|
+
* <button data-fg-goal="homepage-hero-headline" data-fg-metric="signup">Start free</button>
|
|
34
|
+
*
|
|
35
|
+
* <!-- a thank-you page: count the visit as a conversion for every active test -->
|
|
36
|
+
* <body data-fg-goal="*" data-fg-on="load" data-fg-metric="purchase">
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* Robust to dynamically-injected DOM: a MutationObserver re-scans on changes, so
|
|
40
|
+
* page builders and SPA route changes keep working with zero extra calls.
|
|
41
|
+
*/
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.wireDeclarativeExperiments = wireDeclarativeExperiments;
|
|
44
|
+
const WIRED_ATTR = "data-fg-wired";
|
|
45
|
+
const GOAL_ATTR = "data-fg-goal";
|
|
46
|
+
const EVENT_ATTR = "data-fg-event";
|
|
47
|
+
function parseTrigger(raw) {
|
|
48
|
+
switch ((raw || "").toLowerCase()) {
|
|
49
|
+
case "load": return "load";
|
|
50
|
+
case "submit": return "submit";
|
|
51
|
+
case "view": return "view";
|
|
52
|
+
default: return "click";
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** Resolve the experiment ids a `data-fg-goal` value targets. "*" = all active. */
|
|
56
|
+
function resolveExperimentIds(host, goal) {
|
|
57
|
+
const trimmed = goal.trim();
|
|
58
|
+
if (trimmed === "*") {
|
|
59
|
+
try {
|
|
60
|
+
return Object.keys(host.experiments.getAssignments());
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Allow a comma-separated list of ids for multi-experiment conversions.
|
|
67
|
+
return trimmed.split(",").map((s) => s.trim()).filter(Boolean);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Run the element's goal + event side effects once. `trackLocalConversion` is a
|
|
71
|
+
* safe no-op when the visitor isn't bucketed into a given experiment (control,
|
|
72
|
+
* holdout, or no running test), so firing for every resolved id is harmless.
|
|
73
|
+
*/
|
|
74
|
+
function fire(host, el) {
|
|
75
|
+
const goal = el.getAttribute(GOAL_ATTR);
|
|
76
|
+
if (goal) {
|
|
77
|
+
const metric = el.getAttribute("data-fg-metric") || "conversion";
|
|
78
|
+
const rawValue = el.getAttribute("data-fg-value");
|
|
79
|
+
const value = rawValue != null && rawValue.trim() !== "" && Number.isFinite(Number(rawValue))
|
|
80
|
+
? Number(rawValue)
|
|
81
|
+
: 1;
|
|
82
|
+
for (const id of resolveExperimentIds(host, goal)) {
|
|
83
|
+
try {
|
|
84
|
+
void host.experiments.trackLocalConversion(id, metric, value);
|
|
85
|
+
}
|
|
86
|
+
catch { /* ignore */ }
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const eventName = el.getAttribute(EVENT_ATTR);
|
|
90
|
+
if (eventName) {
|
|
91
|
+
try {
|
|
92
|
+
host.track(eventName, { source: "declarative", trigger: el.getAttribute("data-fg-on") || "click" });
|
|
93
|
+
}
|
|
94
|
+
catch { /* ignore */ }
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Wire every `[data-fg-goal]` / `[data-fg-event]` element under `root` that
|
|
99
|
+
* isn't already wired, according to its trigger. Idempotent per element.
|
|
100
|
+
*/
|
|
101
|
+
function wireDeclarativeExperiments(host) {
|
|
102
|
+
if (typeof document === "undefined") {
|
|
103
|
+
return { rescan: () => { }, flushLoad: () => { }, disconnect: () => { } };
|
|
104
|
+
}
|
|
105
|
+
// Whether the engine has had a chance to resolve assignments. `load`/`view`
|
|
106
|
+
// goals discovered before this is true are deferred so a conversion is never
|
|
107
|
+
// recorded before the visitor is bucketed.
|
|
108
|
+
let assignmentsReady = false;
|
|
109
|
+
const pendingImmediate = [];
|
|
110
|
+
let viewObserver = null;
|
|
111
|
+
const fireOrDefer = (el) => {
|
|
112
|
+
if (assignmentsReady)
|
|
113
|
+
fire(host, el);
|
|
114
|
+
else
|
|
115
|
+
pendingImmediate.push(el);
|
|
116
|
+
};
|
|
117
|
+
const wireElement = (el) => {
|
|
118
|
+
if (el.hasAttribute(WIRED_ATTR))
|
|
119
|
+
return;
|
|
120
|
+
el.setAttribute(WIRED_ATTR, "");
|
|
121
|
+
const trigger = parseTrigger(el.getAttribute("data-fg-on"));
|
|
122
|
+
switch (trigger) {
|
|
123
|
+
case "click":
|
|
124
|
+
el.addEventListener("click", () => fire(host, el));
|
|
125
|
+
break;
|
|
126
|
+
case "submit": {
|
|
127
|
+
const form = el.tagName === "FORM" ? el : el.closest("form");
|
|
128
|
+
(form || el).addEventListener("submit", () => fire(host, el));
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
case "view":
|
|
132
|
+
if (typeof IntersectionObserver !== "undefined") {
|
|
133
|
+
if (!viewObserver) {
|
|
134
|
+
viewObserver = new IntersectionObserver((entries, obs) => {
|
|
135
|
+
for (const entry of entries) {
|
|
136
|
+
if (entry.isIntersecting) {
|
|
137
|
+
obs.unobserve(entry.target);
|
|
138
|
+
fireOrDefer(entry.target);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}, { threshold: 0.5 });
|
|
142
|
+
}
|
|
143
|
+
viewObserver.observe(el);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
fireOrDefer(el); // no IO support — count it as seen
|
|
147
|
+
}
|
|
148
|
+
break;
|
|
149
|
+
case "load":
|
|
150
|
+
fireOrDefer(el);
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const scan = (root = document) => {
|
|
155
|
+
const sel = `[${GOAL_ATTR}]:not([${WIRED_ATTR}]),[${EVENT_ATTR}]:not([${WIRED_ATTR}])`;
|
|
156
|
+
root.querySelectorAll(sel).forEach(wireElement);
|
|
157
|
+
};
|
|
158
|
+
scan();
|
|
159
|
+
// Re-scan when the DOM changes (page builders, SPA navigation, lazy content).
|
|
160
|
+
const observer = typeof MutationObserver !== "undefined"
|
|
161
|
+
? new MutationObserver((mutations) => {
|
|
162
|
+
for (const m of mutations) {
|
|
163
|
+
m.addedNodes.forEach((node) => {
|
|
164
|
+
if (node.nodeType === 1)
|
|
165
|
+
scan(node);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
: null;
|
|
170
|
+
observer?.observe(document.documentElement, { childList: true, subtree: true });
|
|
171
|
+
return {
|
|
172
|
+
rescan: () => scan(),
|
|
173
|
+
/**
|
|
174
|
+
* Mark assignments as resolved and fire any `load`/`view` goals that were
|
|
175
|
+
* discovered before the engine had bucketed the visitor. Call once
|
|
176
|
+
* `initFromServer()` settles. Idempotent.
|
|
177
|
+
*/
|
|
178
|
+
flushLoad: () => {
|
|
179
|
+
if (assignmentsReady)
|
|
180
|
+
return;
|
|
181
|
+
assignmentsReady = true;
|
|
182
|
+
const queued = pendingImmediate.splice(0, pendingImmediate.length);
|
|
183
|
+
for (const el of queued)
|
|
184
|
+
fire(host, el);
|
|
185
|
+
},
|
|
186
|
+
disconnect: () => {
|
|
187
|
+
try {
|
|
188
|
+
observer?.disconnect();
|
|
189
|
+
}
|
|
190
|
+
catch { /* ignore */ }
|
|
191
|
+
try {
|
|
192
|
+
viewObserver?.disconnect();
|
|
193
|
+
}
|
|
194
|
+
catch { /* ignore */ }
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=declarativeExperiments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"declarativeExperiments.js","sourceRoot":"","sources":["../../../../src/lib/features/core/declarativeExperiments.ts"],"names":[],"mappings":"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"}
|
|
@@ -239,6 +239,36 @@ export interface VariantResponse {
|
|
|
239
239
|
variantId: string;
|
|
240
240
|
assignedAt: string;
|
|
241
241
|
}
|
|
242
|
+
/**
|
|
243
|
+
* A single declarative DOM change applied for an assigned variant — the no-code
|
|
244
|
+
* rendering primitive. The engine applies these on `init()` so a marketer can
|
|
245
|
+
* run a test (different headline, hidden banner, redirect to another page)
|
|
246
|
+
* without an engineer hand-writing `if (variant === "B")` branching.
|
|
247
|
+
*/
|
|
248
|
+
export type VariantChange = {
|
|
249
|
+
type: 'redirect';
|
|
250
|
+
url: string;
|
|
251
|
+
} | {
|
|
252
|
+
type: 'text';
|
|
253
|
+
selector: string;
|
|
254
|
+
value: string;
|
|
255
|
+
} | {
|
|
256
|
+
type: 'html';
|
|
257
|
+
selector: string;
|
|
258
|
+
value: string;
|
|
259
|
+
} | {
|
|
260
|
+
type: 'hide';
|
|
261
|
+
selector: string;
|
|
262
|
+
} | {
|
|
263
|
+
type: 'style';
|
|
264
|
+
selector: string;
|
|
265
|
+
property: string;
|
|
266
|
+
value: string;
|
|
267
|
+
} | {
|
|
268
|
+
type: 'addClass';
|
|
269
|
+
selector: string;
|
|
270
|
+
value: string;
|
|
271
|
+
};
|
|
242
272
|
/**
|
|
243
273
|
* Local experiment variant definition used by the client-side
|
|
244
274
|
* assignment engine (ported from sdk.js).
|
|
@@ -248,6 +278,15 @@ export interface ExperimentVariant {
|
|
|
248
278
|
id: string;
|
|
249
279
|
/** Traffic allocation weight */
|
|
250
280
|
weight: number;
|
|
281
|
+
/** Optional human-readable label (shown in the dashboard). */
|
|
282
|
+
label?: string;
|
|
283
|
+
/**
|
|
284
|
+
* Split-URL / redirect test shortcut — visitors assigned this variant are
|
|
285
|
+
* sent to `redirectUrl`. Equivalent to a single `{ type: 'redirect' }` change.
|
|
286
|
+
*/
|
|
287
|
+
redirectUrl?: string;
|
|
288
|
+
/** Declarative DOM changes applied when this variant is assigned. */
|
|
289
|
+
changes?: VariantChange[];
|
|
251
290
|
}
|
|
252
291
|
/**
|
|
253
292
|
* Lightweight experiment config passed to `initExperiments()`.
|
|
@@ -432,6 +471,38 @@ export declare class Experiment extends FlowGridTransport {
|
|
|
432
471
|
* @param experiments - Array of experiment configs to register
|
|
433
472
|
*/
|
|
434
473
|
initExperiments(experiments: ExperimentInitConfig[]): Promise<void>;
|
|
474
|
+
private antiFlickerStyleEl;
|
|
475
|
+
private antiFlickerTimer;
|
|
476
|
+
/** Experiments whose assigned variant has already had its changes applied + exposure fired. */
|
|
477
|
+
private appliedExperiments;
|
|
478
|
+
/** Normalises a variant's `redirectUrl` shortcut + `changes` into one list. */
|
|
479
|
+
private variantChanges;
|
|
480
|
+
/** All non-redirect selectors across the passed configs — used for anti-flicker. */
|
|
481
|
+
private collectChangeSelectors;
|
|
482
|
+
private injectAntiFlicker;
|
|
483
|
+
private removeAntiFlicker;
|
|
484
|
+
private applyDomChange;
|
|
485
|
+
/**
|
|
486
|
+
* Apply the assigned variant's declarative changes for every registered
|
|
487
|
+
* experiment, then fire one exposure per experiment. Redirects take priority
|
|
488
|
+
* and short-circuit (the new page re-runs init). DOM changes wait for the
|
|
489
|
+
* document to be ready. Idempotent per experiment.
|
|
490
|
+
*/
|
|
491
|
+
private applyAssignedChanges;
|
|
492
|
+
/**
|
|
493
|
+
* Manually (re-)apply the assigned variant's changes for one experiment —
|
|
494
|
+
* useful after client-side navigation re-renders the DOM.
|
|
495
|
+
*/
|
|
496
|
+
applyVariant(experimentId: string): void;
|
|
497
|
+
/**
|
|
498
|
+
* Zero-config init: fetch this site's running experiments from the server and
|
|
499
|
+
* run them. This is what lets the no-build snippet run experiments with no
|
|
500
|
+
* author JS — the dashboard is the only place experiments are configured.
|
|
501
|
+
*
|
|
502
|
+
* Best-effort: a network/permission failure is a silent no-op (the page just
|
|
503
|
+
* shows its control experience), never a thrown error.
|
|
504
|
+
*/
|
|
505
|
+
initFromServer(): Promise<void>;
|
|
435
506
|
/**
|
|
436
507
|
* Returns the locally assigned variant for an experiment.
|
|
437
508
|
*
|
|
@@ -184,6 +184,13 @@ class Experiment extends transport_1.FlowGridTransport {
|
|
|
184
184
|
this.experiments = {};
|
|
185
185
|
/** Local variant assignments: { [experiment_id]: variant_id } */
|
|
186
186
|
this.assignments = {};
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
// CLIENT-SIDE ENGINE — declarative variant rendering (no-code)
|
|
189
|
+
// ---------------------------------------------------------------------------
|
|
190
|
+
this.antiFlickerStyleEl = null;
|
|
191
|
+
this.antiFlickerTimer = null;
|
|
192
|
+
/** Experiments whose assigned variant has already had its changes applied + exposure fired. */
|
|
193
|
+
this.appliedExperiments = new Set();
|
|
187
194
|
}
|
|
188
195
|
// ---------------------------------------------------------------------------
|
|
189
196
|
// CLIENT-SIDE ENGINE — SSR-safe persistence (localStorage + cookie mirror)
|
|
@@ -534,8 +541,163 @@ class Experiment extends transport_1.FlowGridTransport {
|
|
|
534
541
|
*/
|
|
535
542
|
async initExperiments(experiments) {
|
|
536
543
|
this.assignments = this.loadAssignments();
|
|
537
|
-
|
|
538
|
-
|
|
544
|
+
// Anti-flicker: hide every element a variant might change *before* the
|
|
545
|
+
// (async) verify round-trip, so visitors never see the original flash to
|
|
546
|
+
// the variant. A safety timeout reveals everything even if init stalls.
|
|
547
|
+
const selectors = this.collectChangeSelectors(experiments);
|
|
548
|
+
if (selectors.length > 0)
|
|
549
|
+
this.injectAntiFlicker(selectors);
|
|
550
|
+
try {
|
|
551
|
+
if (experiments.length > 0) {
|
|
552
|
+
await this.verifyExperiments(experiments);
|
|
553
|
+
}
|
|
554
|
+
this.applyAssignedChanges();
|
|
555
|
+
}
|
|
556
|
+
finally {
|
|
557
|
+
this.removeAntiFlicker();
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
/** Normalises a variant's `redirectUrl` shortcut + `changes` into one list. */
|
|
561
|
+
variantChanges(variant) {
|
|
562
|
+
if (!variant)
|
|
563
|
+
return [];
|
|
564
|
+
const out = [];
|
|
565
|
+
if (variant.redirectUrl)
|
|
566
|
+
out.push({ type: 'redirect', url: variant.redirectUrl });
|
|
567
|
+
if (Array.isArray(variant.changes))
|
|
568
|
+
out.push(...variant.changes);
|
|
569
|
+
return out;
|
|
570
|
+
}
|
|
571
|
+
/** All non-redirect selectors across the passed configs — used for anti-flicker. */
|
|
572
|
+
collectChangeSelectors(experiments) {
|
|
573
|
+
const set = new Set();
|
|
574
|
+
for (const exp of experiments) {
|
|
575
|
+
for (const v of exp.variants) {
|
|
576
|
+
for (const c of this.variantChanges(v)) {
|
|
577
|
+
if (c.type !== 'redirect')
|
|
578
|
+
set.add(c.selector);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return Array.from(set);
|
|
583
|
+
}
|
|
584
|
+
injectAntiFlicker(selectors) {
|
|
585
|
+
if (typeof document === 'undefined' || this.antiFlickerStyleEl)
|
|
586
|
+
return;
|
|
587
|
+
try {
|
|
588
|
+
const style = document.createElement('style');
|
|
589
|
+
style.setAttribute('data-flowgrid-antiflicker', '');
|
|
590
|
+
style.textContent = `${selectors.join(',')}{visibility:hidden !important}`;
|
|
591
|
+
(document.head || document.documentElement).appendChild(style);
|
|
592
|
+
this.antiFlickerStyleEl = style;
|
|
593
|
+
// Never leave the page hidden — reveal after 4s no matter what.
|
|
594
|
+
this.antiFlickerTimer = setTimeout(() => this.removeAntiFlicker(), 4000);
|
|
595
|
+
}
|
|
596
|
+
catch { /* ignore */ }
|
|
597
|
+
}
|
|
598
|
+
removeAntiFlicker() {
|
|
599
|
+
if (this.antiFlickerTimer) {
|
|
600
|
+
clearTimeout(this.antiFlickerTimer);
|
|
601
|
+
this.antiFlickerTimer = null;
|
|
602
|
+
}
|
|
603
|
+
try {
|
|
604
|
+
this.antiFlickerStyleEl?.remove();
|
|
605
|
+
}
|
|
606
|
+
catch { /* ignore */ }
|
|
607
|
+
this.antiFlickerStyleEl = null;
|
|
608
|
+
}
|
|
609
|
+
applyDomChange(change) {
|
|
610
|
+
if (typeof document === 'undefined')
|
|
611
|
+
return;
|
|
612
|
+
const nodes = document.querySelectorAll(change.selector);
|
|
613
|
+
nodes.forEach((el) => {
|
|
614
|
+
switch (change.type) {
|
|
615
|
+
case 'text':
|
|
616
|
+
el.textContent = change.value;
|
|
617
|
+
break;
|
|
618
|
+
case 'html':
|
|
619
|
+
el.innerHTML = change.value;
|
|
620
|
+
break;
|
|
621
|
+
case 'hide':
|
|
622
|
+
el.style.display = 'none';
|
|
623
|
+
break;
|
|
624
|
+
case 'style':
|
|
625
|
+
el.style.setProperty(change.property, change.value);
|
|
626
|
+
break;
|
|
627
|
+
case 'addClass':
|
|
628
|
+
el.classList.add(...change.value.split(/\s+/).filter(Boolean));
|
|
629
|
+
break;
|
|
630
|
+
}
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Apply the assigned variant's declarative changes for every registered
|
|
635
|
+
* experiment, then fire one exposure per experiment. Redirects take priority
|
|
636
|
+
* and short-circuit (the new page re-runs init). DOM changes wait for the
|
|
637
|
+
* document to be ready. Idempotent per experiment.
|
|
638
|
+
*/
|
|
639
|
+
applyAssignedChanges() {
|
|
640
|
+
if (typeof window === 'undefined')
|
|
641
|
+
return;
|
|
642
|
+
for (const [experimentId, config] of Object.entries(this.experiments)) {
|
|
643
|
+
if (this.appliedExperiments.has(experimentId))
|
|
644
|
+
continue;
|
|
645
|
+
const variantId = this.assignments[experimentId];
|
|
646
|
+
if (!variantId)
|
|
647
|
+
continue;
|
|
648
|
+
const variant = config.variants.find((v) => v.id === variantId);
|
|
649
|
+
const changes = this.variantChanges(variant);
|
|
650
|
+
// Redirect first — if we're not already on the target, go there. The
|
|
651
|
+
// destination page's own init() handles exposure for the redirected view.
|
|
652
|
+
const redirect = changes.find((c) => c.type === 'redirect');
|
|
653
|
+
if (redirect) {
|
|
654
|
+
const target = new URL(redirect.url, window.location.href);
|
|
655
|
+
if (target.href !== window.location.href) {
|
|
656
|
+
this.appliedExperiments.add(experimentId);
|
|
657
|
+
this.trackLocalExposure(experimentId).catch(() => { });
|
|
658
|
+
window.location.replace(target.href);
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
const domChanges = changes.filter((c) => c.type !== 'redirect');
|
|
663
|
+
const run = () => domChanges.forEach((c) => this.applyDomChange(c));
|
|
664
|
+
if (typeof document !== 'undefined' && document.readyState === 'loading') {
|
|
665
|
+
document.addEventListener('DOMContentLoaded', run, { once: true });
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
run();
|
|
669
|
+
}
|
|
670
|
+
this.appliedExperiments.add(experimentId);
|
|
671
|
+
// Auto-fire exposure so no-code users get results without extra calls.
|
|
672
|
+
this.trackLocalExposure(experimentId).catch(() => { });
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Manually (re-)apply the assigned variant's changes for one experiment —
|
|
677
|
+
* useful after client-side navigation re-renders the DOM.
|
|
678
|
+
*/
|
|
679
|
+
applyVariant(experimentId) {
|
|
680
|
+
this.appliedExperiments.delete(experimentId);
|
|
681
|
+
this.applyAssignedChanges();
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Zero-config init: fetch this site's running experiments from the server and
|
|
685
|
+
* run them. This is what lets the no-build snippet run experiments with no
|
|
686
|
+
* author JS — the dashboard is the only place experiments are configured.
|
|
687
|
+
*
|
|
688
|
+
* Best-effort: a network/permission failure is a silent no-op (the page just
|
|
689
|
+
* shows its control experience), never a thrown error.
|
|
690
|
+
*/
|
|
691
|
+
async initFromServer() {
|
|
692
|
+
try {
|
|
693
|
+
const res = await fetch(`${this.endpoint}/api/v1/experiments/active?web_id=${encodeURIComponent(this.webId)}`);
|
|
694
|
+
const json = await res.json();
|
|
695
|
+
if (json?.ok && Array.isArray(json.data) && json.data.length > 0) {
|
|
696
|
+
await this.initExperiments(json.data);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
catch {
|
|
700
|
+
/* offline, blocked, or no experiments — leave the control experience */
|
|
539
701
|
}
|
|
540
702
|
}
|
|
541
703
|
/**
|