@appfunnel-dev/sdk 0.6.0 → 0.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/{chunk-BUF5FDKC.cjs → chunk-EVUYCLVY.cjs} +42 -19
- package/dist/chunk-EVUYCLVY.cjs.map +1 -0
- package/dist/{chunk-E6KSJ5UI.js → chunk-H3KHXZSI.js} +42 -20
- package/dist/chunk-H3KHXZSI.js.map +1 -0
- package/dist/chunk-P4SLDMWY.js +104 -0
- package/dist/chunk-P4SLDMWY.js.map +1 -0
- package/dist/chunk-XP44I2MU.cjs +108 -0
- package/dist/chunk-XP44I2MU.cjs.map +1 -0
- package/dist/elements/index.cjs +12172 -0
- package/dist/elements/index.cjs.map +1 -0
- package/dist/elements/index.d.cts +602 -0
- package/dist/elements/index.d.ts +602 -0
- package/dist/elements/index.js +12137 -0
- package/dist/elements/index.js.map +1 -0
- package/dist/index.cjs +233 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +70 -3
- package/dist/index.d.ts +70 -3
- package/dist/index.js +199 -91
- package/dist/index.js.map +1 -1
- package/dist/{internal-BlgQ9C2d.d.cts → internal-C7seLJBr.d.cts} +1 -0
- package/dist/{internal-BlgQ9C2d.d.ts → internal-C7seLJBr.d.ts} +1 -0
- package/dist/internal.cjs +2 -2
- package/dist/internal.d.cts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.js +1 -1
- package/package.json +17 -2
- package/dist/chunk-BUF5FDKC.cjs.map +0 -1
- package/dist/chunk-E6KSJ5UI.js.map +0 -1
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
var react = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
|
|
6
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
7
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
8
|
+
}) : x)(function(x) {
|
|
9
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
10
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
11
|
+
});
|
|
12
|
+
|
|
6
13
|
// src/runtime/integrations.ts
|
|
7
14
|
var AppFunnelEventBus = class {
|
|
8
15
|
constructor(store, router, selectProduct) {
|
|
@@ -822,11 +829,13 @@ var FunnelTracker = class {
|
|
|
822
829
|
if (!this.currentPageId || !this.pageStartTime) return;
|
|
823
830
|
const durationMs = Date.now() - this.pageStartTime;
|
|
824
831
|
const activeMs = this.calculateActiveTime();
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
832
|
+
if (durationMs >= 50) {
|
|
833
|
+
this.track(
|
|
834
|
+
"page.exit",
|
|
835
|
+
{ pageId: this.currentPageId, durationMs, activeMs },
|
|
836
|
+
this.variablePersistence.getSavable() || void 0
|
|
837
|
+
);
|
|
838
|
+
}
|
|
830
839
|
this.cleanupPageTracking();
|
|
831
840
|
}
|
|
832
841
|
calculateActiveTime() {
|
|
@@ -861,7 +870,7 @@ var FunnelTracker = class {
|
|
|
861
870
|
// src/runtime/products.ts
|
|
862
871
|
function formatPrice(amount, currency) {
|
|
863
872
|
try {
|
|
864
|
-
return new Intl.NumberFormat(
|
|
873
|
+
return new Intl.NumberFormat("en-US", {
|
|
865
874
|
style: "currency",
|
|
866
875
|
currency: currency.toUpperCase()
|
|
867
876
|
}).format(amount);
|
|
@@ -895,6 +904,14 @@ function getIntervalLabel(interval, intervalCount) {
|
|
|
895
904
|
periodly: `every ${intervalCount} ${interval}s`
|
|
896
905
|
};
|
|
897
906
|
}
|
|
907
|
+
function getCurrencySymbol(currency) {
|
|
908
|
+
try {
|
|
909
|
+
const parts = new Intl.NumberFormat("en-US", { style: "currency", currency: currency.toUpperCase() }).formatToParts(0);
|
|
910
|
+
return parts.find((p) => p.type === "currency")?.value || currency.toUpperCase();
|
|
911
|
+
} catch {
|
|
912
|
+
return currency.toUpperCase();
|
|
913
|
+
}
|
|
914
|
+
}
|
|
898
915
|
function buildRuntimeProduct(product, priceData, trialPriceData) {
|
|
899
916
|
if (!priceData) {
|
|
900
917
|
const c = "USD";
|
|
@@ -916,6 +933,7 @@ function buildRuntimeProduct(product, priceData, trialPriceData) {
|
|
|
916
933
|
periodMonths: 0,
|
|
917
934
|
periodWeeks: 0,
|
|
918
935
|
currencyCode: c,
|
|
936
|
+
currencySymbol: getCurrencySymbol(c),
|
|
919
937
|
hasTrial: fallbackTrialDays > 0,
|
|
920
938
|
trialDays: fallbackTrialDays,
|
|
921
939
|
paidTrial: false,
|
|
@@ -966,6 +984,7 @@ function buildRuntimeProduct(product, priceData, trialPriceData) {
|
|
|
966
984
|
periodMonths,
|
|
967
985
|
periodWeeks,
|
|
968
986
|
currencyCode: currency,
|
|
987
|
+
currencySymbol: getCurrencySymbol(currency),
|
|
969
988
|
hasTrial,
|
|
970
989
|
trialDays,
|
|
971
990
|
paidTrial: hasTrial && trialRawPrice > 0,
|
|
@@ -1242,18 +1261,21 @@ function FunnelProvider({
|
|
|
1242
1261
|
if (sessionData?.sessionId) {
|
|
1243
1262
|
tracker.setSessionId(sessionData.sessionId);
|
|
1244
1263
|
}
|
|
1245
|
-
const
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1264
|
+
const timer = setTimeout(() => {
|
|
1265
|
+
const currentPage = router.getCurrentPage();
|
|
1266
|
+
tracker.track("funnel.start");
|
|
1267
|
+
if (currentPage) {
|
|
1268
|
+
tracker.track("page.view", {
|
|
1269
|
+
pageId: currentPage.key,
|
|
1270
|
+
pageKey: currentPage.key,
|
|
1271
|
+
pageName: currentPage.name,
|
|
1272
|
+
isInitial: true
|
|
1273
|
+
});
|
|
1274
|
+
tracker.startPageTracking(currentPage.key);
|
|
1275
|
+
}
|
|
1276
|
+
}, 50);
|
|
1256
1277
|
return () => {
|
|
1278
|
+
clearTimeout(timer);
|
|
1257
1279
|
tracker.stopPageTracking();
|
|
1258
1280
|
tracker.flushVariables();
|
|
1259
1281
|
};
|
|
@@ -1297,7 +1319,8 @@ function FunnelProvider({
|
|
|
1297
1319
|
}
|
|
1298
1320
|
|
|
1299
1321
|
exports.FunnelProvider = FunnelProvider;
|
|
1322
|
+
exports.__require = __require;
|
|
1300
1323
|
exports.registerIntegration = registerIntegration;
|
|
1301
1324
|
exports.useFunnelContext = useFunnelContext;
|
|
1302
|
-
//# sourceMappingURL=chunk-
|
|
1303
|
-
//# sourceMappingURL=chunk-
|
|
1325
|
+
//# sourceMappingURL=chunk-EVUYCLVY.cjs.map
|
|
1326
|
+
//# sourceMappingURL=chunk-EVUYCLVY.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/integrations.ts","../src/runtime/variableStore.ts","../src/runtime/conditions.ts","../src/runtime/router.ts","../src/runtime/tracker.ts","../src/runtime/products.ts","../src/runtime/systemVariables.ts","../src/runtime/i18n.ts","../src/components/FunnelProvider.tsx"],"names":["f","createContext","useContext","useRef","i18n","useMemo","useCallback","useEffect"],"mappings":"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","file":"chunk-EVUYCLVY.cjs","sourcesContent":["/**\n * Integration runtime — sets up window.appfunnel event bus and initializes\n * third-party integrations (Meta Pixel, GTM, Clarity, etc.).\n *\n * The integration loaders from the admin codebase subscribe to events via\n * window.appfunnel.on(). The FunnelTracker emits events via _emitEvent().\n * This module bridges the two by setting up the pub/sub layer.\n */\n\nimport type { VariableValue } from '../types'\nimport type { VariableStore } from './variableStore'\nimport type { Router } from './router'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Integration config map: integrationId -> config object */\nexport type IntegrationConfigs = Record<string, Record<string, unknown>>\n\ntype EventCallback = (data: unknown) => void\n\ninterface Subscription {\n callback: EventCallback\n scope: 'global' | 'page'\n}\n\n// ============================================================================\n// AppFunnel Runtime (window.appfunnel event bus)\n// ============================================================================\n\nexport class AppFunnelEventBus {\n private subscriptions = new Map<string, Subscription[]>()\n private store: VariableStore\n private router: Router\n private selectProduct: (productId: string) => void\n\n constructor(\n store: VariableStore,\n router: Router,\n selectProduct: (productId: string) => void,\n ) {\n this.store = store\n this.router = router\n this.selectProduct = selectProduct\n }\n\n /** Attach the event bus to window.appfunnel */\n attach(): void {\n if (typeof window === 'undefined') return\n\n const self = this\n\n ;(window as unknown as Record<string, unknown>).appfunnel = {\n // Event subscriptions\n on(eventType: string, callback: EventCallback): () => void {\n return self.on(eventType, callback)\n },\n off(eventType: string, callback: EventCallback): void {\n self.off(eventType, callback)\n },\n\n // Internal — called by FunnelTracker.emitToRuntime()\n _emitEvent(eventType: string, data?: unknown): void {\n self.emit(eventType, data)\n },\n\n // Getters for integration loaders that need them\n getVariable(variableId: string): VariableValue {\n return self.store.get(variableId)\n },\n getVariables(): Record<string, VariableValue> {\n return { ...self.store.getState() }\n },\n getCurrentPageId(): string | null {\n return self.router.getCurrentPage()?.key ?? null\n },\n getCustomerId(): string | null {\n return (self.store.get('user.stripeCustomerId') as string) || null\n },\n isPaymentAuthorized(): boolean {\n return !!(self.store.get('user.stripeCustomerId') as string)\n },\n\n // Methods\n setVariable(variableId: string, value: VariableValue): void {\n self.store.set(variableId, value)\n },\n selectProduct(productId: string): void {\n self.selectProduct(productId)\n },\n goToNextPage(): void {\n self.router.goToNextPage(self.store.getState())\n },\n goBack(): void {\n self.router.goBack()\n },\n openUrl(url: string): void {\n if (url) window.open(url, '_blank', 'noopener,noreferrer')\n },\n callEvent(eventName: string, data?: Record<string, unknown>): void {\n self.emit(eventName, data)\n },\n\n // Debug\n debug: false,\n setDebug(_enabled: boolean): void { /* noop in SDK */ },\n }\n }\n\n /** Emit an event to all subscribers */\n emit(eventType: string, data?: unknown): void {\n const subs = this.subscriptions.get(eventType)\n if (!subs || subs.length === 0) return\n\n for (const sub of subs) {\n try {\n sub.callback(data)\n } catch (error) {\n console.error(`[AppFunnel] Error in event handler for \"${eventType}\":`, error)\n }\n }\n }\n\n /** Clean up page-scoped subscriptions (called on page change) */\n onPageChange(): void {\n for (const [eventType, subs] of this.subscriptions.entries()) {\n this.subscriptions.set(eventType, subs.filter((s) => s.scope === 'global'))\n }\n }\n\n /** Destroy and detach from window */\n destroy(): void {\n this.subscriptions.clear()\n if (typeof window !== 'undefined') {\n delete (window as unknown as Record<string, unknown>).appfunnel\n }\n }\n\n private on(eventType: string, callback: EventCallback): () => void {\n if (!this.subscriptions.has(eventType)) {\n this.subscriptions.set(eventType, [])\n }\n const sub: Subscription = { callback, scope: 'global' }\n this.subscriptions.get(eventType)!.push(sub)\n return () => this.off(eventType, callback)\n }\n\n private off(eventType: string, callback: EventCallback): void {\n const subs = this.subscriptions.get(eventType)\n if (!subs) return\n const index = subs.findIndex((s) => s.callback === callback)\n if (index > -1) subs.splice(index, 1)\n }\n}\n\n// ============================================================================\n// Integration Loader Registry\n// ============================================================================\n\ntype IntegrationLoader = (config: Record<string, unknown>) => void\n\nconst loaders: Record<string, IntegrationLoader> = {}\n\n/**\n * Register a custom integration loader.\n * Called by the CLI build or user code to add integrations.\n */\nexport function registerIntegration(id: string, loader: IntegrationLoader): void {\n loaders[id] = loader\n}\n\n/**\n * Initialize all integrations from config.\n * Must be called after AppFunnelEventBus.attach() so window.appfunnel exists.\n */\nexport function initializeIntegrations(integrations: IntegrationConfigs): void {\n if (typeof window === 'undefined') return\n\n ;(window as unknown as Record<string, unknown>).__INTEGRATIONS__ = integrations\n\n for (const [integrationId, config] of Object.entries(integrations)) {\n const loader = loaders[integrationId]\n if (loader) {\n try {\n loader(config)\n } catch (err) {\n console.error(`[AppFunnel] Error loading integration ${integrationId}:`, err)\n }\n }\n }\n}\n","import type { VariableValue, VariableConfig } from '../types'\n\n/**\n * External variable store for funnel variables.\n * Components subscribe selectively via useSyncExternalStore, so only\n * components that depend on changed keys re-render.\n *\n * Forked from admin/lib/funnel/utils/variableStore.ts — simplified\n * to remove component variable logic and Liquid template evaluation.\n */\ninterface ScopedListener {\n listener: () => void\n /** Exact keys to watch, or null for all changes */\n keys: string[] | null\n /** Prefix to watch (e.g. 'answers.'), or null for all */\n prefix: string | null\n}\n\nexport class VariableStore {\n private state: Record<string, VariableValue>\n private listeners = new Set<ScopedListener>()\n /** Tracks which keys changed in the last mutation — used by scoped notify */\n private changedKeys: string[] = []\n\n constructor(initial: Record<string, VariableValue>) {\n this.state = { ...initial }\n }\n\n getState(): Record<string, VariableValue> {\n return this.state\n }\n\n get(key: string): VariableValue {\n return this.state[key]\n }\n\n set(key: string, value: VariableValue): void {\n if (this.state[key] === value) return\n this.state = { ...this.state, [key]: value }\n this.changedKeys = [key]\n this.notify()\n }\n\n setState(updater: (prev: Record<string, VariableValue>) => Record<string, VariableValue>): void {\n const prev = this.state\n const next = updater(prev)\n if (next === prev) return\n this.state = next\n // Compute changed keys\n this.changedKeys = []\n for (const key of Object.keys(next)) {\n if (next[key] !== prev[key]) this.changedKeys.push(key)\n }\n for (const key of Object.keys(prev)) {\n if (!(key in next) && prev[key] !== undefined) this.changedKeys.push(key)\n }\n this.notify()\n }\n\n /** Batch set multiple variables at once */\n setMany(updates: Record<string, VariableValue>): void {\n const changed: string[] = []\n const next = { ...this.state }\n for (const [key, value] of Object.entries(updates)) {\n if (next[key] !== value) {\n next[key] = value\n changed.push(key)\n }\n }\n if (changed.length === 0) return\n this.state = next\n this.changedKeys = changed\n this.notify()\n }\n\n /**\n * Subscribe to store changes.\n *\n * @param listener - callback fired when relevant keys change\n * @param scope - optional scope to limit notifications:\n * - `{ keys: ['data.x', 'user.email'] }` — only fire when these exact keys change\n * - `{ prefix: 'answers.' }` — only fire when any key starting with this prefix changes\n * - omit or `{}` — fire on every change (global listener)\n */\n subscribe(\n listener: () => void,\n scope?: { keys?: string[]; prefix?: string },\n ): () => void {\n const entry: ScopedListener = {\n listener,\n keys: scope?.keys || null,\n prefix: scope?.prefix || null,\n }\n this.listeners.add(entry)\n return () => this.listeners.delete(entry)\n }\n\n private notify(): void {\n const changed = this.changedKeys\n for (const entry of this.listeners) {\n // Global listener — no scope\n if (!entry.keys && !entry.prefix) {\n entry.listener()\n continue\n }\n // Key-scoped listener\n if (entry.keys) {\n if (changed.some((k) => entry.keys!.includes(k))) {\n entry.listener()\n }\n continue\n }\n // Prefix-scoped listener\n if (entry.prefix) {\n if (changed.some((k) => k.startsWith(entry.prefix!))) {\n entry.listener()\n }\n }\n }\n }\n}\n\n// ── Built-in variable namespaces ─────────────────────────\n\n/** User variables — always present, no config needed */\nconst BUILTIN_USER_VARIABLES: Record<string, VariableValue> = {\n 'user.email': '',\n 'user.name': '',\n 'user.stripeCustomerId': '',\n 'user.paddleCustomerId': '',\n}\n\n/** UTM query params — always present, auto-populated from URL */\nconst BUILTIN_QUERY_VARIABLES: Record<string, VariableValue> = {\n 'query.utm_source': '',\n 'query.utm_medium': '',\n 'query.utm_campaign': '',\n 'query.utm_content': '',\n 'query.utm_term': '',\n}\n\n/** Collect query params from the URL and prefix with `query.` */\nfunction collectQueryVariables(): Record<string, VariableValue> {\n if (typeof window === 'undefined') return {}\n const params = new URLSearchParams(window.location.search)\n const result: Record<string, VariableValue> = {}\n params.forEach((value, key) => {\n result[`query.${key}`] = value\n })\n return result\n}\n\nexport interface VariableStoreConfig {\n /** Response variables (answers.*) */\n responses?: Record<string, VariableConfig>\n /** Query param variables (query.*) */\n queryParams?: Record<string, VariableConfig>\n /** Data variables (data.*) */\n data?: Record<string, VariableConfig>\n}\n\n/**\n * Initialize a VariableStore from config variable definitions\n * merged with any session-restored values.\n *\n * Built-in namespaces:\n * - `user.*` — always present (email, name, stripeCustomerId, paddleCustomerId)\n * - `query.*` — auto-populated from URL search params, plus any declared in config\n * - `answers.*` — response variables from config\n * - `data.*` — data variables from config\n */\nexport function createVariableStore(\n config: VariableStoreConfig,\n sessionValues?: Record<string, VariableValue>,\n): VariableStore {\n const initial: Record<string, VariableValue> = {}\n\n // 1. Built-in variables (lowest priority)\n Object.assign(initial, BUILTIN_USER_VARIABLES)\n Object.assign(initial, BUILTIN_QUERY_VARIABLES)\n\n // 2. Query params from URL (overrides built-in defaults)\n Object.assign(initial, collectQueryVariables())\n\n // 3. Config-defined variables (prefixed by namespace)\n if (config.responses) {\n for (const [key, cfg] of Object.entries(config.responses)) {\n initial[`answers.${key}`] = cfg.default ?? getDefaultForType(cfg.type)\n }\n }\n if (config.queryParams) {\n for (const [key, cfg] of Object.entries(config.queryParams)) {\n // Only set default if not already populated from URL\n if (initial[`query.${key}`] === undefined) {\n initial[`query.${key}`] = cfg.default ?? getDefaultForType(cfg.type)\n }\n }\n }\n if (config.data) {\n for (const [key, cfg] of Object.entries(config.data)) {\n initial[`data.${key}`] = cfg.default ?? getDefaultForType(cfg.type)\n }\n }\n\n // 4. Session-restored values (highest priority — overrides defaults)\n if (sessionValues) {\n for (const [key, value] of Object.entries(sessionValues)) {\n if (value !== undefined) {\n initial[key] = value\n }\n }\n }\n\n return new VariableStore(initial)\n}\n\nfunction getDefaultForType(type: string): VariableValue {\n switch (type) {\n case 'string': return ''\n case 'number': return 0\n case 'boolean': return false\n case 'stringArray': return []\n default: return ''\n }\n}\n","import type { ConditionConfig, ConditionGroupConfig, VariableValue } from '../types'\n\ntype VariableContext = Record<string, VariableValue>\n\n/**\n * Check if a value is a ConditionGroupConfig (has operator + rules).\n */\nfunction isConditionGroup(\n condition: ConditionConfig | ConditionGroupConfig\n): condition is ConditionGroupConfig {\n return 'operator' in condition && 'rules' in condition\n}\n\n/**\n * Evaluate a condition or condition group against current variables.\n * Forked from admin/lib/funnel/utils/conditionEvaluator.ts — adapted to\n * work with the simpler SDK ConditionConfig types (no Liquid expressions).\n */\nexport function evaluateCondition(\n condition: ConditionConfig | ConditionGroupConfig,\n variables: VariableContext,\n): boolean {\n if (isConditionGroup(condition)) {\n return evaluateConditionGroup(condition, variables)\n }\n return evaluateSimpleCondition(condition, variables)\n}\n\n/**\n * Evaluate a condition group with AND/OR logic.\n */\nexport function evaluateConditionGroup(\n group: ConditionGroupConfig,\n variables: VariableContext,\n): boolean {\n const { operator, rules } = group\n\n if (!rules || rules.length === 0) return true\n\n const results = rules.map((rule) => evaluateCondition(rule, variables))\n\n if (operator === 'AND') {\n return results.every(Boolean)\n }\n return results.some(Boolean)\n}\n\n/**\n * Evaluate a simple condition against variables.\n */\nfunction evaluateSimpleCondition(\n condition: ConditionConfig,\n variables: VariableContext,\n): boolean {\n const variableValue = variables[condition.variable]\n\n // Check each condition property\n if (condition.equals !== undefined) {\n if (Array.isArray(variableValue)) {\n return variableValue.length === Number(condition.equals)\n }\n // eslint-disable-next-line eqeqeq\n return variableValue == condition.equals\n }\n\n if (condition.notEquals !== undefined) {\n if (Array.isArray(variableValue)) {\n return variableValue.length !== Number(condition.notEquals)\n }\n // eslint-disable-next-line eqeqeq\n return variableValue != condition.notEquals\n }\n\n if (condition.contains !== undefined) {\n if (typeof variableValue !== 'string') return false\n return variableValue.includes(condition.contains)\n }\n\n if (condition.greaterThan !== undefined) {\n if (Array.isArray(variableValue)) {\n return variableValue.length > condition.greaterThan\n }\n return Number(variableValue) > condition.greaterThan\n }\n\n if (condition.lessThan !== undefined) {\n if (Array.isArray(variableValue)) {\n return variableValue.length < condition.lessThan\n }\n return Number(variableValue) < condition.lessThan\n }\n\n if (condition.exists !== undefined) {\n const exists = variableValue !== undefined && variableValue !== null && variableValue !== ''\n return condition.exists ? exists : !exists\n }\n\n if (condition.isEmpty !== undefined) {\n let empty: boolean\n if (Array.isArray(variableValue)) {\n empty = variableValue.length === 0\n } else if (typeof variableValue === 'string') {\n empty = variableValue.trim() === ''\n } else {\n empty = !variableValue\n }\n return condition.isEmpty ? empty : !empty\n }\n\n if (condition.includes !== undefined) {\n if (!Array.isArray(variableValue)) return false\n return variableValue.includes(condition.includes)\n }\n\n // No condition properties set — always true (fallback route)\n return true\n}\n","import type {\n AppFunnelConfig,\n RouteConfig,\n PageState,\n Progress,\n VariableValue,\n} from '../types'\nimport { evaluateCondition } from './conditions'\n\nexport interface RouterOptions {\n config: AppFunnelConfig\n /** Override the initial page (from URL deep link or config) */\n initialPage?: string\n /** Base path for URL updates, e.g. '/f/my-campaign' */\n basePath?: string\n /** Campaign slug — used to check session cookies for deep-link gating */\n campaignSlug?: string\n}\n\n/**\n * Router — observable page state machine for funnel navigation.\n *\n * Subscribable so React components can re-render on page changes\n * via useSyncExternalStore.\n */\nexport class Router {\n private config: AppFunnelConfig\n private pageKeys: string[]\n private history: string[] = []\n private currentKey: string\n private initialKey: string\n private listeners = new Set<() => void>()\n readonly basePath: string\n\n constructor(options: RouterOptions) {\n const { config, initialPage, basePath, campaignSlug } = options\n this.config = config\n this.pageKeys = Object.keys(config.pages ?? {})\n this.basePath = basePath || ''\n\n const defaultInitial = config.initialPageKey || this.pageKeys[0] || ''\n const isDev = typeof globalThis !== 'undefined' && (globalThis as any).__APPFUNNEL_DEV__\n\n // If a deep-linked page was requested, validate access\n if (initialPage && initialPage !== defaultInitial) {\n if (isDev || !campaignSlug) {\n // Dev mode: always allow deep links\n this.initialKey = config.pages?.[initialPage] ? initialPage : defaultInitial\n } else {\n // Production: require session cookie for deep links\n const hasSession = this.hasSessionCookie(campaignSlug)\n this.initialKey = (hasSession && config.pages?.[initialPage]) ? initialPage : defaultInitial\n }\n } else {\n this.initialKey = initialPage || defaultInitial\n }\n\n this.currentKey = this.initialKey\n }\n\n // ── Session check ──────────────────────────────────\n\n private hasSessionCookie(campaignSlug?: string): boolean {\n if (!campaignSlug || typeof document === 'undefined') return false\n const name = `fs_${campaignSlug}=`\n return document.cookie.split(';').some(c => c.trim().startsWith(name))\n }\n\n // ── Subscriptions ────────────────────────────────────\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n private notify(): void {\n for (const listener of this.listeners) listener()\n }\n\n /** Snapshot key for useSyncExternalStore — changes on every navigation. */\n getSnapshot(): string {\n return this.currentKey\n }\n\n // ── Reads ────────────────────────────────────────────\n\n getCurrentPage(): PageState | null {\n if (!this.currentKey) return null\n const pageConfig = this.config.pages?.[this.currentKey]\n if (!pageConfig) return null\n return {\n key: this.currentKey,\n name: pageConfig.name,\n type: pageConfig.type,\n slug: pageConfig.slug || this.currentKey,\n index: this.pageKeys.indexOf(this.currentKey),\n }\n }\n\n /** Build the full URL path for a page key. */\n getPageUrl(pageKey: string): string {\n const pageConfig = this.config.pages?.[pageKey]\n const slug = pageConfig?.slug || pageKey\n return this.basePath ? `${this.basePath}/${slug}` : `/${slug}`\n }\n\n /** Resolve a page key from a URL slug. */\n resolveSlug(slug: string): string | null {\n const pages = this.config.pages ?? {}\n if (pages[slug]) return slug\n for (const [key, config] of Object.entries(pages)) {\n if (config.slug === slug) return key\n }\n return null\n }\n\n getPageHistory(): string[] {\n return [...this.history]\n }\n\n getProgress(): Progress {\n const total = this.calculateExpectedPathLength()\n const current = this.history.length + 1\n return {\n current,\n total,\n percentage: total > 0 ? Math.min(100, Math.round((current / total) * 100)) : 0,\n }\n }\n\n // ── Navigation ───────────────────────────────────────\n\n /**\n * Evaluate routes for the current page and navigate to the first matching target.\n * Returns the new page key, or null if no route matched.\n */\n goToNextPage(variables: Record<string, VariableValue>): string | null {\n const routes = this.config.routes?.[this.currentKey]\n if (!routes || routes.length === 0) return null\n\n for (const route of routes) {\n if (!route.when || evaluateCondition(route.when, variables)) {\n return this.navigateTo(route.to)\n }\n }\n\n return null\n }\n\n /** Navigate to a specific page by key. */\n goToPage(pageKey: string): string | null {\n if (!this.config.pages?.[pageKey]) return null\n return this.navigateTo(pageKey)\n }\n\n /** Go back to the previous page in history. */\n goBack(): string | null {\n const previousKey = this.history.pop()\n if (!previousKey) return null\n this.currentKey = previousKey\n this.notify()\n return previousKey\n }\n\n /** Set the current page directly (used for deep-link/reload restore). */\n setCurrentPage(pageKey: string): void {\n if (this.config.pages?.[pageKey] && this.currentKey !== pageKey) {\n this.currentKey = pageKey\n this.notify()\n }\n }\n\n private navigateTo(pageKey: string): string {\n this.history.push(this.currentKey)\n this.currentKey = pageKey\n this.notify()\n return pageKey\n }\n\n private calculateExpectedPathLength(): number {\n const visited = new Set<string>()\n let current: string | null = this.initialKey || null\n let length = 0\n\n while (current && !visited.has(current)) {\n visited.add(current)\n length++\n\n const routes: RouteConfig[] | undefined = this.config.routes?.[current]\n if (!routes || routes.length === 0) break\n\n const fallback: RouteConfig | undefined = routes[routes.length - 1]\n current = fallback?.to ?? null\n }\n\n return length\n }\n}\n","/**\n * Funnel Tracker — handles event tracking, session management, and attribution.\n * Forked from admin/lib/funnel/tracking.ts — simplified for headless SDK.\n */\n\n// ─── Types ──────────────────────────────────────────────\n\ninterface SessionMetadata {\n device?: string\n browser?: string\n os?: string\n screen?: string\n language?: string\n timezone?: string\n referrer?: string\n}\n\ninterface TrackEventResponse {\n success: boolean\n sessionId?: string\n customerId?: string\n error?: string\n}\n\nexport interface FunnelEventDataMap {\n 'funnel.start': Record<string, never>\n 'page.view': { pageId: string; pageKey?: string; pageName?: string; isInitial?: boolean }\n 'page.exit': { pageId: string; durationMs: number; activeMs: number }\n 'user.registered': { email: string }\n 'checkout.start': { productId?: string; priceId: string; productName?: string }\n 'checkout.payment_added': Record<string, never>\n 'purchase.complete': { amount?: number; currency?: string; email?: string }\n}\n\nexport type KnownFunnelEvent = keyof FunnelEventDataMap\n\n// ─── Utilities ──────────────────────────────────────────\n\nfunction getCookieValue(name: string): string | null {\n if (typeof document === 'undefined') return null\n const match = document.cookie.match(\n new RegExp('(?:^|; )' + name.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') + '=([^;]*)'),\n )\n return match ? decodeURIComponent(match[1]) : null\n}\n\nfunction collectAdAttribution(): Record<string, string> {\n if (typeof window === 'undefined') return {}\n\n const attribution: Record<string, string> = {}\n const params = new URLSearchParams(window.location.search)\n\n // Meta (Facebook)\n const fbp = getCookieValue('_fbp')\n if (fbp) attribution.fbp = fbp\n const fbc = getCookieValue('_fbc')\n const fbclid = params.get('fbclid')\n if (fbc) {\n attribution.fbc = fbc\n } else if (fbclid) {\n attribution.fbc = `fb.1.${Date.now()}.${fbclid}`\n }\n\n // TikTok\n const ttp = getCookieValue('_ttp')\n if (ttp) attribution.ttp = ttp\n const ttclid = params.get('ttclid')\n if (ttclid) attribution.ttclid = ttclid\n\n // Google Ads\n for (const key of ['gclid', 'wbraid', 'gbraid'] as const) {\n const val = params.get(key)\n if (val) attribution[key] = val\n }\n\n return attribution\n}\n\nfunction generateEventId(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID()\n }\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0\n const v = c === 'x' ? r : (r & 0x3) | 0x8\n return v.toString(16)\n })\n}\n\nfunction collectMetadata(): SessionMetadata {\n if (typeof window === 'undefined') return {}\n\n const screen = `${window.screen.width}x${window.screen.height}`\n const language = navigator.language\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone\n const referrer = document.referrer || undefined\n const userAgent = navigator.userAgent.toLowerCase()\n\n let device = 'desktop'\n if (/mobile|android|iphone|ipod|blackberry|windows phone/.test(userAgent)) {\n device = 'mobile'\n } else if (/tablet|ipad/.test(userAgent)) {\n device = 'tablet'\n }\n\n let browser = 'unknown'\n if (userAgent.includes('firefox')) browser = 'Firefox'\n else if (userAgent.includes('safari') && !userAgent.includes('chrome')) browser = 'Safari'\n else if (userAgent.includes('chrome')) browser = 'Chrome'\n else if (userAgent.includes('edge')) browser = 'Edge'\n\n let os = 'unknown'\n if (userAgent.includes('win')) os = 'Windows'\n else if (userAgent.includes('mac')) os = 'macOS'\n else if (userAgent.includes('linux')) os = 'Linux'\n else if (userAgent.includes('android')) os = 'Android'\n else if (/ios|iphone|ipad/.test(userAgent)) os = 'iOS'\n\n return { device, browser, os, screen, language, timezone, referrer }\n}\n\n// ─── Session Cookie ─────────────────────────────────────\n\nconst COOKIE_MAX_AGE_DAYS = 30\n\nfunction getSessionCookie(campaignSlug: string): string | null {\n if (typeof document === 'undefined') return null\n const name = `fs_${campaignSlug}=`\n const cookies = document.cookie.split(';')\n for (const cookie of cookies) {\n const trimmed = cookie.trim()\n if (trimmed.startsWith(name)) {\n return trimmed.substring(name.length)\n }\n }\n return null\n}\n\nfunction setSessionCookie(campaignSlug: string, sessionId: string): void {\n if (typeof document === 'undefined') return\n const maxAge = COOKIE_MAX_AGE_DAYS * 24 * 60 * 60\n document.cookie = `fs_${campaignSlug}=${sessionId}; path=/; max-age=${maxAge}; SameSite=Lax`\n}\n\n// ─── Variable Persistence ───────────────────────────────\n\n/** Only persist user-defined variable prefixes to the backend. */\nconst SAVABLE_PREFIXES = ['query.', 'data.', 'answers.', 'user.']\n\nfunction filterSavable(variables: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {}\n for (const key of Object.keys(variables)) {\n if (SAVABLE_PREFIXES.some((p) => key.startsWith(p))) {\n result[key] = variables[key]\n }\n }\n return result\n}\n\nclass VariablePersistence {\n private variables: Record<string, unknown> | null = null\n private debounceTimer: ReturnType<typeof setTimeout> | null = null\n private maxDelayTimer: ReturnType<typeof setTimeout> | null = null\n\n constructor(\n private readonly save: (data: Record<string, unknown>) => Promise<void>,\n private readonly DEBOUNCE_MS = 2000,\n private readonly MAX_DELAY_MS = 5000,\n ) {}\n\n update(variables: Record<string, unknown>, canSave: boolean = true): void {\n this.variables = variables\n if (canSave) this.scheduleSave()\n }\n\n /** Get the filtered savable variables (for attaching to events). */\n getSavable(): Record<string, unknown> | null {\n if (!this.variables) return null\n return filterSavable(this.variables)\n }\n\n async flush(): Promise<void> {\n this.clearTimers()\n if (this.variables) {\n await this.save(filterSavable(this.variables))\n }\n }\n\n destroy(): void {\n this.clearTimers()\n }\n\n private scheduleSave(): void {\n if (this.debounceTimer) clearTimeout(this.debounceTimer)\n this.debounceTimer = setTimeout(() => this.executeSave(), this.DEBOUNCE_MS)\n\n if (!this.maxDelayTimer) {\n this.maxDelayTimer = setTimeout(() => this.executeSave(), this.MAX_DELAY_MS)\n }\n }\n\n private executeSave(): void {\n this.clearTimers()\n if (this.variables) {\n this.save(filterSavable(this.variables)).catch((error: unknown) => {\n console.error('[AppFunnel] Variable save failed:', error)\n })\n }\n }\n\n private clearTimers(): void {\n if (this.debounceTimer) { clearTimeout(this.debounceTimer); this.debounceTimer = null }\n if (this.maxDelayTimer) { clearTimeout(this.maxDelayTimer); this.maxDelayTimer = null }\n }\n}\n\n// ─── FunnelTracker ──────────────────────────────────────\n\nconst API_BASE_URL = 'https://api.appfunnel.net'\n\nexport class FunnelTracker {\n private campaignId: string | null = null\n private funnelId: string | null = null\n private campaignSlug: string | null = null\n private sessionId: string | null = null\n private experimentId: string | null = null\n private initialized: boolean = false\n private customerId: string | null = null\n private adAttribution: Record<string, string> = {}\n\n // Page time tracking\n private currentPageId: string | null = null\n private pageStartTime: number | null = null\n private pageActiveTime: number = 0\n private lastActiveStart: number = 0\n private isPageVisible: boolean = true\n\n private variablePersistence: VariablePersistence\n\n constructor() {\n this.variablePersistence = new VariablePersistence((data) => this.updateUserData(data))\n }\n\n // ── Session management ──────────────────────────────\n\n init(\n campaignId: string,\n funnelId: string,\n campaignSlug?: string,\n experimentId?: string | null,\n ): void {\n if (typeof window === 'undefined') return\n\n this.campaignId = campaignId\n this.funnelId = funnelId\n this.campaignSlug = campaignSlug || null\n this.experimentId = experimentId || null\n this.initialized = true\n this.adAttribution = collectAdAttribution()\n\n if (campaignSlug) {\n const cookieSessionId = getSessionCookie(campaignSlug)\n if (cookieSessionId) {\n this.sessionId = cookieSessionId\n return\n }\n }\n\n const storedSessionId = localStorage.getItem(`campaign_session_${campaignId}`)\n if (storedSessionId) {\n this.sessionId = storedSessionId\n }\n }\n\n getSessionId(): string | null { return this.sessionId }\n getCustomerId(): string | null { return this.customerId }\n\n setSessionId(sessionId: string): void {\n this.persistSessionId(sessionId)\n }\n\n private persistSessionId(sessionId: string): void {\n this.sessionId = sessionId\n if (this.campaignSlug) {\n setSessionCookie(this.campaignSlug, sessionId)\n }\n if (this.campaignId) {\n localStorage.setItem(`campaign_session_${this.campaignId}`, sessionId)\n }\n }\n\n // ── Event tracking ──────────────────────────────────\n\n async track<E extends KnownFunnelEvent>(\n event: E,\n data?: FunnelEventDataMap[E],\n userData?: Record<string, unknown>,\n ): Promise<string>\n async track(event: string, data?: Record<string, unknown>, userData?: Record<string, unknown>): Promise<string>\n async track(event: string, data?: Record<string, unknown>, userData?: Record<string, unknown>): Promise<string> {\n const eventId = (data as Record<string, unknown>)?.eventId as string || generateEventId()\n\n if (!this.initialized || !this.campaignId) {\n console.warn('[AppFunnel] Tracker not initialized. Call init() first.')\n return eventId\n }\n\n if (typeof window === 'undefined') return eventId\n\n // Dev mode: log to console instead of calling API\n if ((globalThis as any).__APPFUNNEL_DEV__) {\n console.log(`[AppFunnel] track: ${event}`, data || '')\n return eventId\n }\n\n try {\n const metadata = collectMetadata()\n const response = await fetch(\n `${API_BASE_URL}/campaign/${this.campaignId}/event`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n campaignId: this.campaignId,\n funnelId: this.funnelId || undefined,\n eventId,\n sessionId: this.sessionId || undefined,\n event,\n data,\n userData: userData || undefined,\n metadata,\n adAttribution: Object.keys(this.adAttribution).length > 0 ? this.adAttribution : undefined,\n experimentId: this.experimentId || undefined,\n }),\n },\n )\n\n if (!response.ok) {\n console.error('[AppFunnel] Failed to track event:', response.statusText)\n return eventId\n }\n\n const result: TrackEventResponse = await response.json()\n\n if (result.success && result.sessionId) {\n this.persistSessionId(result.sessionId)\n if (result.customerId && result.customerId !== this.customerId) {\n this.customerId = result.customerId\n }\n }\n } catch (error) {\n console.error('[AppFunnel] Error tracking event:', error)\n }\n\n return eventId\n }\n\n /** Identify a user by email — fires user.registered event */\n async identify(email: string): Promise<void> {\n await this.track('user.registered', { email })\n }\n\n async updateUserData(userData: Record<string, unknown>): Promise<void> {\n if (!this.sessionId || typeof window === 'undefined') return\n\n try {\n const response = await fetch(\n `${API_BASE_URL}/campaign/${this.campaignId}/event/session/data`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId: this.sessionId, userData }),\n },\n )\n\n if (!response.ok) {\n console.error('[AppFunnel] Failed to update user data:', response.statusText)\n }\n } catch (error) {\n console.error('[AppFunnel] Error updating user data:', error)\n }\n }\n\n // ── Variable persistence ────────────────────────────\n\n setCurrentVariables(variables: Record<string, unknown>): void {\n this.variablePersistence.update(variables, !!this.sessionId)\n }\n\n async flushVariables(): Promise<void> {\n if (!this.sessionId) return\n await this.variablePersistence.flush()\n }\n\n // ── Page time tracking ──────────────────────────────\n\n startPageTracking(pageId: string): void {\n if (typeof window === 'undefined') return\n this.stopPageTracking()\n\n this.currentPageId = pageId\n this.pageStartTime = Date.now()\n this.pageActiveTime = 0\n this.lastActiveStart = Date.now()\n this.isPageVisible = document.visibilityState === 'visible'\n\n document.addEventListener('visibilitychange', this.handleVisibilityChange)\n window.addEventListener('beforeunload', this.handleBeforeUnload)\n }\n\n stopPageTracking(): void {\n if (!this.currentPageId || !this.pageStartTime) return\n\n const durationMs = Date.now() - this.pageStartTime\n const activeMs = this.calculateActiveTime()\n\n // Skip spurious page.exit from React Strict Mode double-mount (duration < 50ms)\n if (durationMs >= 50) {\n this.track(\n 'page.exit',\n { pageId: this.currentPageId, durationMs, activeMs },\n this.variablePersistence.getSavable() || undefined,\n )\n }\n\n this.cleanupPageTracking()\n }\n\n private calculateActiveTime(): number {\n let activeTime = this.pageActiveTime\n if (this.isPageVisible && this.lastActiveStart > 0) {\n activeTime += Date.now() - this.lastActiveStart\n }\n return activeTime\n }\n\n private handleVisibilityChange = (): void => {\n if (document.visibilityState === 'hidden') {\n if (this.isPageVisible && this.lastActiveStart > 0) {\n this.pageActiveTime += Date.now() - this.lastActiveStart\n }\n this.isPageVisible = false\n } else {\n this.isPageVisible = true\n this.lastActiveStart = Date.now()\n }\n }\n\n private handleBeforeUnload = (): void => {\n if (!this.currentPageId || !this.pageStartTime || !this.initialized || !this.campaignId) return\n\n const durationMs = Date.now() - this.pageStartTime\n const activeMs = this.calculateActiveTime()\n const eventId = generateEventId()\n\n const payload = JSON.stringify({\n campaignId: this.campaignId,\n funnelId: this.funnelId || undefined,\n eventId,\n sessionId: this.sessionId || undefined,\n experimentId: this.experimentId || undefined,\n event: 'page.exit',\n data: { pageId: this.currentPageId, durationMs, activeMs },\n userData: this.variablePersistence.getSavable() || undefined,\n metadata: collectMetadata(),\n adAttribution: Object.keys(this.adAttribution).length > 0 ? this.adAttribution : undefined,\n })\n\n navigator.sendBeacon(`${API_BASE_URL}/campaign/${this.campaignId}/event`, payload)\n }\n\n private cleanupPageTracking(): void {\n if (typeof window === 'undefined') return\n document.removeEventListener('visibilitychange', this.handleVisibilityChange)\n window.removeEventListener('beforeunload', this.handleBeforeUnload)\n this.currentPageId = null\n this.pageStartTime = null\n this.pageActiveTime = 0\n this.lastActiveStart = 0\n this.isPageVisible = true\n }\n\n // ── Lifecycle ───────────────────────────────────────\n\n reset(): void {\n this.variablePersistence.destroy()\n if (this.campaignId && typeof window !== 'undefined') {\n localStorage.removeItem(`campaign_session_${this.campaignId}`)\n }\n this.sessionId = null\n this.customerId = null\n this.cleanupPageTracking()\n }\n}\n","import type { RuntimeProduct, ProductConfig, EnrichedPriceData } from '../types'\n\n// ============================================================================\n// Price Utilities — forked from admin/lib/funnel/utils/productVariables.ts\n// ============================================================================\n\nfunction formatPrice(amount: number, currency: string): string {\n try {\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: currency.toUpperCase(),\n }).format(amount)\n } catch {\n return `${currency.toUpperCase()} ${amount.toFixed(2)}`\n }\n}\n\nfunction calculatePeriodDays(interval: string, intervalCount: number): number {\n const map: Record<string, number> = { day: 1, week: 7, month: 30, year: 365, one_time: 0 }\n return (map[interval] || 0) * intervalCount\n}\n\nfunction calculatePeriodMonths(interval: string, intervalCount: number): number {\n const map: Record<string, number> = { day: 1 / 30, week: 1 / 4, month: 1, year: 12, one_time: 0 }\n return (map[interval] || 0) * intervalCount\n}\n\nfunction calculatePeriodWeeks(interval: string, intervalCount: number): number {\n const map: Record<string, number> = { day: 1 / 7, week: 1, month: 4, year: 52, one_time: 0 }\n return (map[interval] || 0) * intervalCount\n}\n\nexport function getIntervalLabel(\n interval: string,\n intervalCount: number,\n): { period: string; periodly: string } {\n if (interval === 'one_time') return { period: 'one-time', periodly: 'one-time' }\n if (interval === 'month' && intervalCount === 3) return { period: 'quarter', periodly: 'quarterly' }\n if (interval === 'month' && intervalCount === 6) return { period: '6 months', periodly: 'semiannually' }\n if (interval === 'week' && intervalCount === 2) return { period: '2 weeks', periodly: 'biweekly' }\n if (intervalCount === 1) {\n const periodlyMap: Record<string, string> = { day: 'daily', week: 'weekly', month: 'monthly', year: 'yearly' }\n return { period: interval, periodly: periodlyMap[interval] || interval }\n }\n return {\n period: `${intervalCount} ${interval}s`,\n periodly: `every ${intervalCount} ${interval}s`,\n }\n}\n\nfunction getCurrencySymbol(currency: string): string {\n try {\n const parts = new Intl.NumberFormat('en-US', { style: 'currency', currency: currency.toUpperCase() }).formatToParts(0)\n return parts.find((p) => p.type === 'currency')?.value || currency.toUpperCase()\n } catch {\n return currency.toUpperCase()\n }\n}\n\n// ============================================================================\n// Product Runtime — builds RuntimeProduct from config + enriched API data\n// ============================================================================\n\n/**\n * Build a RuntimeProduct from config + enriched price data from the API.\n */\nexport function buildRuntimeProduct(\n product: ProductConfig,\n priceData: EnrichedPriceData | undefined,\n trialPriceData?: EnrichedPriceData | undefined,\n): RuntimeProduct {\n if (!priceData) {\n const c = 'USD'\n const f = (n: number) => formatPrice(n, c)\n const fallbackTrialDays = product.trialDays || 0\n return {\n id: product.id,\n name: product.name,\n storePriceId: product.storePriceId,\n price: f(0),\n rawPrice: 0,\n monthlyPrice: f(0),\n dailyPrice: f(0),\n weeklyPrice: f(0),\n yearlyPrice: f(0),\n period: 'one_time',\n periodly: 'one-time',\n periodDays: 0,\n periodMonths: 0,\n periodWeeks: 0,\n currencyCode: c,\n currencySymbol: getCurrencySymbol(c),\n hasTrial: fallbackTrialDays > 0,\n trialDays: fallbackTrialDays,\n paidTrial: false,\n trialRawPrice: 0,\n trialPrice: f(0),\n trialDailyPrice: f(0),\n trialCurrencyCode: c,\n trialStorePriceId: product.trialStorePriceId || '',\n stripePriceId: '',\n stripeProductId: '',\n paddlePriceId: '',\n paddleProductId: '',\n displayName: product.name,\n }\n }\n\n const rawPrice = priceData.amount / 100\n const currency = priceData.currency.toUpperCase()\n const f = (n: number) => formatPrice(n, currency)\n const interval = priceData.interval || 'one_time'\n const intervalCount = priceData.intervalCount || 1\n\n const periodDays = calculatePeriodDays(interval, intervalCount)\n const periodMonths = calculatePeriodMonths(interval, intervalCount)\n const periodWeeks = calculatePeriodWeeks(interval, intervalCount)\n\n const dailyPrice = periodDays > 0 ? rawPrice / periodDays : rawPrice\n const weeklyPrice = periodWeeks > 0 ? rawPrice / periodWeeks : rawPrice * 7\n const monthlyPrice = periodMonths > 0 ? rawPrice / periodMonths : rawPrice * 30\n const yearlyPrice = periodMonths > 0 ? (rawPrice / periodMonths) * 12 : rawPrice * 365\n\n const { period, periodly } = getIntervalLabel(interval, intervalCount)\n\n const trialDays = product.trialDays || 0\n const hasTrial = trialDays > 0\n const trialRawPrice = trialPriceData ? trialPriceData.amount / 100 : 0\n const trialCurrency = trialPriceData ? trialPriceData.currency.toUpperCase() : currency\n const ft = (n: number) => formatPrice(n, trialCurrency)\n const trialDailyPrice = trialDays > 0 ? trialRawPrice / trialDays : 0\n\n return {\n id: product.id,\n name: product.name,\n storePriceId: product.storePriceId,\n price: f(rawPrice),\n rawPrice,\n monthlyPrice: f(monthlyPrice),\n dailyPrice: f(dailyPrice),\n weeklyPrice: f(weeklyPrice),\n yearlyPrice: f(yearlyPrice),\n period,\n periodly,\n periodDays,\n periodMonths,\n periodWeeks,\n currencyCode: currency,\n currencySymbol: getCurrencySymbol(currency),\n hasTrial,\n trialDays,\n paidTrial: hasTrial && trialRawPrice > 0,\n trialRawPrice,\n trialPrice: ft(trialRawPrice),\n trialDailyPrice: ft(trialDailyPrice),\n trialCurrencyCode: trialCurrency,\n trialStorePriceId: product.trialStorePriceId || '',\n stripePriceId: priceData.stripePriceId || '',\n stripeProductId: priceData.stripeProductId || '',\n paddlePriceId: priceData.paddlePriceId || '',\n paddleProductId: priceData.paddleProductId || '',\n displayName: priceData.displayName || priceData.priceName || priceData.name || product.name,\n }\n}\n\n/**\n * Build all RuntimeProducts from config + enriched price data map.\n */\nexport function buildRuntimeProducts(\n products: ProductConfig[],\n priceDataMap: Map<string, EnrichedPriceData>,\n): RuntimeProduct[] {\n return products.map((product) => {\n const priceData = priceDataMap.get(product.storePriceId)\n const trialPriceData = product.trialStorePriceId\n ? priceDataMap.get(product.trialStorePriceId)\n : undefined\n return buildRuntimeProduct(product, priceData, trialPriceData)\n })\n}\n","import type { VariableValue } from '../types'\n\n/**\n * System variable computation — forked from admin/lib/funnel/systemVariables.ts.\n * Simplified: no component-bound variables, no ua-parser-js dependency.\n */\n\nexport interface SystemVariableContext {\n currentPageKey: string\n pageHistory: string[]\n pageStartTime: number\n sessionStartTime: number\n totalPages: number\n funnelId: string\n campaignId: string\n}\n\ninterface BrowserInfo {\n userAgent: string\n browserName: string\n browserVersion: string\n deviceType: 'mobile' | 'tablet' | 'desktop'\n isMobile: boolean\n isTablet: boolean\n os: string\n screenWidth: number\n screenHeight: number\n viewportWidth: number\n viewportHeight: number\n language: string\n timezone: string\n colorDepth: number\n pixelRatio: number\n cookieEnabled: boolean\n online: boolean\n}\n\nlet cachedBrowserInfo: BrowserInfo | null = null\n\nfunction detectBrowserInfo(): BrowserInfo {\n if (cachedBrowserInfo) return cachedBrowserInfo\n\n if (typeof window === 'undefined') {\n return {\n userAgent: 'unknown', browserName: 'Unknown', browserVersion: '0',\n deviceType: 'desktop', isMobile: false, isTablet: false, os: 'Unknown',\n screenWidth: 0, screenHeight: 0, viewportWidth: 0, viewportHeight: 0,\n language: 'en', timezone: 'UTC', colorDepth: 24, pixelRatio: 1,\n cookieEnabled: true, online: true,\n }\n }\n\n const ua = navigator.userAgent\n const uaLower = ua.toLowerCase()\n\n // Browser detection\n let browserName = 'Unknown'\n let browserVersion = '0'\n if (uaLower.includes('firefox')) { browserName = 'Firefox'; browserVersion = extractVersion(ua, /Firefox\\/(\\d+[\\d.]*)/) }\n else if (uaLower.includes('edg')) { browserName = 'Edge'; browserVersion = extractVersion(ua, /Edg\\/(\\d+[\\d.]*)/) }\n else if (uaLower.includes('chrome') && !uaLower.includes('edg')) { browserName = 'Chrome'; browserVersion = extractVersion(ua, /Chrome\\/(\\d+[\\d.]*)/) }\n else if (uaLower.includes('safari') && !uaLower.includes('chrome')) { browserName = 'Safari'; browserVersion = extractVersion(ua, /Version\\/(\\d+[\\d.]*)/) }\n\n // OS detection\n let os = 'Unknown'\n if (uaLower.includes('win')) os = 'Windows'\n else if (uaLower.includes('mac')) os = 'macOS'\n else if (uaLower.includes('linux') && !uaLower.includes('android')) os = 'Linux'\n else if (uaLower.includes('android')) os = 'Android'\n else if (/iphone|ipad|ipod/.test(uaLower)) os = 'iOS'\n\n // Device detection\n let deviceType: 'mobile' | 'tablet' | 'desktop' = 'desktop'\n if (/mobile|android(?!.*tablet)|iphone|ipod/.test(uaLower)) deviceType = 'mobile'\n else if (/tablet|ipad/.test(uaLower)) deviceType = 'tablet'\n\n cachedBrowserInfo = {\n userAgent: ua,\n browserName,\n browserVersion,\n deviceType,\n isMobile: deviceType === 'mobile',\n isTablet: deviceType === 'tablet',\n os,\n screenWidth: window.screen?.width || 0,\n screenHeight: window.screen?.height || 0,\n viewportWidth: window.innerWidth || 0,\n viewportHeight: window.innerHeight || 0,\n language: navigator.language || 'en',\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC',\n colorDepth: window.screen?.colorDepth || 24,\n pixelRatio: window.devicePixelRatio || 1,\n cookieEnabled: navigator.cookieEnabled ?? true,\n online: navigator.onLine ?? true,\n }\n\n return cachedBrowserInfo\n}\n\nfunction extractVersion(ua: string, regex: RegExp): string {\n const match = ua.match(regex)\n return match?.[1] || '0'\n}\n\n/**\n * Compute all system variables and update the store.\n */\nexport function computeSystemVariables(\n context: SystemVariableContext,\n): Record<string, VariableValue> {\n const browser = detectBrowserInfo()\n const now = Date.now()\n\n return {\n // Session\n 'session.startedAt': context.sessionStartTime,\n\n // Page\n 'page.currentId': context.currentPageKey,\n 'page.currentIndex': context.pageHistory.length,\n 'page.current': context.pageHistory.length + 1,\n 'page.total': context.totalPages,\n 'page.progressPercentage': context.totalPages > 0\n ? Math.min(100, Math.round(((context.pageHistory.length + 1) / context.totalPages) * 100))\n : 0,\n 'page.startedAt': context.pageStartTime || now,\n\n // Device\n 'device.isMobile': browser.isMobile,\n 'device.isTablet': browser.isTablet,\n 'device.type': browser.deviceType,\n 'device.screenWidth': browser.screenWidth,\n 'device.screenHeight': browser.screenHeight,\n 'device.viewportWidth': browser.viewportWidth,\n 'device.viewportHeight': browser.viewportHeight,\n 'device.colorDepth': browser.colorDepth,\n 'device.pixelRatio': browser.pixelRatio,\n\n // Browser\n 'browser.userAgent': browser.userAgent,\n 'browser.name': browser.browserName,\n 'browser.version': browser.browserVersion,\n 'browser.cookieEnabled': browser.cookieEnabled,\n 'browser.online': browser.online,\n 'browser.language': browser.language,\n\n // OS\n 'os.name': browser.os,\n 'os.timezone': browser.timezone,\n\n // Metadata\n 'metadata.webfunnelId': context.funnelId,\n 'metadata.campaignId': context.campaignId,\n }\n}\n\n","/**\n * Lightweight i18n runtime.\n *\n * Translations are flat or nested JSON objects per locale:\n * { \"en\": { \"welcome\": \"Hello, {{name}}\" }, \"de\": { \"welcome\": \"Hallo, {{name}}\" } }\n *\n * The CLI build reads `locales/*.json` and passes them to FunnelProvider.\n */\n\nexport type TranslationMap = Record<string, Record<string, string>>\n\nexport class I18n {\n private translations: TranslationMap = {}\n private locale: string\n private fallbackLocale: string\n private listeners = new Set<() => void>()\n\n constructor(defaultLocale: string = 'en') {\n this.locale = defaultLocale\n this.fallbackLocale = defaultLocale\n }\n\n /** Load all translations at once */\n load(translations: TranslationMap): void {\n this.translations = translations\n }\n\n getLocale(): string {\n return this.locale\n }\n\n setLocale(locale: string): void {\n if (this.locale === locale) return\n this.locale = locale\n this.notify()\n }\n\n getAvailableLocales(): string[] {\n return Object.keys(this.translations)\n }\n\n /**\n * Translate a key with optional interpolation.\n *\n * Supports dot notation for nested keys and `{{var}}` interpolation:\n * t('checkout.title')\n * t('welcome', { name: 'John' }) → \"Hello, John\"\n */\n t(key: string, params?: Record<string, string | number>): string {\n // Try current locale, then fallback\n let value = this.resolve(this.locale, key)\n ?? this.resolve(this.fallbackLocale, key)\n\n if (value === undefined) return key\n\n // Interpolate {{var}} placeholders\n if (params) {\n value = value.replace(/\\{\\{(\\w+)\\}\\}/g, (_, name) => {\n return params[name] !== undefined ? String(params[name]) : `{{${name}}}`\n })\n }\n\n return value\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n private resolve(locale: string, key: string): string | undefined {\n const dict = this.translations[locale]\n if (!dict) return undefined\n\n // Direct match\n if (dict[key] !== undefined) return dict[key]\n\n return undefined\n }\n\n private notify(): void {\n this.listeners.forEach((l) => l())\n }\n}\n","import { createContext, useContext, useEffect, useRef, useMemo, useCallback } from 'react'\nimport type {\n AppFunnelConfig,\n VariableValue,\n RuntimeProduct,\n EnrichedPriceData,\n} from '../types'\nimport { VariableStore, createVariableStore } from '../runtime/variableStore'\nimport { Router } from '../runtime/router'\nimport { FunnelTracker } from '../runtime/tracker'\nimport { buildRuntimeProducts } from '../runtime/products'\nimport { computeSystemVariables } from '../runtime/systemVariables'\nimport { AppFunnelEventBus, initializeIntegrations } from '../runtime/integrations'\nimport { I18n, type TranslationMap } from '../runtime/i18n'\n\n// ============================================================================\n// Context\n// ============================================================================\n\nexport interface FunnelContextValue {\n config: AppFunnelConfig\n variableStore: VariableStore\n router: Router\n tracker: FunnelTracker\n i18n: I18n\n products: RuntimeProduct[]\n selectedProductId: string | null\n selectProduct: (productId: string) => void\n funnelId: string\n campaignId: string\n sessionId: string | null\n}\n\nconst FunnelContext = createContext<FunnelContextValue | null>(null)\n\nexport function useFunnelContext(): FunnelContextValue {\n const ctx = useContext(FunnelContext)\n if (!ctx) {\n throw new Error('useFunnelContext must be used within a <FunnelProvider>')\n }\n return ctx\n}\n\n// ============================================================================\n// Provider Props\n// ============================================================================\n\nexport interface FunnelProviderProps {\n config: AppFunnelConfig\n children: React.ReactNode\n /** Pre-fetched session data (from API) */\n sessionData?: {\n sessionId?: string\n campaignId: string\n funnelId: string\n variables?: Record<string, VariableValue>\n customerId?: string\n experimentId?: string | null\n }\n /** Pre-fetched enriched price data map: storePriceId → price data */\n priceData?: Map<string, EnrichedPriceData>\n /** Campaign slug for session cookies and URL routing */\n campaignSlug?: string\n /** Base path for URL updates, e.g. '/f/my-campaign' */\n basePath?: string\n /** Override the initial page (e.g. from URL slug on reload/deep link) */\n initialPage?: string\n /** Translations map: { \"en\": { \"key\": \"value\" }, \"de\": { \"key\": \"wert\" } } */\n translations?: TranslationMap\n}\n\n// ============================================================================\n// Provider\n// ============================================================================\n\nexport function FunnelProvider({\n config,\n children,\n sessionData,\n priceData,\n campaignSlug,\n basePath,\n initialPage,\n translations,\n}: FunnelProviderProps) {\n const campaignId = sessionData?.campaignId || config.projectId || ''\n const funnelId = sessionData?.funnelId || config.projectId || ''\n\n // ── Initialize runtime objects (once) ─────────────\n const storeRef = useRef<VariableStore | null>(null)\n const routerRef = useRef<Router | null>(null)\n const trackerRef = useRef<FunnelTracker | null>(null)\n const eventBusRef = useRef<AppFunnelEventBus | null>(null)\n const i18nRef = useRef<I18n | null>(null)\n\n if (!storeRef.current) {\n storeRef.current = createVariableStore(\n { responses: config.responses, queryParams: config.queryParams, data: config.data },\n sessionData?.variables,\n )\n }\n if (!routerRef.current) {\n routerRef.current = new Router({\n config,\n initialPage,\n basePath,\n campaignSlug,\n })\n }\n if (!trackerRef.current) {\n trackerRef.current = new FunnelTracker()\n }\n if (!i18nRef.current) {\n const i18n = new I18n(config.defaultLocale || 'en')\n if (translations) i18n.load(translations)\n // Auto-detect locale from browser if available\n if (typeof navigator !== 'undefined') {\n const browserLang = navigator.language?.split('-')[0]\n if (browserLang && translations?.[browserLang]) {\n i18n.setLocale(browserLang)\n }\n }\n i18nRef.current = i18n\n }\n\n const store = storeRef.current\n const router = routerRef.current\n const tracker = trackerRef.current\n const i18n = i18nRef.current\n\n // ── Build products ────────────────────────────────\n const products = useMemo(() => {\n if (!config.products?.items || !priceData) return []\n return buildRuntimeProducts(config.products.items, priceData)\n }, [config.products, priceData])\n\n // ── Selected product ──────────────────────────────\n const defaultProductId = config.products?.defaultId || products[0]?.id || null\n const selectedProductIdRef = useRef<string | null>(defaultProductId)\n\n const selectProduct = useCallback((productId: string) => {\n selectedProductIdRef.current = productId\n store.set('products.selectedProductId', productId)\n }, [store])\n\n // ── Event bus + integrations ──────────────────────\n useEffect(() => {\n const eventBus = new AppFunnelEventBus(store, router, selectProduct)\n eventBus.attach()\n eventBusRef.current = eventBus\n\n // Initialize third-party integrations (Meta Pixel, GTM, Clarity, etc.)\n if (config.integrations && Object.keys(config.integrations).length > 0) {\n initializeIntegrations(config.integrations)\n }\n\n return () => {\n eventBus.destroy()\n eventBusRef.current = null\n }\n }, []) // eslint-disable-line react-hooks/exhaustive-deps\n\n // ── Initialize tracker ────────────────────────────\n useEffect(() => {\n tracker.init(campaignId, funnelId, campaignSlug, sessionData?.experimentId)\n\n if (sessionData?.sessionId) {\n tracker.setSessionId(sessionData.sessionId)\n }\n\n // Defer initial events so React Strict Mode's quick unmount cancels them\n const timer = setTimeout(() => {\n const currentPage = router.getCurrentPage()\n tracker.track('funnel.start')\n if (currentPage) {\n tracker.track('page.view', {\n pageId: currentPage.key,\n pageKey: currentPage.key,\n pageName: currentPage.name,\n isInitial: true,\n })\n tracker.startPageTracking(currentPage.key)\n }\n }, 50)\n\n return () => {\n clearTimeout(timer)\n tracker.stopPageTracking()\n tracker.flushVariables()\n }\n }, []) // eslint-disable-line react-hooks/exhaustive-deps\n\n // ── System variables ──────────────────────────────\n const sessionStartTime = useRef(Date.now())\n const pageStartTime = useRef(Date.now())\n\n useEffect(() => {\n const sysVars = computeSystemVariables({\n currentPageKey: router.getCurrentPage()?.key || '',\n pageHistory: router.getPageHistory(),\n pageStartTime: pageStartTime.current,\n sessionStartTime: sessionStartTime.current,\n totalPages: Object.keys(config.pages ?? {}).length,\n funnelId,\n campaignId,\n })\n store.setMany(sysVars)\n\n if (defaultProductId) {\n store.set('products.selectedProductId', defaultProductId)\n }\n }, []) // eslint-disable-line react-hooks/exhaustive-deps\n\n // ── Sync variables to tracker for persistence ─────\n useEffect(() => {\n return store.subscribe(() => {\n tracker.setCurrentVariables(store.getState() as Record<string, unknown>)\n })\n }, [store, tracker])\n\n // ── Context value ─────────────────────────────────\n const contextValue = useMemo<FunnelContextValue>(() => ({\n config,\n variableStore: store,\n router,\n tracker,\n i18n,\n products,\n selectedProductId: selectedProductIdRef.current,\n selectProduct,\n funnelId,\n campaignId,\n sessionId: tracker.getSessionId(),\n }), [config, store, router, tracker, i18n, products, selectProduct, funnelId, campaignId])\n\n return (\n <FunnelContext.Provider value={contextValue}>\n {children}\n </FunnelContext.Provider>\n )\n}\n"]}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { createContext, useContext, useRef, useMemo, useCallback, useEffect } from 'react';
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
5
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
6
|
+
}) : x)(function(x) {
|
|
7
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
8
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
9
|
+
});
|
|
10
|
+
|
|
4
11
|
// src/runtime/integrations.ts
|
|
5
12
|
var AppFunnelEventBus = class {
|
|
6
13
|
constructor(store, router, selectProduct) {
|
|
@@ -820,11 +827,13 @@ var FunnelTracker = class {
|
|
|
820
827
|
if (!this.currentPageId || !this.pageStartTime) return;
|
|
821
828
|
const durationMs = Date.now() - this.pageStartTime;
|
|
822
829
|
const activeMs = this.calculateActiveTime();
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
830
|
+
if (durationMs >= 50) {
|
|
831
|
+
this.track(
|
|
832
|
+
"page.exit",
|
|
833
|
+
{ pageId: this.currentPageId, durationMs, activeMs },
|
|
834
|
+
this.variablePersistence.getSavable() || void 0
|
|
835
|
+
);
|
|
836
|
+
}
|
|
828
837
|
this.cleanupPageTracking();
|
|
829
838
|
}
|
|
830
839
|
calculateActiveTime() {
|
|
@@ -859,7 +868,7 @@ var FunnelTracker = class {
|
|
|
859
868
|
// src/runtime/products.ts
|
|
860
869
|
function formatPrice(amount, currency) {
|
|
861
870
|
try {
|
|
862
|
-
return new Intl.NumberFormat(
|
|
871
|
+
return new Intl.NumberFormat("en-US", {
|
|
863
872
|
style: "currency",
|
|
864
873
|
currency: currency.toUpperCase()
|
|
865
874
|
}).format(amount);
|
|
@@ -893,6 +902,14 @@ function getIntervalLabel(interval, intervalCount) {
|
|
|
893
902
|
periodly: `every ${intervalCount} ${interval}s`
|
|
894
903
|
};
|
|
895
904
|
}
|
|
905
|
+
function getCurrencySymbol(currency) {
|
|
906
|
+
try {
|
|
907
|
+
const parts = new Intl.NumberFormat("en-US", { style: "currency", currency: currency.toUpperCase() }).formatToParts(0);
|
|
908
|
+
return parts.find((p) => p.type === "currency")?.value || currency.toUpperCase();
|
|
909
|
+
} catch {
|
|
910
|
+
return currency.toUpperCase();
|
|
911
|
+
}
|
|
912
|
+
}
|
|
896
913
|
function buildRuntimeProduct(product, priceData, trialPriceData) {
|
|
897
914
|
if (!priceData) {
|
|
898
915
|
const c = "USD";
|
|
@@ -914,6 +931,7 @@ function buildRuntimeProduct(product, priceData, trialPriceData) {
|
|
|
914
931
|
periodMonths: 0,
|
|
915
932
|
periodWeeks: 0,
|
|
916
933
|
currencyCode: c,
|
|
934
|
+
currencySymbol: getCurrencySymbol(c),
|
|
917
935
|
hasTrial: fallbackTrialDays > 0,
|
|
918
936
|
trialDays: fallbackTrialDays,
|
|
919
937
|
paidTrial: false,
|
|
@@ -964,6 +982,7 @@ function buildRuntimeProduct(product, priceData, trialPriceData) {
|
|
|
964
982
|
periodMonths,
|
|
965
983
|
periodWeeks,
|
|
966
984
|
currencyCode: currency,
|
|
985
|
+
currencySymbol: getCurrencySymbol(currency),
|
|
967
986
|
hasTrial,
|
|
968
987
|
trialDays,
|
|
969
988
|
paidTrial: hasTrial && trialRawPrice > 0,
|
|
@@ -1240,18 +1259,21 @@ function FunnelProvider({
|
|
|
1240
1259
|
if (sessionData?.sessionId) {
|
|
1241
1260
|
tracker.setSessionId(sessionData.sessionId);
|
|
1242
1261
|
}
|
|
1243
|
-
const
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1262
|
+
const timer = setTimeout(() => {
|
|
1263
|
+
const currentPage = router.getCurrentPage();
|
|
1264
|
+
tracker.track("funnel.start");
|
|
1265
|
+
if (currentPage) {
|
|
1266
|
+
tracker.track("page.view", {
|
|
1267
|
+
pageId: currentPage.key,
|
|
1268
|
+
pageKey: currentPage.key,
|
|
1269
|
+
pageName: currentPage.name,
|
|
1270
|
+
isInitial: true
|
|
1271
|
+
});
|
|
1272
|
+
tracker.startPageTracking(currentPage.key);
|
|
1273
|
+
}
|
|
1274
|
+
}, 50);
|
|
1254
1275
|
return () => {
|
|
1276
|
+
clearTimeout(timer);
|
|
1255
1277
|
tracker.stopPageTracking();
|
|
1256
1278
|
tracker.flushVariables();
|
|
1257
1279
|
};
|
|
@@ -1294,6 +1316,6 @@ function FunnelProvider({
|
|
|
1294
1316
|
return /* @__PURE__ */ jsx(FunnelContext.Provider, { value: contextValue, children });
|
|
1295
1317
|
}
|
|
1296
1318
|
|
|
1297
|
-
export { FunnelProvider, registerIntegration, useFunnelContext };
|
|
1298
|
-
//# sourceMappingURL=chunk-
|
|
1299
|
-
//# sourceMappingURL=chunk-
|
|
1319
|
+
export { FunnelProvider, __require, registerIntegration, useFunnelContext };
|
|
1320
|
+
//# sourceMappingURL=chunk-H3KHXZSI.js.map
|
|
1321
|
+
//# sourceMappingURL=chunk-H3KHXZSI.js.map
|