@funnelsgrove/runtime 0.1.17 → 0.1.18
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.
|
@@ -271,9 +271,6 @@ export function usePreviewBridge({ activeStepId, onGoToStep, resolveRenderableSt
|
|
|
271
271
|
emitPreviewReady(activeStepId);
|
|
272
272
|
}, [activeStepId]);
|
|
273
273
|
useEffect(() => {
|
|
274
|
-
if (shouldLockToInitialStep) {
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
274
|
const handlePreviewMessage = (event) => {
|
|
278
275
|
const action = parsePreviewBridgeMessage(event.data);
|
|
279
276
|
if (!action) {
|
|
@@ -298,6 +295,9 @@ export function usePreviewBridge({ activeStepId, onGoToStep, resolveRenderableSt
|
|
|
298
295
|
setRuntimeMode(action.mode);
|
|
299
296
|
return;
|
|
300
297
|
}
|
|
298
|
+
if (shouldLockToInitialStep) {
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
301
|
const targetStepId = resolveRenderableStepId(action.stepId);
|
|
302
302
|
if (!targetStepId) {
|
|
303
303
|
logger.warn({
|
|
@@ -340,7 +340,7 @@ export function useFunnelFlowController({ initialStepId, lockToInitialStep = fal
|
|
|
340
340
|
endedAt: record.completedAt,
|
|
341
341
|
selected: record.choices,
|
|
342
342
|
});
|
|
343
|
-
capturePostHogStepEvent('step_completed', Object.assign({ distinct_id: currentUserIdRef.current, funnel_id: FUNNEL_ID || undefined, funnel_version_id: FUNNEL_VERSION_ID || undefined, project_id: PROJECT_ID || undefined, step_id: record.stepId, step_name: record.stepName, started_at: startedAt, ended_at: record.completedAt, duration_ms: Number.isFinite(durationMs) ? durationMs : undefined, selected: record.choices }, buildFeatureFlagProperties(postHogFeatureFlagsRef.current)));
|
|
343
|
+
capturePostHogStepEvent('step_completed', Object.assign({ distinct_id: currentUserIdRef.current, funnel_id: FUNNEL_ID || undefined, funnel_version_id: FUNNEL_VERSION_ID || undefined, project_id: PROJECT_ID || undefined, environment: runtimeMode, step_id: record.stepId, step_name: record.stepName, started_at: startedAt, ended_at: record.completedAt, duration_ms: Number.isFinite(durationMs) ? durationMs : undefined, selected: record.choices }, buildFeatureFlagProperties(postHogFeatureFlagsRef.current)));
|
|
344
344
|
}
|
|
345
345
|
setUser((prev) => {
|
|
346
346
|
var _a, _b;
|
|
@@ -390,7 +390,7 @@ export function useFunnelFlowController({ initialStepId, lockToInitialStep = fal
|
|
|
390
390
|
stepName,
|
|
391
391
|
startedAt,
|
|
392
392
|
});
|
|
393
|
-
capturePostHogStepEvent('step_started', Object.assign({ distinct_id: currentUserIdRef.current, funnel_id: FUNNEL_ID || undefined, funnel_version_id: FUNNEL_VERSION_ID || undefined, project_id: PROJECT_ID || undefined, step_id: renderedStepId, step_name: stepName, started_at: startedAt }, buildFeatureFlagProperties(postHogFeatureFlagsRef.current)));
|
|
393
|
+
capturePostHogStepEvent('step_started', Object.assign({ distinct_id: currentUserIdRef.current, funnel_id: FUNNEL_ID || undefined, funnel_version_id: FUNNEL_VERSION_ID || undefined, project_id: PROJECT_ID || undefined, environment: runtimeMode, step_id: renderedStepId, step_name: stepName, started_at: startedAt }, buildFeatureFlagProperties(postHogFeatureFlagsRef.current)));
|
|
394
394
|
}
|
|
395
395
|
attributesAtStepStart.current = Object.assign({}, attributesRef.current);
|
|
396
396
|
prevStepIdRef.current = renderedStepId;
|
|
@@ -420,7 +420,7 @@ export function useFunnelFlowController({ initialStepId, lockToInitialStep = fal
|
|
|
420
420
|
engagementThresholdMs: FIRST_STEP_ENGAGEMENT_THRESHOLD_MS,
|
|
421
421
|
},
|
|
422
422
|
});
|
|
423
|
-
capturePostHogStepEvent('step_engaged', Object.assign({ distinct_id: currentUserIdRef.current, funnel_id: FUNNEL_ID || undefined, funnel_version_id: FUNNEL_VERSION_ID || undefined, project_id: PROJECT_ID || undefined, step_id: engagedStepId, step_name: engagedStepName, started_at: engagedStartedAt, ended_at: engagedAt, duration_ms: FIRST_STEP_ENGAGEMENT_THRESHOLD_MS, engagement_threshold_ms: FIRST_STEP_ENGAGEMENT_THRESHOLD_MS }, buildFeatureFlagProperties(postHogFeatureFlagsRef.current)));
|
|
423
|
+
capturePostHogStepEvent('step_engaged', Object.assign({ distinct_id: currentUserIdRef.current, funnel_id: FUNNEL_ID || undefined, funnel_version_id: FUNNEL_VERSION_ID || undefined, project_id: PROJECT_ID || undefined, environment: runtimeMode, step_id: engagedStepId, step_name: engagedStepName, started_at: engagedStartedAt, ended_at: engagedAt, duration_ms: FIRST_STEP_ENGAGEMENT_THRESHOLD_MS, engagement_threshold_ms: FIRST_STEP_ENGAGEMENT_THRESHOLD_MS }, buildFeatureFlagProperties(postHogFeatureFlagsRef.current)));
|
|
424
424
|
}, FIRST_STEP_ENGAGEMENT_THRESHOLD_MS);
|
|
425
425
|
return () => window.clearTimeout(timer);
|
|
426
426
|
}, [
|
|
@@ -51,6 +51,13 @@ export type ManageSubscriptionsResponse = {
|
|
|
51
51
|
billingInterval?: string | null;
|
|
52
52
|
billingIntervalCount?: number | null;
|
|
53
53
|
discountCouponIds?: string[];
|
|
54
|
+
retentionDiscount?: {
|
|
55
|
+
couponId: string;
|
|
56
|
+
discountPercent: number;
|
|
57
|
+
amountCents: number;
|
|
58
|
+
discountedAmountCents: number;
|
|
59
|
+
originalAmountCents: number;
|
|
60
|
+
};
|
|
54
61
|
environment: 'test' | 'live';
|
|
55
62
|
}>;
|
|
56
63
|
eventsCount: number;
|
|
@@ -2,9 +2,58 @@ import { buildMainApiUrl, buildSdkHeaders, FUNNEL_ID, FUNNEL_VERSION_ID, getFunn
|
|
|
2
2
|
import { mergeFunnelUserAttribution, } from '../runtime/funnel-attribution.js';
|
|
3
3
|
import { applyUrlUserAttributesToUser, hasUrlUserProfileAttributes, resolveUrlUserAttributes, } from '../runtime/url-user-attributes.js';
|
|
4
4
|
const DEFAULT_USER_ID_STORAGE_KEY = 'funnel:user-id';
|
|
5
|
+
const DEFAULT_FUNNEL_DOMAIN_SIGNAL = 'funnelsgrove';
|
|
5
6
|
const canUseDom = () => {
|
|
6
7
|
return typeof window !== 'undefined';
|
|
7
8
|
};
|
|
9
|
+
const normalizeRuntimeEnvironment = (value) => {
|
|
10
|
+
if (typeof value !== 'string') {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const normalized = value.trim().toLowerCase();
|
|
14
|
+
if (normalized === 'test') {
|
|
15
|
+
return 'test';
|
|
16
|
+
}
|
|
17
|
+
if (normalized === 'live' || normalized === 'prod' || normalized === 'production') {
|
|
18
|
+
return 'live';
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
};
|
|
22
|
+
const readCookieValue = (name) => {
|
|
23
|
+
var _a, _b;
|
|
24
|
+
if (!canUseDom() || typeof document === 'undefined') {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return (((_b = (_a = document.cookie) === null || _a === void 0 ? void 0 : _a.split(';').map((part) => part.trim()).find((part) => part.startsWith(`${name}=`))) === null || _b === void 0 ? void 0 : _b.slice(name.length + 1)) || null);
|
|
28
|
+
};
|
|
29
|
+
const resolveRuntimeAnalyticsEnvironment = () => {
|
|
30
|
+
var _a, _b, _c, _d;
|
|
31
|
+
if (!canUseDom()) {
|
|
32
|
+
return 'live';
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const queryMode = normalizeRuntimeEnvironment(new URLSearchParams(((_a = window.location) === null || _a === void 0 ? void 0 : _a.search) || '').get('mode'));
|
|
36
|
+
if (queryMode) {
|
|
37
|
+
return queryMode;
|
|
38
|
+
}
|
|
39
|
+
const cookieMode = normalizeRuntimeEnvironment(readCookieValue('funnel-mode'));
|
|
40
|
+
if (cookieMode) {
|
|
41
|
+
return cookieMode;
|
|
42
|
+
}
|
|
43
|
+
const hostname = ((_c = (_b = window.location) === null || _b === void 0 ? void 0 : _b.hostname) === null || _c === void 0 ? void 0 : _c.trim().toLowerCase()) || '';
|
|
44
|
+
if (hostname.includes(DEFAULT_FUNNEL_DOMAIN_SIGNAL)) {
|
|
45
|
+
return 'test';
|
|
46
|
+
}
|
|
47
|
+
const storageMode = normalizeRuntimeEnvironment((_d = window.localStorage) === null || _d === void 0 ? void 0 : _d.getItem('funnel-mode'));
|
|
48
|
+
if (storageMode) {
|
|
49
|
+
return storageMode;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (_e) {
|
|
53
|
+
return 'live';
|
|
54
|
+
}
|
|
55
|
+
return 'live';
|
|
56
|
+
};
|
|
8
57
|
const isRecord = (value) => {
|
|
9
58
|
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
10
59
|
};
|
|
@@ -80,7 +129,7 @@ const buildSdkEvent = (event) => {
|
|
|
80
129
|
startedAt: event.startedAt || null,
|
|
81
130
|
endedAt: event.endedAt || null,
|
|
82
131
|
selected: event.selected || {},
|
|
83
|
-
metadata: event.metadata || {},
|
|
132
|
+
metadata: Object.assign({ environment: resolveRuntimeAnalyticsEnvironment() }, (event.metadata || {})),
|
|
84
133
|
};
|
|
85
134
|
};
|
|
86
135
|
const withMergedAttributionDocument = (document, attribution) => {
|
|
@@ -236,6 +285,7 @@ class ApiService {
|
|
|
236
285
|
fullName: inputName,
|
|
237
286
|
metadata: {
|
|
238
287
|
source: 'funnel-session',
|
|
288
|
+
environment: resolveRuntimeAnalyticsEnvironment(),
|
|
239
289
|
},
|
|
240
290
|
attribution: input === null || input === void 0 ? void 0 : input.attribution,
|
|
241
291
|
}),
|
|
@@ -285,6 +335,7 @@ class ApiService {
|
|
|
285
335
|
},
|
|
286
336
|
metadata: {
|
|
287
337
|
source: 'funnel',
|
|
338
|
+
environment: resolveRuntimeAnalyticsEnvironment(),
|
|
288
339
|
},
|
|
289
340
|
attribution: options === null || options === void 0 ? void 0 : options.attribution,
|
|
290
341
|
}),
|