@appfunnel-dev/sdk 0.5.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/index.cjs CHANGED
@@ -1,9 +1,11 @@
1
1
  'use strict';
2
2
 
3
+ var chunkXP44I2MU_cjs = require('./chunk-XP44I2MU.cjs');
4
+ var chunkEVUYCLVY_cjs = require('./chunk-EVUYCLVY.cjs');
3
5
  var react = require('react');
4
- var jsxRuntime = require('react/jsx-runtime');
5
6
  var stripeJs = require('@stripe/stripe-js');
6
7
  var reactStripeJs = require('@stripe/react-stripe-js');
8
+ var jsxRuntime = require('react/jsx-runtime');
7
9
 
8
10
  // src/config.ts
9
11
  function defineConfig(config) {
@@ -12,23 +14,11 @@ function defineConfig(config) {
12
14
  function definePage(definition) {
13
15
  return definition;
14
16
  }
15
- function registerIntegration(id, loader) {
16
- }
17
- var FunnelContext = react.createContext(null);
18
- function useFunnelContext() {
19
- const ctx = react.useContext(FunnelContext);
20
- if (!ctx) {
21
- throw new Error("useFunnelContext must be used within a <FunnelProvider>");
22
- }
23
- return ctx;
24
- }
25
-
26
- // src/hooks/useVariable.ts
27
17
  function useVariable(id) {
28
- const { variableStore } = useFunnelContext();
18
+ const { variableStore } = chunkEVUYCLVY_cjs.useFunnelContext();
29
19
  const subscribe = react.useCallback(
30
- (callback) => variableStore.subscribe(callback),
31
- [variableStore]
20
+ (callback) => variableStore.subscribe(callback, { keys: [id] }),
21
+ [variableStore, id]
32
22
  );
33
23
  const getSnapshot = react.useCallback(
34
24
  () => variableStore.get(id),
@@ -42,7 +32,7 @@ function useVariable(id) {
42
32
  return [value, setValue];
43
33
  }
44
34
  function useVariables() {
45
- const { variableStore } = useFunnelContext();
35
+ const { variableStore } = chunkEVUYCLVY_cjs.useFunnelContext();
46
36
  const subscribe = react.useCallback(
47
37
  (callback) => variableStore.subscribe(callback),
48
38
  [variableStore]
@@ -53,10 +43,106 @@ function useVariables() {
53
43
  );
54
44
  return react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
55
45
  }
46
+
47
+ // src/utils/date.ts
48
+ function toISODate(input) {
49
+ if (!input || !input.trim()) return "";
50
+ const s = input.trim();
51
+ if (/^\d{4}-\d{2}-\d{2}$/.test(s)) return s;
52
+ if (/^\d{4}-\d{2}-\d{2}T/.test(s)) return s.slice(0, 10);
53
+ const sepMatch = s.match(/^(\d{1,2})[/\-.](\d{1,2})[/\-.](\d{4})$/);
54
+ if (sepMatch) {
55
+ const a = parseInt(sepMatch[1], 10);
56
+ const b = parseInt(sepMatch[2], 10);
57
+ const year = sepMatch[3];
58
+ let month;
59
+ let day;
60
+ if (a > 12 && b <= 12) {
61
+ day = a;
62
+ month = b;
63
+ } else if (b > 12 && a <= 12) {
64
+ month = a;
65
+ day = b;
66
+ } else {
67
+ month = a;
68
+ day = b;
69
+ }
70
+ if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
71
+ return `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
72
+ }
73
+ }
74
+ const ymdSlash = s.match(/^(\d{4})[/\-.](\d{1,2})[/\-.](\d{1,2})$/);
75
+ if (ymdSlash) {
76
+ const year = ymdSlash[1];
77
+ const month = parseInt(ymdSlash[2], 10);
78
+ const day = parseInt(ymdSlash[3], 10);
79
+ if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
80
+ return `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
81
+ }
82
+ }
83
+ if (/^\d{8}$/.test(s)) {
84
+ const a = parseInt(s.slice(0, 2), 10);
85
+ const b = parseInt(s.slice(2, 4), 10);
86
+ const year = s.slice(4, 8);
87
+ let month;
88
+ let day;
89
+ if (a > 12 && b <= 12) {
90
+ day = a;
91
+ month = b;
92
+ } else {
93
+ month = a;
94
+ day = b;
95
+ }
96
+ if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
97
+ return `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
98
+ }
99
+ }
100
+ throw new Error(
101
+ `[AppFunnel] Invalid date format: "${input}". Expected a date string like MM/DD/YYYY, DD/MM/YYYY, YYYY-MM-DD, or MMDDYYYY.`
102
+ );
103
+ }
104
+ function toISODateWithFormat(input, format) {
105
+ if (!input || !input.trim()) return "";
106
+ const s = input.trim();
107
+ if (/^\d{4}-\d{2}-\d{2}$/.test(s) || /^\d{4}-\d{2}-\d{2}T/.test(s)) {
108
+ return s.slice(0, 10);
109
+ }
110
+ const digits = s.replace(/[^\d]/g, "");
111
+ if (format === "YYYY-MM-DD") {
112
+ const m = s.match(/^(\d{4})[/\-.](\d{1,2})[/\-.](\d{1,2})$/);
113
+ if (m) return `${m[1]}-${m[2].padStart(2, "0")}-${m[3].padStart(2, "0")}`;
114
+ if (digits.length === 8) {
115
+ return `${digits.slice(0, 4)}-${digits.slice(4, 6)}-${digits.slice(6, 8)}`;
116
+ }
117
+ }
118
+ if (format === "MM/DD/YYYY") {
119
+ const m = s.match(/^(\d{1,2})[/\-.](\d{1,2})[/\-.](\d{4})$/);
120
+ if (m) return `${m[3]}-${m[1].padStart(2, "0")}-${m[2].padStart(2, "0")}`;
121
+ if (digits.length === 8) {
122
+ return `${digits.slice(4, 8)}-${digits.slice(0, 2)}-${digits.slice(2, 4)}`;
123
+ }
124
+ }
125
+ if (format === "DD/MM/YYYY") {
126
+ const m = s.match(/^(\d{1,2})[/\-.](\d{1,2})[/\-.](\d{4})$/);
127
+ if (m) return `${m[3]}-${m[2].padStart(2, "0")}-${m[1].padStart(2, "0")}`;
128
+ if (digits.length === 8) {
129
+ return `${digits.slice(4, 8)}-${digits.slice(2, 4)}-${digits.slice(0, 2)}`;
130
+ }
131
+ }
132
+ throw new Error(
133
+ `[AppFunnel] Invalid date format: "${input}". Expected format ${format} (e.g. ${{
134
+ "MM/DD/YYYY": "03/15/1990 or 03151990",
135
+ "DD/MM/YYYY": "15/03/1990 or 15031990",
136
+ "YYYY-MM-DD": "1990-03-15 or 19900315"
137
+ }[format]}).`
138
+ );
139
+ }
140
+
141
+ // src/hooks/useUser.ts
56
142
  function useUser() {
57
- const { variableStore, tracker } = useFunnelContext();
143
+ const { variableStore } = chunkEVUYCLVY_cjs.useFunnelContext();
58
144
  const subscribe = react.useCallback(
59
- (cb) => variableStore.subscribe(cb),
145
+ (cb) => variableStore.subscribe(cb, { prefix: "user." }),
60
146
  [variableStore]
61
147
  );
62
148
  const getSnapshot = react.useCallback(
@@ -73,24 +159,23 @@ function useUser() {
73
159
  dateOfBirth: variables["user.dateOfBirth"] || "",
74
160
  setEmail(email) {
75
161
  variableStore.set("user.email", email);
76
- tracker.identify(email);
77
162
  },
78
163
  setName(name) {
79
164
  variableStore.set("user.name", name);
80
165
  },
81
166
  setDateOfBirth(dateOfBirth) {
82
- variableStore.set("user.dateOfBirth", dateOfBirth);
167
+ variableStore.set("user.dateOfBirth", toISODate(dateOfBirth));
83
168
  }
84
169
  }),
85
- [variables, variableStore, tracker]
170
+ [variables, variableStore]
86
171
  );
87
172
  }
88
173
  function useUserProperty(field) {
89
- const { variableStore } = useFunnelContext();
174
+ const { variableStore } = chunkEVUYCLVY_cjs.useFunnelContext();
90
175
  const key = `user.${field}`;
91
176
  const subscribe = react.useCallback(
92
- (cb) => variableStore.subscribe(cb),
93
- [variableStore]
177
+ (cb) => variableStore.subscribe(cb, { keys: [key] }),
178
+ [variableStore, key]
94
179
  );
95
180
  const getSnapshot = react.useCallback(
96
181
  () => variableStore.get(key) || "",
@@ -103,49 +188,28 @@ function useUserProperty(field) {
103
188
  );
104
189
  return [value, setValue];
105
190
  }
106
- function useResponse(key) {
107
- const { variableStore } = useFunnelContext();
108
- const prefixedKey = `answers.${key}`;
191
+ function useDateOfBirth(format = "MM/DD/YYYY") {
192
+ const { variableStore } = chunkEVUYCLVY_cjs.useFunnelContext();
193
+ const key = "user.dateOfBirth";
109
194
  const subscribe = react.useCallback(
110
- (cb) => variableStore.subscribe(cb),
195
+ (cb) => variableStore.subscribe(cb, { keys: [key] }),
111
196
  [variableStore]
112
197
  );
113
198
  const getSnapshot = react.useCallback(
114
- () => variableStore.get(prefixedKey),
115
- [variableStore, prefixedKey]
199
+ () => variableStore.get(key) || "",
200
+ [variableStore]
116
201
  );
117
202
  const value = react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
118
203
  const setValue = react.useCallback(
119
- (v) => variableStore.set(prefixedKey, v),
120
- [variableStore, prefixedKey]
204
+ (v) => variableStore.set(key, toISODateWithFormat(v, format)),
205
+ [variableStore, format]
121
206
  );
122
207
  return [value, setValue];
123
208
  }
124
- function useResponses() {
125
- const { variableStore } = useFunnelContext();
126
- const subscribe = react.useCallback(
127
- (cb) => variableStore.subscribe(cb),
128
- [variableStore]
129
- );
130
- const getSnapshot = react.useCallback(
131
- () => variableStore.getState(),
132
- [variableStore]
133
- );
134
- const variables = react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
135
- return react.useMemo(() => {
136
- const result = {};
137
- for (const [key, value] of Object.entries(variables)) {
138
- if (key.startsWith("answers.")) {
139
- result[key.slice(8)] = value;
140
- }
141
- }
142
- return result;
143
- }, [variables]);
144
- }
145
209
  function useQueryParams() {
146
- const { variableStore } = useFunnelContext();
210
+ const { variableStore } = chunkEVUYCLVY_cjs.useFunnelContext();
147
211
  const subscribe = react.useCallback(
148
- (cb) => variableStore.subscribe(cb),
212
+ (cb) => variableStore.subscribe(cb, { prefix: "query." }),
149
213
  [variableStore]
150
214
  );
151
215
  const getSnapshot = react.useCallback(
@@ -164,11 +228,11 @@ function useQueryParams() {
164
228
  }, [variables]);
165
229
  }
166
230
  function useQueryParam(key) {
167
- const { variableStore } = useFunnelContext();
231
+ const { variableStore } = chunkEVUYCLVY_cjs.useFunnelContext();
168
232
  const prefixedKey = `query.${key}`;
169
233
  const subscribe = react.useCallback(
170
- (cb) => variableStore.subscribe(cb),
171
- [variableStore]
234
+ (cb) => variableStore.subscribe(cb, { keys: [prefixedKey] }),
235
+ [variableStore, prefixedKey]
172
236
  );
173
237
  const getSnapshot = react.useCallback(
174
238
  () => variableStore.get(prefixedKey) || "",
@@ -177,11 +241,11 @@ function useQueryParam(key) {
177
241
  return react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
178
242
  }
179
243
  function useData(key) {
180
- const { variableStore } = useFunnelContext();
244
+ const { variableStore } = chunkEVUYCLVY_cjs.useFunnelContext();
181
245
  const prefixedKey = `data.${key}`;
182
246
  const subscribe = react.useCallback(
183
- (cb) => variableStore.subscribe(cb),
184
- [variableStore]
247
+ (cb) => variableStore.subscribe(cb, { keys: [prefixedKey] }),
248
+ [variableStore, prefixedKey]
185
249
  );
186
250
  const getSnapshot = react.useCallback(
187
251
  () => variableStore.get(prefixedKey),
@@ -230,7 +294,7 @@ function detect24Hour(locale) {
230
294
  }
231
295
  }
232
296
  function useTranslation() {
233
- const { i18n } = useFunnelContext();
297
+ const { i18n } = chunkEVUYCLVY_cjs.useFunnelContext();
234
298
  const subscribe = react.useCallback(
235
299
  (cb) => i18n.subscribe(cb),
236
300
  [i18n]
@@ -252,99 +316,10 @@ function useTranslation() {
252
316
  const availableLocales = i18n.getAvailableLocales();
253
317
  return { t, locale, setLocale, availableLocales };
254
318
  }
255
- function useNavigation() {
256
- const { router, variableStore, tracker } = useFunnelContext();
257
- const subscribe = react.useCallback(
258
- (cb) => variableStore.subscribe(cb),
259
- [variableStore]
260
- );
261
- const getSnapshot = react.useCallback(
262
- () => variableStore.getState(),
263
- [variableStore]
264
- );
265
- const variables = react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
266
- const goToNextPage = react.useCallback(() => {
267
- const previousPage = router.getCurrentPage();
268
- if (previousPage) {
269
- tracker.stopPageTracking();
270
- }
271
- const nextKey = router.goToNextPage(variables);
272
- if (nextKey) {
273
- const nextPage = router.getCurrentPage();
274
- if (nextPage) {
275
- tracker.track("page.view", {
276
- pageId: nextPage.key,
277
- pageKey: nextPage.key,
278
- pageName: nextPage.name
279
- });
280
- tracker.startPageTracking(nextPage.key);
281
- }
282
- variableStore.setMany({
283
- "page.currentId": nextKey,
284
- "page.currentIndex": router.getPageHistory().length,
285
- "page.current": router.getPageHistory().length + 1,
286
- "page.startedAt": Date.now(),
287
- "page.timeOnCurrent": 0
288
- });
289
- }
290
- }, [router, variables, tracker, variableStore]);
291
- const goBack = react.useCallback(() => {
292
- tracker.stopPageTracking();
293
- const prevKey = router.goBack();
294
- if (prevKey) {
295
- const page = router.getCurrentPage();
296
- if (page) {
297
- tracker.track("page.view", {
298
- pageId: page.key,
299
- pageKey: page.key,
300
- pageName: page.name
301
- });
302
- tracker.startPageTracking(page.key);
303
- }
304
- variableStore.setMany({
305
- "page.currentId": prevKey,
306
- "page.currentIndex": router.getPageHistory().length,
307
- "page.current": router.getPageHistory().length + 1,
308
- "page.startedAt": Date.now(),
309
- "page.timeOnCurrent": 0
310
- });
311
- }
312
- }, [router, tracker, variableStore]);
313
- const goToPage = react.useCallback((pageKey) => {
314
- tracker.stopPageTracking();
315
- const key = router.goToPage(pageKey);
316
- if (key) {
317
- const page = router.getCurrentPage();
318
- if (page) {
319
- tracker.track("page.view", {
320
- pageId: page.key,
321
- pageKey: page.key,
322
- pageName: page.name
323
- });
324
- tracker.startPageTracking(page.key);
325
- }
326
- variableStore.setMany({
327
- "page.currentId": key,
328
- "page.currentIndex": router.getPageHistory().length,
329
- "page.current": router.getPageHistory().length + 1,
330
- "page.startedAt": Date.now(),
331
- "page.timeOnCurrent": 0
332
- });
333
- }
334
- }, [router, tracker, variableStore]);
335
- return {
336
- goToNextPage,
337
- goBack,
338
- goToPage,
339
- currentPage: router.getCurrentPage(),
340
- pageHistory: router.getPageHistory(),
341
- progress: router.getProgress()
342
- };
343
- }
344
319
  function useProducts() {
345
- const { products, variableStore, selectProduct: ctxSelect } = useFunnelContext();
320
+ const { products, variableStore, selectProduct: ctxSelect } = chunkEVUYCLVY_cjs.useFunnelContext();
346
321
  const subscribe = react.useCallback(
347
- (cb) => variableStore.subscribe(cb),
322
+ (cb) => variableStore.subscribe(cb, { keys: ["products.selectedProductId"] }),
348
323
  [variableStore]
349
324
  );
350
325
  const getSnapshot = react.useCallback(
@@ -359,7 +334,7 @@ function useProducts() {
359
334
  return { products, selected, select };
360
335
  }
361
336
  function useTracking() {
362
- const { tracker } = useFunnelContext();
337
+ const { tracker } = chunkEVUYCLVY_cjs.useFunnelContext();
363
338
  const track = react.useCallback(
364
339
  (eventName, data) => {
365
340
  tracker.track(eventName, data);
@@ -374,10 +349,19 @@ function useTracking() {
374
349
  );
375
350
  return { track, identify };
376
351
  }
352
+ var PAYMENT_KEYS = [
353
+ "card.last4",
354
+ "card.brand",
355
+ "card.expMonth",
356
+ "card.expYear",
357
+ "payment.loading",
358
+ "payment.error",
359
+ "payment.customerId"
360
+ ];
377
361
  function usePayment() {
378
- const { variableStore, tracker } = useFunnelContext();
362
+ const { variableStore } = chunkEVUYCLVY_cjs.useFunnelContext();
379
363
  const subscribe = react.useCallback(
380
- (cb) => variableStore.subscribe(cb),
364
+ (cb) => variableStore.subscribe(cb, { keys: PAYMENT_KEYS }),
381
365
  [variableStore]
382
366
  );
383
367
  const getSnapshot = react.useCallback(
@@ -390,269 +374,483 @@ function usePayment() {
390
374
  const brand = variables["card.brand"] || "";
391
375
  const expMonth = variables["card.expMonth"] || 0;
392
376
  const expYear = variables["card.expYear"] || 0;
377
+ const customerId = variables["payment.customerId"] || null;
393
378
  return {
394
- customerId: tracker.getCustomerId(),
379
+ customerId,
395
380
  isAuthorized: !!last4,
396
381
  loading: !!variables["payment.loading"],
397
382
  error: variables["payment.error"] || null,
398
383
  cardDetails: last4 ? { last4, brand, expMonth, expYear } : null
399
384
  };
400
- }, [variables, tracker]);
385
+ }, [variables]);
386
+ }
387
+ var DEVICE_KEYS = [
388
+ "os.name",
389
+ "os.timezone",
390
+ "device.type",
391
+ "device.isMobile",
392
+ "device.isTablet",
393
+ "device.screenWidth",
394
+ "device.screenHeight",
395
+ "device.viewportWidth",
396
+ "device.viewportHeight",
397
+ "device.colorDepth",
398
+ "device.pixelRatio",
399
+ "browser.name",
400
+ "browser.version",
401
+ "browser.userAgent",
402
+ "browser.cookieEnabled",
403
+ "browser.online",
404
+ "browser.language"
405
+ ];
406
+ function useDeviceInfo() {
407
+ const { variableStore } = chunkEVUYCLVY_cjs.useFunnelContext();
408
+ const subscribe = react.useCallback(
409
+ (cb) => variableStore.subscribe(cb, { keys: DEVICE_KEYS }),
410
+ [variableStore]
411
+ );
412
+ const getSnapshot = react.useCallback(
413
+ () => variableStore.getState(),
414
+ [variableStore]
415
+ );
416
+ const variables = react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
417
+ return react.useMemo(() => ({
418
+ os: {
419
+ name: variables["os.name"] || "",
420
+ timezone: variables["os.timezone"] || ""
421
+ },
422
+ device: {
423
+ type: variables["device.type"] || "desktop",
424
+ isMobile: !!variables["device.isMobile"],
425
+ isTablet: !!variables["device.isTablet"],
426
+ screenWidth: variables["device.screenWidth"] || 0,
427
+ screenHeight: variables["device.screenHeight"] || 0,
428
+ viewportWidth: variables["device.viewportWidth"] || 0,
429
+ viewportHeight: variables["device.viewportHeight"] || 0,
430
+ colorDepth: variables["device.colorDepth"] || 24,
431
+ pixelRatio: variables["device.pixelRatio"] || 1
432
+ },
433
+ browser: {
434
+ name: variables["browser.name"] || "",
435
+ version: variables["browser.version"] || "",
436
+ userAgent: variables["browser.userAgent"] || "",
437
+ cookieEnabled: variables["browser.cookieEnabled"] !== false,
438
+ online: variables["browser.online"] !== false,
439
+ language: variables["browser.language"] || "en"
440
+ }
441
+ }), [variables]);
442
+ }
443
+ function useSafeArea() {
444
+ const [insets, setInsets] = react.useState({ top: 0, right: 0, bottom: 0, left: 0 });
445
+ react.useEffect(() => {
446
+ if (typeof window === "undefined") return;
447
+ const el = document.createElement("div");
448
+ el.style.cssText = [
449
+ "position:fixed",
450
+ "top:env(safe-area-inset-top,0px)",
451
+ "right:env(safe-area-inset-right,0px)",
452
+ "bottom:env(safe-area-inset-bottom,0px)",
453
+ "left:env(safe-area-inset-left,0px)",
454
+ "pointer-events:none",
455
+ "visibility:hidden",
456
+ "z-index:-1"
457
+ ].join(";");
458
+ document.body.appendChild(el);
459
+ function read() {
460
+ const style = getComputedStyle(el);
461
+ setInsets({
462
+ top: parseFloat(style.top) || 0,
463
+ right: parseFloat(style.right) || 0,
464
+ bottom: parseFloat(style.bottom) || 0,
465
+ left: parseFloat(style.left) || 0
466
+ });
467
+ }
468
+ read();
469
+ const observer = new ResizeObserver(read);
470
+ observer.observe(el);
471
+ window.addEventListener("resize", read);
472
+ return () => {
473
+ observer.disconnect();
474
+ window.removeEventListener("resize", read);
475
+ el.remove();
476
+ };
477
+ }, []);
478
+ return insets;
479
+ }
480
+ function useKeyboard() {
481
+ const [state, setState] = react.useState({ isOpen: false, height: 0 });
482
+ const timeoutRef = react.useRef();
483
+ react.useEffect(() => {
484
+ if (typeof window === "undefined") return;
485
+ if ("virtualKeyboard" in navigator) {
486
+ const vk = navigator.virtualKeyboard;
487
+ vk.overlaysContent = true;
488
+ const handler = () => {
489
+ const h = vk.boundingRect.height;
490
+ setState((prev) => {
491
+ if (prev.height === h && prev.isOpen === h > 0) return prev;
492
+ return { isOpen: h > 0, height: h };
493
+ });
494
+ };
495
+ vk.addEventListener("geometrychange", handler);
496
+ handler();
497
+ return () => vk.removeEventListener("geometrychange", handler);
498
+ }
499
+ const vv = window.visualViewport;
500
+ if (!vv) return;
501
+ let layoutHeight = window.innerHeight;
502
+ function compute() {
503
+ const kbHeight = Math.max(0, layoutHeight - vv.height);
504
+ const h = kbHeight > 40 ? Math.round(kbHeight) : 0;
505
+ setState((prev) => {
506
+ if (prev.height === h && prev.isOpen === h > 0) return prev;
507
+ return { isOpen: h > 0, height: h };
508
+ });
509
+ }
510
+ function onViewportResize() {
511
+ compute();
512
+ clearTimeout(timeoutRef.current);
513
+ timeoutRef.current = setTimeout(compute, 1e3);
514
+ }
515
+ function onWindowResize() {
516
+ layoutHeight = window.innerHeight;
517
+ compute();
518
+ }
519
+ vv.addEventListener("resize", onViewportResize);
520
+ window.addEventListener("resize", onWindowResize);
521
+ window.addEventListener("orientationchange", onWindowResize);
522
+ compute();
523
+ return () => {
524
+ clearTimeout(timeoutRef.current);
525
+ vv.removeEventListener("resize", onViewportResize);
526
+ window.removeEventListener("resize", onWindowResize);
527
+ window.removeEventListener("orientationchange", onWindowResize);
528
+ };
529
+ }, []);
530
+ return state;
531
+ }
532
+ var PAGE_KEYS = [
533
+ "page.currentId",
534
+ "page.currentIndex",
535
+ "page.current",
536
+ "page.total",
537
+ "page.progressPercentage",
538
+ "page.startedAt"
539
+ ];
540
+ function usePageData() {
541
+ const { variableStore } = chunkEVUYCLVY_cjs.useFunnelContext();
542
+ const subscribe = react.useCallback(
543
+ (cb) => variableStore.subscribe(cb, { keys: PAGE_KEYS }),
544
+ [variableStore]
545
+ );
546
+ const getSnapshot = react.useCallback(
547
+ () => variableStore.getState(),
548
+ [variableStore]
549
+ );
550
+ const variables = react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
551
+ return react.useMemo(() => ({
552
+ currentId: variables["page.currentId"] || "",
553
+ currentIndex: variables["page.currentIndex"] || 0,
554
+ current: variables["page.current"] || 1,
555
+ total: variables["page.total"] || 0,
556
+ progressPercentage: variables["page.progressPercentage"] || 0,
557
+ startedAt: variables["page.startedAt"] || 0
558
+ }), [variables]);
401
559
  }
402
560
 
403
561
  // src/hooks/useFunnel.ts
404
562
  function useFunnel() {
405
- const { funnelId, campaignId, tracker } = useFunnelContext();
563
+ const { funnelId, campaignId, tracker } = chunkEVUYCLVY_cjs.useFunnelContext();
406
564
  return {
407
565
  funnelId,
408
566
  campaignId,
409
567
  sessionId: tracker.getSessionId(),
410
568
  variables: useVariables(),
411
569
  user: useUser(),
412
- responses: useResponses(),
570
+ responses: chunkXP44I2MU_cjs.useResponses(),
413
571
  queryParams: useQueryParams(),
414
- navigation: useNavigation(),
572
+ navigation: chunkXP44I2MU_cjs.useNavigation(),
415
573
  products: useProducts(),
416
574
  tracking: useTracking(),
417
575
  payment: usePayment()
418
576
  };
419
577
  }
420
- function InnerPaymentForm({
421
- paymentMode,
422
- validateOnly,
423
- onSuccess,
424
- onError
425
- }) {
426
- const stripe = reactStripeJs.useStripe();
427
- const elements = reactStripeJs.useElements();
428
- const [error, setError] = react.useState(null);
429
- const { variableStore, campaignId, tracker, apiBaseUrl, products } = useFunnelContext();
430
- const handleSubmit = react.useCallback(async () => {
431
- if (!stripe || !elements) {
432
- const msg = "Stripe not loaded";
433
- setError(msg);
434
- onError?.(msg);
435
- return;
436
- }
437
- setError(null);
438
- variableStore.set("payment.loading", true);
439
- try {
440
- const confirmFn = paymentMode === "setup" ? stripe.confirmSetup : stripe.confirmPayment;
441
- const confirmResult = await confirmFn({
442
- elements,
443
- redirect: "if_required",
444
- confirmParams: { return_url: window.location.href }
445
- });
446
- if (confirmResult.error) {
447
- const msg = confirmResult.error.message || "Payment failed";
578
+ var API_BASE_URL = "https://api.appfunnel.net";
579
+ var InnerPaymentForm = react.forwardRef(
580
+ function InnerPaymentForm2({ paymentMode, validateOnly, onSuccess, onError, onReady, layout }, ref) {
581
+ const stripe = reactStripeJs.useStripe();
582
+ const elements = reactStripeJs.useElements();
583
+ const [error, setError] = react.useState(null);
584
+ const { variableStore, campaignId, tracker, products } = chunkEVUYCLVY_cjs.useFunnelContext();
585
+ const readyFired = react.useRef(false);
586
+ react.useEffect(() => {
587
+ if (stripe && elements && !readyFired.current) {
588
+ readyFired.current = true;
589
+ onReady?.();
590
+ }
591
+ }, [stripe, elements, onReady]);
592
+ const handleSubmit = react.useCallback(async () => {
593
+ if (!stripe || !elements) {
594
+ const msg = "Stripe not loaded";
448
595
  setError(msg);
449
- variableStore.set("payment.error", msg);
450
596
  onError?.(msg);
451
597
  return;
452
598
  }
453
- tracker.track("checkout.payment_added");
454
- if (validateOnly) {
455
- const piId = "paymentIntent" in confirmResult ? confirmResult.paymentIntent : void 0;
456
- if (!piId?.id) {
457
- const msg = "PaymentIntent not found after confirmation";
599
+ setError(null);
600
+ variableStore.set("payment.loading", true);
601
+ try {
602
+ const confirmFn = paymentMode === "setup" ? stripe.confirmSetup : stripe.confirmPayment;
603
+ const confirmResult = await confirmFn({
604
+ elements,
605
+ redirect: "if_required",
606
+ confirmParams: { return_url: window.location.href }
607
+ });
608
+ if (confirmResult.error) {
609
+ const msg = confirmResult.error.message || "Payment failed";
458
610
  setError(msg);
459
611
  variableStore.set("payment.error", msg);
460
612
  onError?.(msg);
461
613
  return;
462
614
  }
463
- const response2 = await fetch(
464
- `${apiBaseUrl}/campaign/${campaignId}/stripe/validate-card`,
615
+ tracker.track("checkout.payment_added");
616
+ if (validateOnly) {
617
+ const piId = "paymentIntent" in confirmResult ? confirmResult.paymentIntent : void 0;
618
+ if (!piId?.id) {
619
+ const msg = "PaymentIntent not found after confirmation";
620
+ setError(msg);
621
+ variableStore.set("payment.error", msg);
622
+ onError?.(msg);
623
+ return;
624
+ }
625
+ const response2 = await fetch(
626
+ `${API_BASE_URL}/campaign/${campaignId}/stripe/validate-card`,
627
+ {
628
+ method: "POST",
629
+ headers: { "Content-Type": "application/json" },
630
+ body: JSON.stringify({
631
+ campaignId,
632
+ sessionId: tracker.getSessionId(),
633
+ paymentIntentId: piId.id
634
+ })
635
+ }
636
+ );
637
+ const result2 = await response2.json();
638
+ if (!result2.success) {
639
+ const msg = result2.error || "Card validation failed";
640
+ setError(msg);
641
+ variableStore.set("payment.error", msg);
642
+ onError?.(msg);
643
+ return;
644
+ }
645
+ variableStore.setMany({
646
+ "card.last4": result2.card.last4,
647
+ "card.brand": result2.card.brand,
648
+ "card.expMonth": result2.card.expMonth,
649
+ "card.expYear": result2.card.expYear,
650
+ "card.funding": result2.card.funding,
651
+ "payment.error": ""
652
+ });
653
+ onSuccess?.();
654
+ return;
655
+ }
656
+ const paymentIntentId = "paymentIntent" in confirmResult ? confirmResult.paymentIntent?.id : void 0;
657
+ const selectedId = variableStore.get("products.selectedProductId");
658
+ const product = products.find((p) => p.id === selectedId);
659
+ if (!product?.stripePriceId) {
660
+ const msg = "No product selected or missing Stripe price";
661
+ setError(msg);
662
+ variableStore.set("payment.error", msg);
663
+ onError?.(msg);
664
+ return;
665
+ }
666
+ const response = await fetch(
667
+ `${API_BASE_URL}/campaign/${campaignId}/stripe/purchase`,
465
668
  {
466
669
  method: "POST",
467
670
  headers: { "Content-Type": "application/json" },
468
671
  body: JSON.stringify({
469
672
  campaignId,
470
673
  sessionId: tracker.getSessionId(),
471
- paymentIntentId: piId.id
674
+ stripePriceId: product.stripePriceId,
675
+ trialPeriodDays: product.hasTrial ? product.trialDays : void 0,
676
+ onSessionPiId: paymentMode === "payment" ? paymentIntentId : void 0
472
677
  })
473
678
  }
474
679
  );
475
- const result2 = await response2.json();
476
- if (!result2.success) {
477
- const msg = result2.error || "Card validation failed";
680
+ const result = await response.json();
681
+ if (result.success) {
682
+ variableStore.set("payment.error", "");
683
+ if (result.eventId || result.eventIds?.firstPeriod) {
684
+ tracker.track("purchase.complete", {
685
+ amount: product.rawPrice ? product.rawPrice / 100 : 0,
686
+ currency: product.currencyCode || "USD"
687
+ });
688
+ }
689
+ onSuccess?.();
690
+ } else {
691
+ const msg = result.error || "Failed to process payment";
478
692
  setError(msg);
479
693
  variableStore.set("payment.error", msg);
480
694
  onError?.(msg);
481
- return;
482
695
  }
483
- variableStore.setMany({
484
- "card.last4": result2.card.last4,
485
- "card.brand": result2.card.brand,
486
- "card.expMonth": result2.card.expMonth,
487
- "card.expYear": result2.card.expYear,
488
- "card.funding": result2.card.funding,
489
- "payment.error": ""
490
- });
491
- onSuccess?.();
492
- return;
493
- }
494
- const paymentIntentId = "paymentIntent" in confirmResult ? confirmResult.paymentIntent?.id : void 0;
495
- const selectedId = variableStore.get("products.selectedProductId");
496
- const product = products.find((p) => p.id === selectedId);
497
- if (!product?.stripePriceId) {
498
- const msg = "No product selected or missing Stripe price";
696
+ } catch (err) {
697
+ const msg = err instanceof Error ? err.message : "An error occurred";
499
698
  setError(msg);
500
699
  variableStore.set("payment.error", msg);
501
700
  onError?.(msg);
502
- return;
701
+ } finally {
702
+ variableStore.set("payment.loading", false);
503
703
  }
504
- const variables = variableStore.getState();
505
- await tracker.updateUserData(variables);
506
- const response = await fetch(
507
- `${apiBaseUrl}/campaign/${campaignId}/stripe/purchase`,
508
- {
509
- method: "POST",
510
- headers: { "Content-Type": "application/json" },
511
- body: JSON.stringify({
512
- campaignId,
513
- sessionId: tracker.getSessionId(),
514
- stripePriceId: product.stripePriceId,
515
- trialPeriodDays: product.hasTrial ? product.trialDays : void 0,
516
- onSessionPiId: paymentMode === "payment" ? paymentIntentId : void 0
517
- })
518
- }
519
- );
520
- const result = await response.json();
521
- if (result.success) {
522
- variableStore.set("payment.error", "");
523
- if (result.eventId || result.eventIds?.firstPeriod) {
524
- tracker.track("purchase.complete", {
525
- amount: product.rawPrice ? product.rawPrice / 100 : 0,
526
- currency: product.currencyCode || "USD"
704
+ }, [stripe, elements, paymentMode, validateOnly, variableStore, campaignId, tracker, products, onSuccess, onError]);
705
+ react.useImperativeHandle(ref, () => ({ submit: handleSubmit }), [handleSubmit]);
706
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
707
+ /* @__PURE__ */ jsxRuntime.jsx(reactStripeJs.PaymentElement, { options: { layout: layout || "tabs" } }),
708
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#ef4444", fontSize: "14px", marginTop: "12px" }, children: error })
709
+ ] });
710
+ }
711
+ );
712
+ var StripePaymentForm = react.forwardRef(
713
+ function StripePaymentForm2({
714
+ productId,
715
+ mode = "checkout",
716
+ variant = "elements",
717
+ onSuccess,
718
+ onError,
719
+ onReady,
720
+ className,
721
+ appearance,
722
+ layout
723
+ }, ref) {
724
+ const { campaignId, tracker, variableStore, products } = chunkEVUYCLVY_cjs.useFunnelContext();
725
+ const [email] = useVariable("user.email");
726
+ const validateOnly = mode === "validate-only";
727
+ const product = react.useMemo(() => {
728
+ if (productId) return products.find((p) => p.id === productId) || null;
729
+ const selectedId = variableStore.get("products.selectedProductId");
730
+ return products.find((p) => p.id === selectedId) || null;
731
+ }, [productId, products, variableStore]);
732
+ const paymentMode = react.useMemo(() => {
733
+ if (validateOnly) return "payment";
734
+ if (product?.hasTrial && !product.paidTrial) return "setup";
735
+ return "payment";
736
+ }, [product, validateOnly]);
737
+ const [stripePromise, setStripePromise] = react.useState(null);
738
+ const [clientSecret, setClientSecret] = react.useState(null);
739
+ const [error, setError] = react.useState(null);
740
+ const [isLoading, setIsLoading] = react.useState(false);
741
+ const hasInitialized = react.useRef(false);
742
+ react.useEffect(() => {
743
+ if (!email || !campaignId || hasInitialized.current) return;
744
+ if (!product?.storePriceId) return;
745
+ hasInitialized.current = true;
746
+ setIsLoading(true);
747
+ variableStore.set("payment.loading", true);
748
+ const createIntent = async () => {
749
+ try {
750
+ if (variant === "embedded") {
751
+ const response = await fetch(
752
+ `${API_BASE_URL}/campaign/${campaignId}/stripe/checkout-session`,
753
+ {
754
+ method: "POST",
755
+ headers: { "Content-Type": "application/json" },
756
+ body: JSON.stringify({
757
+ campaignId,
758
+ sessionId: tracker.getSessionId(),
759
+ customerEmail: email,
760
+ priceId: product.storePriceId,
761
+ trialPeriodDays: product.hasTrial ? product.trialDays : void 0
762
+ })
763
+ }
764
+ );
765
+ const result = await response.json();
766
+ if (!result.success) throw new Error(result.error || "Failed to create checkout session");
767
+ setStripePromise(stripeJs.loadStripe(result.publishableKey));
768
+ setClientSecret(result.clientSecret);
769
+ } else {
770
+ const endpoint = paymentMode === "setup" ? `/campaign/${campaignId}/stripe/setup-intent` : `/campaign/${campaignId}/stripe/payment-intent`;
771
+ const body = {
772
+ campaignId,
773
+ sessionId: tracker.getSessionId(),
774
+ customerEmail: email,
775
+ priceId: product.storePriceId
776
+ };
777
+ if (validateOnly) body.validateOnly = true;
778
+ const response = await fetch(`${API_BASE_URL}${endpoint}`, {
779
+ method: "POST",
780
+ headers: { "Content-Type": "application/json" },
781
+ body: JSON.stringify(body)
782
+ });
783
+ const result = await response.json();
784
+ if (!result.success) throw new Error(result.error || "Failed to create intent");
785
+ setStripePromise(stripeJs.loadStripe(result.publishableKey));
786
+ setClientSecret(result.clientSecret);
787
+ variableStore.set("user.stripeCustomerId", result.customerId);
788
+ }
789
+ tracker.track("checkout.start", {
790
+ productId: product.id,
791
+ priceId: product.stripePriceId || product.storePriceId,
792
+ productName: product.displayName
527
793
  });
794
+ } catch (err) {
795
+ const msg = err instanceof Error ? err.message : "Failed to initialize payment";
796
+ setError(msg);
797
+ variableStore.set("payment.error", msg);
798
+ } finally {
799
+ setIsLoading(false);
800
+ variableStore.set("payment.loading", false);
528
801
  }
529
- onSuccess?.();
530
- } else {
531
- const msg = result.error || "Failed to process payment";
532
- setError(msg);
533
- variableStore.set("payment.error", msg);
534
- onError?.(msg);
535
- }
536
- } catch (err) {
537
- const msg = err instanceof Error ? err.message : "An error occurred";
538
- setError(msg);
539
- variableStore.set("payment.error", msg);
540
- onError?.(msg);
541
- } finally {
542
- variableStore.set("payment.loading", false);
802
+ };
803
+ createIntent();
804
+ }, [email, campaignId, product, paymentMode, validateOnly, variant, tracker, variableStore]);
805
+ if (isLoading) {
806
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { padding: "20px", textAlign: "center", color: "#6b7280" }, children: "Loading payment form..." });
543
807
  }
544
- }, [stripe, elements, paymentMode, validateOnly, variableStore, campaignId, tracker, apiBaseUrl, products, onSuccess, onError]);
545
- react.useEffect(() => {
546
- if (typeof window !== "undefined") {
547
- window.__paymentElementSubmit = handleSubmit;
808
+ if (!email) {
809
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { padding: "20px", textAlign: "center", color: "#ef4444", fontSize: "14px" }, children: "Email is required to initialize payment" });
548
810
  }
549
- return () => {
550
- if (typeof window !== "undefined") {
551
- delete window.__paymentElementSubmit;
552
- }
553
- };
554
- }, [handleSubmit]);
555
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
556
- /* @__PURE__ */ jsxRuntime.jsx(reactStripeJs.PaymentElement, { options: { layout: "tabs" } }),
557
- error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#ef4444", fontSize: "14px", marginTop: "12px" }, children: error })
558
- ] });
559
- }
560
- function PaymentForm({
561
- productId,
562
- mode = "checkout",
563
- onSuccess,
564
- onError,
565
- className,
566
- appearance
567
- }) {
568
- const { campaignId, tracker, variableStore, apiBaseUrl, products } = useFunnelContext();
569
- const [email] = useVariable("user.email");
570
- const validateOnly = mode === "validate-only";
571
- const product = react.useMemo(() => {
572
- if (productId) return products.find((p) => p.id === productId) || null;
573
- const selectedId = variableStore.get("products.selectedProductId");
574
- return products.find((p) => p.id === selectedId) || null;
575
- }, [productId, products, variableStore]);
576
- const paymentMode = react.useMemo(() => {
577
- if (validateOnly) return "payment";
578
- if (product?.hasTrial && !product.paidTrial) return "setup";
579
- return "payment";
580
- }, [product, validateOnly]);
581
- const [stripePromise, setStripePromise] = react.useState(null);
582
- const [clientSecret, setClientSecret] = react.useState(null);
583
- const [error, setError] = react.useState(null);
584
- const [isLoading, setIsLoading] = react.useState(false);
585
- const hasInitialized = react.useRef(false);
586
- react.useEffect(() => {
587
- if (!email || !campaignId || hasInitialized.current) return;
588
- if (!product?.storePriceId) return;
589
- hasInitialized.current = true;
590
- setIsLoading(true);
591
- variableStore.set("payment.loading", true);
592
- const createIntent = async () => {
593
- try {
594
- const endpoint = paymentMode === "setup" ? `/campaign/${campaignId}/stripe/setup-intent` : `/campaign/${campaignId}/stripe/payment-intent`;
595
- const body = {
596
- campaignId,
597
- sessionId: tracker.getSessionId(),
598
- customerEmail: email,
599
- priceId: product.storePriceId
600
- };
601
- if (validateOnly) body.validateOnly = true;
602
- const response = await fetch(`${apiBaseUrl}${endpoint}`, {
603
- method: "POST",
604
- headers: { "Content-Type": "application/json" },
605
- body: JSON.stringify(body)
606
- });
607
- const result = await response.json();
608
- if (!result.success) {
609
- throw new Error(result.error || "Failed to create intent");
811
+ if (error) {
812
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { padding: "20px", textAlign: "center", color: "#ef4444", fontSize: "14px" }, children: error });
813
+ }
814
+ if (!stripePromise || !clientSecret) {
815
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { padding: "20px", textAlign: "center", color: "#6b7280" }, children: "Initializing payment..." });
816
+ }
817
+ if (variant === "embedded") {
818
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx(
819
+ reactStripeJs.EmbeddedCheckoutProvider,
820
+ {
821
+ stripe: stripePromise,
822
+ options: {
823
+ clientSecret,
824
+ onComplete: () => {
825
+ tracker.track("purchase.complete", {
826
+ amount: product?.rawPrice ? product.rawPrice / 100 : 0,
827
+ currency: product?.currencyCode || "USD"
828
+ });
829
+ onSuccess?.();
830
+ }
831
+ },
832
+ children: /* @__PURE__ */ jsxRuntime.jsx(reactStripeJs.EmbeddedCheckout, {})
610
833
  }
611
- setStripePromise(stripeJs.loadStripe(result.publishableKey));
612
- setClientSecret(result.clientSecret);
613
- variableStore.set("user.stripeCustomerId", result.customerId);
614
- tracker.track("checkout.start", {
615
- productId: product.id,
616
- priceId: product.stripePriceId || product.storePriceId,
617
- productName: product.displayName
618
- });
619
- } catch (err) {
620
- const msg = err instanceof Error ? err.message : "Failed to initialize payment";
621
- setError(msg);
622
- variableStore.set("payment.error", msg);
623
- } finally {
624
- setIsLoading(false);
625
- variableStore.set("payment.loading", false);
626
- }
834
+ ) });
835
+ }
836
+ const defaultAppearance = {
837
+ theme: "stripe",
838
+ variables: { colorPrimary: "#3b82f6", borderRadius: "8px" }
627
839
  };
628
- createIntent();
629
- }, [email, campaignId, product, paymentMode, validateOnly, tracker, variableStore, apiBaseUrl]);
630
- if (isLoading) {
631
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { padding: "20px", textAlign: "center", color: "#6b7280" }, children: "Loading payment form..." });
632
- }
633
- if (!email) {
634
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { padding: "20px", textAlign: "center", color: "#ef4444", fontSize: "14px" }, children: "Email is required to initialize payment" });
635
- }
636
- if (error) {
637
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { padding: "20px", textAlign: "center", color: "#ef4444", fontSize: "14px" }, children: error });
638
- }
639
- if (!stripePromise || !clientSecret) {
640
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { padding: "20px", textAlign: "center", color: "#6b7280" }, children: "Initializing payment..." });
840
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx(reactStripeJs.Elements, { stripe: stripePromise, options: { clientSecret, appearance: appearance || defaultAppearance }, children: /* @__PURE__ */ jsxRuntime.jsx(
841
+ InnerPaymentForm,
842
+ {
843
+ ref,
844
+ paymentMode,
845
+ validateOnly,
846
+ onSuccess,
847
+ onError,
848
+ onReady,
849
+ layout
850
+ }
851
+ ) }) });
641
852
  }
642
- const defaultAppearance = {
643
- theme: "stripe",
644
- variables: { colorPrimary: "#3b82f6", borderRadius: "8px" }
645
- };
646
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx(reactStripeJs.Elements, { stripe: stripePromise, options: { clientSecret, appearance: appearance || defaultAppearance }, children: /* @__PURE__ */ jsxRuntime.jsx(
647
- InnerPaymentForm,
648
- {
649
- paymentMode,
650
- validateOnly,
651
- onSuccess,
652
- onError
653
- }
654
- ) }) });
655
- }
853
+ );
656
854
  function PaddleCheckout({
657
855
  productId,
658
856
  mode = "overlay",
@@ -660,7 +858,7 @@ function PaddleCheckout({
660
858
  onError,
661
859
  className
662
860
  }) {
663
- const { variableStore, tracker, products } = useFunnelContext();
861
+ const { variableStore, tracker, products } = chunkEVUYCLVY_cjs.useFunnelContext();
664
862
  const containerRef = react.useRef(null);
665
863
  const initializedRef = react.useRef(false);
666
864
  const product = productId ? products.find((p) => p.id === productId) : products.find((p) => p.id === variableStore.get("products.selectedProductId"));
@@ -717,21 +915,42 @@ function PaddleCheckout({
717
915
  return null;
718
916
  }
719
917
 
918
+ Object.defineProperty(exports, "useNavigation", {
919
+ enumerable: true,
920
+ get: function () { return chunkXP44I2MU_cjs.useNavigation; }
921
+ });
922
+ Object.defineProperty(exports, "useResponse", {
923
+ enumerable: true,
924
+ get: function () { return chunkXP44I2MU_cjs.useResponse; }
925
+ });
926
+ Object.defineProperty(exports, "useResponses", {
927
+ enumerable: true,
928
+ get: function () { return chunkXP44I2MU_cjs.useResponses; }
929
+ });
930
+ Object.defineProperty(exports, "FunnelProvider", {
931
+ enumerable: true,
932
+ get: function () { return chunkEVUYCLVY_cjs.FunnelProvider; }
933
+ });
934
+ Object.defineProperty(exports, "registerIntegration", {
935
+ enumerable: true,
936
+ get: function () { return chunkEVUYCLVY_cjs.registerIntegration; }
937
+ });
720
938
  exports.PaddleCheckout = PaddleCheckout;
721
- exports.PaymentForm = PaymentForm;
939
+ exports.StripePaymentForm = StripePaymentForm;
722
940
  exports.defineConfig = defineConfig;
723
941
  exports.definePage = definePage;
724
- exports.registerIntegration = registerIntegration;
725
942
  exports.useData = useData;
943
+ exports.useDateOfBirth = useDateOfBirth;
944
+ exports.useDeviceInfo = useDeviceInfo;
726
945
  exports.useFunnel = useFunnel;
946
+ exports.useKeyboard = useKeyboard;
727
947
  exports.useLocale = useLocale;
728
- exports.useNavigation = useNavigation;
948
+ exports.usePageData = usePageData;
729
949
  exports.usePayment = usePayment;
730
950
  exports.useProducts = useProducts;
731
951
  exports.useQueryParam = useQueryParam;
732
952
  exports.useQueryParams = useQueryParams;
733
- exports.useResponse = useResponse;
734
- exports.useResponses = useResponses;
953
+ exports.useSafeArea = useSafeArea;
735
954
  exports.useTracking = useTracking;
736
955
  exports.useTranslation = useTranslation;
737
956
  exports.useUser = useUser;