@appfunnel-dev/sdk 2.0.0-canary.5 → 2.0.0-canary.7

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,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkG44BUG6G_cjs = require('./chunk-G44BUG6G.cjs');
3
+ var chunkBPOAWI4G_cjs = require('./chunk-BPOAWI4G.cjs');
4
4
  var chunkWYUDL4FI_cjs = require('./chunk-WYUDL4FI.cjs');
5
5
  var chunkQMAZGLGV_cjs = require('./chunk-QMAZGLGV.cjs');
6
6
  require('./chunk-EMMSS5I5.cjs');
@@ -392,7 +392,9 @@ function createBus(accessors, now2 = () => Date.now()) {
392
392
  const currentNav = () => {
393
393
  if (!nav && !warnedNoNav) {
394
394
  warnedNoNav = true;
395
- console.warn("[appfunnel] window.appfunnel navigation called before the funnel flow mounted \u2014 ignored");
395
+ console.warn(
396
+ "[appfunnel] window.appfunnel navigation called before the funnel flow mounted \u2014 ignored"
397
+ );
396
398
  }
397
399
  return nav;
398
400
  };
@@ -407,7 +409,18 @@ function createBus(accessors, now2 = () => Date.now()) {
407
409
  const goNext = () => currentNav()?.goNext();
408
410
  const goPrevious = () => currentNav()?.goPrevious();
409
411
  const navigation = () => nav?.snapshot() ?? null;
410
- return { on, off, events, emit, registerNavigation, goTo, goNext, goPrevious, navigation, ...accessors };
412
+ return {
413
+ on,
414
+ off,
415
+ events,
416
+ emit,
417
+ registerNavigation,
418
+ goTo,
419
+ goNext,
420
+ goPrevious,
421
+ navigation,
422
+ ...accessors
423
+ };
411
424
  }
412
425
  function withBus(tracker, bus) {
413
426
  return {
@@ -491,9 +504,9 @@ function LocaleProvider({
491
504
  override,
492
505
  children
493
506
  }) {
494
- const [locale, setLocale] = React.useState(() => chunkG44BUG6G_cjs.resolveLocale(config, detected, override));
507
+ const [locale, setLocale] = React.useState(() => chunkBPOAWI4G_cjs.resolveLocale(config, detected, override));
495
508
  React.useEffect(() => {
496
- setLocale(chunkG44BUG6G_cjs.resolveLocale(config, detected, override));
509
+ setLocale(chunkBPOAWI4G_cjs.resolveLocale(config, detected, override));
497
510
  }, [config, detected, override]);
498
511
  const value = React.useMemo(
499
512
  () => ({ locale, setLocale, config, catalog }),
@@ -565,7 +578,7 @@ function useTranslation() {
565
578
  fmt,
566
579
  locale,
567
580
  setLocale,
568
- dir: chunkG44BUG6G_cjs.isRtl(locale) ? "rtl" : "ltr",
581
+ dir: chunkBPOAWI4G_cjs.isRtl(locale) ? "rtl" : "ltr",
569
582
  locales: config?.supported ?? [locale]
570
583
  };
571
584
  }
@@ -582,17 +595,20 @@ function useCatalog() {
582
595
  return React.useContext(CatalogContext) ?? EMPTY;
583
596
  }
584
597
  var EMPTY = /* @__PURE__ */ new Map();
585
- function useProduct(id) {
598
+ function useOffering(id) {
586
599
  const catalog = useCatalog();
587
600
  const locale = useActiveLocale();
588
601
  const resolved = id ? catalog.get(id) : void 0;
589
- return React.useMemo(() => resolved ? chunkG44BUG6G_cjs.formatProduct(resolved, locale) : void 0, [resolved, locale]);
602
+ return React.useMemo(
603
+ () => resolved ? chunkBPOAWI4G_cjs.formatOffering(resolved, locale) : void 0,
604
+ [resolved, locale]
605
+ );
590
606
  }
591
- function useProducts() {
607
+ function useOfferings() {
592
608
  const catalog = useCatalog();
593
609
  const locale = useActiveLocale();
594
610
  return React.useMemo(
595
- () => Array.from(catalog.values()).map((r) => chunkG44BUG6G_cjs.formatProduct(r, locale)),
611
+ () => Array.from(catalog.values()).map((r) => chunkBPOAWI4G_cjs.formatOffering(r, locale)),
596
612
  [catalog, locale]
597
613
  );
598
614
  }
@@ -770,10 +786,10 @@ function FunnelView({
770
786
  [pages]
771
787
  );
772
788
  const seedRef = React.useRef(null);
773
- if (seedRef.current === null) seedRef.current = chunkG44BUG6G_cjs.bucketingSeed(funnel.context);
789
+ if (seedRef.current === null) seedRef.current = chunkBPOAWI4G_cjs.bucketingSeed(funnel.context);
774
790
  const seed = seedRef.current;
775
791
  const experiments = React.useMemo(
776
- () => chunkG44BUG6G_cjs.resolveExperiments(pages, funnel.experiments, seed),
792
+ () => chunkBPOAWI4G_cjs.resolveExperiments(pages, funnel.experiments, seed),
777
793
  [pages, funnel.experiments, seed]
778
794
  );
779
795
  const toSlot = React.useCallback((k) => experiments.slotOf[k] ?? k, [experiments]);
@@ -784,8 +800,12 @@ function FunnelView({
784
800
  [experiments, pageByKey]
785
801
  );
786
802
  const flow = React.useMemo(
787
- () => flowPages.map((p) => ({ key: p.key, meta: p.meta })),
788
- [flowPages]
803
+ () => flowPages.map((p) => {
804
+ const servedVariant = experiments.render[p.key];
805
+ const variantNext = servedVariant ? pageByKey.get(servedVariant)?.meta?.next : void 0;
806
+ return variantNext ? { key: p.key, meta: { ...p.meta ?? {}, next: variantNext } } : { key: p.key, meta: p.meta };
807
+ }),
808
+ [flowPages, experiments, pageByKey]
789
809
  );
790
810
  const [history, setHistory] = React.useState(() => {
791
811
  const start = flowPages[0]?.key;
@@ -793,8 +813,8 @@ function FunnelView({
793
813
  const target = toSlot(initialKey);
794
814
  const page2 = flowPages.find((p) => p.key === target);
795
815
  if (trustInitialKey) return page2 ? [target] : start ? [start] : [];
796
- const guard = chunkG44BUG6G_cjs.entryGuard(page2?.meta);
797
- const ok = page2 && (!guard || chunkG44BUG6G_cjs.evaluateGate(guard, funnel.snapshot()));
816
+ const guard = chunkBPOAWI4G_cjs.entryGuard(page2?.meta);
817
+ const ok = page2 && (!guard || chunkBPOAWI4G_cjs.evaluateGate(guard, funnel.snapshot()));
798
818
  const first = ok ? target : start;
799
819
  return first ? [first] : [];
800
820
  });
@@ -802,7 +822,7 @@ function FunnelView({
802
822
  const index = history.length - 1;
803
823
  const startKey = history[0];
804
824
  const total = React.useMemo(
805
- () => chunkG44BUG6G_cjs.expectedPathLength(flow, startKey, funnel.snapshot()),
825
+ () => chunkBPOAWI4G_cjs.expectedPathLength(flow, startKey, funnel.snapshot()),
806
826
  // currentKey in deps: re-trace as each step's answers settle the branch.
807
827
  [flow, startKey, currentKey, funnel]
808
828
  );
@@ -837,7 +857,7 @@ function FunnelView({
837
857
  usePageExitTimer(tracker, currentKey);
838
858
  const [isNavigating, startNav] = React.useTransition();
839
859
  const next = React.useCallback(() => {
840
- const target = chunkG44BUG6G_cjs.nextPage(flow, currentKey, funnel.snapshot());
860
+ const target = chunkBPOAWI4G_cjs.nextPage(flow, currentKey, funnel.snapshot());
841
861
  const resolved = target ? toSlot(target) : target;
842
862
  if (resolved) startNav(() => setHistory((h) => [...h, resolved]));
843
863
  }, [flow, currentKey, funnel, toSlot]);
@@ -861,7 +881,7 @@ function FunnelView({
861
881
  [loaders, toRenderKey]
862
882
  );
863
883
  const nextCandidates = React.useMemo(
864
- () => [...new Set(chunkG44BUG6G_cjs.outgoingKeys(flow, currentKey).map(toRenderKey))],
884
+ () => [...new Set(chunkBPOAWI4G_cjs.outgoingKeys(flow, currentKey).map(toRenderKey))],
865
885
  [flow, currentKey, toRenderKey]
866
886
  );
867
887
  React.useEffect(() => {
@@ -1009,7 +1029,7 @@ function EmbedBridge() {
1009
1029
  function usePage() {
1010
1030
  return useNavigation().page;
1011
1031
  }
1012
- var symModalId = /* @__PURE__ */ Symbol("AppFunnelModalId");
1032
+ var symModalId = /* @__PURE__ */ Symbol("AppfunnelModalId");
1013
1033
  var initialState = {};
1014
1034
  var ModalStateContext = React.createContext(initialState);
1015
1035
  var ModalIdContext = React.createContext(null);
@@ -1024,7 +1044,9 @@ var runtimeStack = [];
1024
1044
  var dispatch = (action) => {
1025
1045
  const top = runtimeStack[runtimeStack.length - 1];
1026
1046
  if (!top) {
1027
- throw new Error("No modal dispatch \u2014 render inside <FunnelProvider> (which mounts the modal runtime).");
1047
+ throw new Error(
1048
+ "No modal dispatch \u2014 render inside <FunnelProvider> (which mounts the modal runtime)."
1049
+ );
1028
1050
  }
1029
1051
  top(action);
1030
1052
  };
@@ -1123,26 +1145,42 @@ function useModal(modal, args) {
1123
1145
  const d = React.useContext(ModalDispatchContext) ?? dispatch;
1124
1146
  const isComponent = !!modal && typeof modal !== "string";
1125
1147
  const id = modal ? idOf(modal) : contextId;
1126
- if (!id) throw new Error("useModal: no modal id (call inside a defineModal component, or pass an id/component).");
1148
+ if (!id)
1149
+ throw new Error(
1150
+ "useModal: no modal id (call inside a defineModal component, or pass an id/component)."
1151
+ );
1127
1152
  React.useEffect(() => {
1128
- if (isComponent && !REGISTRY[id]) registerModal(id, modal, args);
1153
+ if (isComponent && !REGISTRY[id])
1154
+ registerModal(id, modal, args);
1129
1155
  }, [isComponent, id, modal, args]);
1130
1156
  const info = modals[id];
1131
- const show = React.useCallback((a) => showModalVia(d, id, a), [d, id]);
1157
+ const show = React.useCallback(
1158
+ (a) => showModalVia(d, id, a),
1159
+ [d, id]
1160
+ );
1132
1161
  const hide = React.useCallback(() => hideModalVia(d, id), [d, id]);
1133
1162
  const remove = React.useCallback(() => removeModalVia(d, id), [d, id]);
1134
- const resolve = React.useCallback((v) => {
1135
- modalCallbacks[id]?.resolve(v);
1136
- delete modalCallbacks[id];
1137
- }, [id]);
1138
- const reject = React.useCallback((v) => {
1139
- modalCallbacks[id]?.reject(v);
1140
- delete modalCallbacks[id];
1141
- }, [id]);
1142
- const resolveHide = React.useCallback((v) => {
1143
- hideCallbacks[id]?.resolve(v);
1144
- delete hideCallbacks[id];
1145
- }, [id]);
1163
+ const resolve = React.useCallback(
1164
+ (v) => {
1165
+ modalCallbacks[id]?.resolve(v);
1166
+ delete modalCallbacks[id];
1167
+ },
1168
+ [id]
1169
+ );
1170
+ const reject = React.useCallback(
1171
+ (v) => {
1172
+ modalCallbacks[id]?.reject(v);
1173
+ delete modalCallbacks[id];
1174
+ },
1175
+ [id]
1176
+ );
1177
+ const resolveHide = React.useCallback(
1178
+ (v) => {
1179
+ hideCallbacks[id]?.resolve(v);
1180
+ delete hideCallbacks[id];
1181
+ },
1182
+ [id]
1183
+ );
1146
1184
  return React.useMemo(
1147
1185
  () => ({
1148
1186
  id,
@@ -1156,11 +1194,27 @@ function useModal(modal, args) {
1156
1194
  reject,
1157
1195
  resolveHide
1158
1196
  }),
1159
- [id, info?.args, info?.visible, info?.keepMounted, show, hide, remove, resolve, reject, resolveHide]
1197
+ [
1198
+ id,
1199
+ info?.args,
1200
+ info?.visible,
1201
+ info?.keepMounted,
1202
+ show,
1203
+ hide,
1204
+ remove,
1205
+ resolve,
1206
+ reject,
1207
+ resolveHide
1208
+ ]
1160
1209
  );
1161
1210
  }
1162
1211
  function defineModal(Comp) {
1163
- return function Wrapped({ id, defaultVisible, keepMounted, ...props }) {
1212
+ return function Wrapped({
1213
+ id,
1214
+ defaultVisible,
1215
+ keepMounted,
1216
+ ...props
1217
+ }) {
1164
1218
  const { args, show } = useModal(id);
1165
1219
  const modals = React.useContext(ModalStateContext);
1166
1220
  const d = React.useContext(ModalDispatchContext) ?? dispatch;
@@ -1193,7 +1247,9 @@ function ModalRoot() {
1193
1247
  return React.createElement(
1194
1248
  "div",
1195
1249
  { "data-appfunnel-modal-root": "" },
1196
- ...toRender.map((t) => React.createElement(t.comp, { key: t.id, id: t.id, ...t.props }))
1250
+ ...toRender.map(
1251
+ (t) => React.createElement(t.comp, { key: t.id, id: t.id, ...t.props })
1252
+ )
1197
1253
  );
1198
1254
  }
1199
1255
  function ModalRuntime({ children }) {
@@ -1321,12 +1377,20 @@ function Modal(props) {
1321
1377
 
1322
1378
  // src/commerce/checkout.tsx
1323
1379
  function createMockDriver(provider = "stripe", options = {}) {
1324
- const success = options.result ?? { ok: true, amountMinor: 0, currency: "USD" };
1325
- const offError = typeof options.failOffSession === "object" ? options.failOffSession : chunkQMAZGLGV_cjs.checkoutError("authentication_required", "off-session charge declined (mock)");
1380
+ const success = options.result ?? {
1381
+ ok: true,
1382
+ amountMinor: 0,
1383
+ currency: "USD"
1384
+ };
1385
+ const offError = typeof options.failOffSession === "object" ? options.failOffSession : chunkQMAZGLGV_cjs.checkoutError(
1386
+ "authentication_required",
1387
+ "off-session charge declined (mock)"
1388
+ );
1326
1389
  return {
1327
1390
  provider,
1328
1391
  start: (req) => {
1329
- if (options.failOffSession && !req.surface) return Promise.resolve({ ok: false, error: offError });
1392
+ if (options.failOffSession && !req.surface)
1393
+ return Promise.resolve({ ok: false, error: offError });
1330
1394
  return Promise.resolve(success);
1331
1395
  },
1332
1396
  renderInline: (req, cb) => React.createElement(
@@ -1337,7 +1401,13 @@ function createMockDriver(provider = "stripe", options = {}) {
1337
1401
  onClick: () => {
1338
1402
  cb.onStart?.();
1339
1403
  if (success.ok) cb.onSuccess(success);
1340
- else cb.onError(success.error ?? chunkQMAZGLGV_cjs.checkoutError("processing_error", "failed (mock)"));
1404
+ else
1405
+ cb.onError(
1406
+ success.error ?? chunkQMAZGLGV_cjs.checkoutError(
1407
+ "processing_error",
1408
+ "failed (mock)"
1409
+ )
1410
+ );
1341
1411
  }
1342
1412
  },
1343
1413
  `Pay (mock ${req.surface})`
@@ -1395,11 +1465,11 @@ function useCheckout(opts = {}) {
1395
1465
  [catalog, kind]
1396
1466
  );
1397
1467
  const recovering = React.useRef(false);
1398
- const failRef = React.useRef(() => {
1399
- });
1400
- const attemptRef = React.useRef(
1401
- async () => ({ ok: false })
1468
+ const failRef = React.useRef(
1469
+ () => {
1470
+ }
1402
1471
  );
1472
+ const attemptRef = React.useRef(async () => ({ ok: false }));
1403
1473
  const succeed = React.useCallback(
1404
1474
  (result, product) => {
1405
1475
  setStatus("success");
@@ -1413,7 +1483,12 @@ function useCheckout(opts = {}) {
1413
1483
  // server-minted (browser↔CAPI dedup); undefined if none
1414
1484
  });
1415
1485
  if (isSubscription) {
1416
- tracker.track("subscription.created", { amount, currency: result.currency, productId, eventId: result.eventId });
1486
+ tracker.track("subscription.created", {
1487
+ amount,
1488
+ currency: result.currency,
1489
+ productId,
1490
+ eventId: result.eventId
1491
+ });
1417
1492
  }
1418
1493
  opts.onSuccess?.(result);
1419
1494
  if (advance) nav.next();
@@ -1427,14 +1502,25 @@ function useCheckout(opts = {}) {
1427
1502
  setStatus("loading");
1428
1503
  setError(null);
1429
1504
  const { productId, amount, currency } = productFacts(product);
1430
- tracker.track("checkout.start", { productId, amount, currency, surface, eventId: newEventId() });
1505
+ tracker.track("checkout.start", {
1506
+ productId,
1507
+ amount,
1508
+ currency,
1509
+ surface,
1510
+ eventId: newEventId()
1511
+ });
1431
1512
  },
1432
1513
  [tracker, productFacts]
1433
1514
  );
1434
1515
  const paymentAdded = React.useCallback(
1435
1516
  (product) => {
1436
1517
  const { productId, amount, currency } = productFacts(product);
1437
- tracker.track("checkout.payment_added", { productId, amount, currency, eventId: newEventId() });
1518
+ tracker.track("checkout.payment_added", {
1519
+ productId,
1520
+ amount,
1521
+ currency,
1522
+ eventId: newEventId()
1523
+ });
1438
1524
  },
1439
1525
  [tracker, productFacts]
1440
1526
  );
@@ -1457,7 +1543,9 @@ function useCheckout(opts = {}) {
1457
1543
  }
1458
1544
  };
1459
1545
  failRef.current = (err, product) => {
1460
- setStatus(err.category === "authentication_required" ? "requires_action" : "error");
1546
+ setStatus(
1547
+ err.category === "authentication_required" ? "requires_action" : "error"
1548
+ );
1461
1549
  setError(err);
1462
1550
  tracker.track("checkout.failed", {
1463
1551
  category: err.category,
@@ -1488,35 +1576,59 @@ function useCheckout(opts = {}) {
1488
1576
  if (!product) return;
1489
1577
  recovering.current = true;
1490
1578
  if (!surface) {
1491
- if (intent === "upsell") void attemptRef.current(product);
1492
- else startRecovery(product, chunkQMAZGLGV_cjs.PROVIDER_PROFILES[driver.provider]?.surfaces.sheet ? "sheet" : "popup");
1579
+ if (intent === "upsell")
1580
+ void attemptRef.current(product);
1581
+ else
1582
+ startRecovery(
1583
+ product,
1584
+ chunkQMAZGLGV_cjs.PROVIDER_PROFILES[driver.provider]?.surfaces.sheet ? "sheet" : "popup"
1585
+ );
1493
1586
  return;
1494
1587
  }
1495
1588
  startRecovery(product, surface);
1496
1589
  }
1497
1590
  };
1498
- void showModal(route.modal, props);
1591
+ void showModal(
1592
+ route.modal,
1593
+ props
1594
+ );
1499
1595
  } else if ("fallback" in route) {
1500
- if (product && !recovering.current) startRecovery(product, route.fallback);
1596
+ if (product && !recovering.current)
1597
+ startRecovery(product, route.fallback);
1501
1598
  }
1502
1599
  };
1503
1600
  attemptRef.current = async (product, surface) => {
1504
1601
  begin(product, surface);
1505
1602
  try {
1506
- const result = await driver.start({ product, intent, surface, kind });
1603
+ const result = await driver.start({
1604
+ product,
1605
+ intent,
1606
+ surface,
1607
+ kind
1608
+ });
1507
1609
  if (result.ok) succeedRef.current(result, product);
1508
- else failRef.current(result.error ?? chunkQMAZGLGV_cjs.checkoutError("unknown", "Checkout failed"), product);
1610
+ else
1611
+ failRef.current(
1612
+ result.error ?? chunkQMAZGLGV_cjs.checkoutError("unknown", "Checkout failed"),
1613
+ product
1614
+ );
1509
1615
  return result;
1510
1616
  } catch (e) {
1511
- const err = chunkQMAZGLGV_cjs.checkoutError("processing_error", e instanceof Error ? e.message : "Checkout failed");
1617
+ const err = chunkQMAZGLGV_cjs.checkoutError(
1618
+ "processing_error",
1619
+ e instanceof Error ? e.message : "Checkout failed"
1620
+ );
1512
1621
  failRef.current(err, product);
1513
1622
  return { ok: false, error: err };
1514
1623
  }
1515
1624
  };
1516
- const open = React.useCallback(async (product, surface) => {
1517
- recovering.current = false;
1518
- return attemptRef.current(product, surface);
1519
- }, []);
1625
+ const open = React.useCallback(
1626
+ async (product, surface) => {
1627
+ recovering.current = false;
1628
+ return attemptRef.current(product, surface);
1629
+ },
1630
+ []
1631
+ );
1520
1632
  const callbacksFor = React.useCallback(
1521
1633
  (product, surface) => ({
1522
1634
  onStart: () => {
@@ -1534,7 +1646,14 @@ function useCheckout(opts = {}) {
1534
1646
  setStatus("idle");
1535
1647
  setError(null);
1536
1648
  }, []);
1537
- return { open, status, error, isLoading: status === "loading", reset, callbacksFor };
1649
+ return {
1650
+ open,
1651
+ status,
1652
+ error,
1653
+ isLoading: status === "loading",
1654
+ reset,
1655
+ callbacksFor
1656
+ };
1538
1657
  }
1539
1658
  var CheckoutSheet = defineModal(({ product, surface, intent, kind, onSuccess, onError, onPaymentAdded }) => {
1540
1659
  const driver = useDriver();
@@ -1547,7 +1666,10 @@ var CheckoutSheet = defineModal(({ product, surface, intent, kind, onSuccess, on
1547
1666
  if (!hostable) {
1548
1667
  resolved.current = true;
1549
1668
  onErrorRef.current(
1550
- chunkQMAZGLGV_cjs.checkoutError("processing_error", "This checkout driver has no inline surface to host in the sheet")
1669
+ chunkQMAZGLGV_cjs.checkoutError(
1670
+ "processing_error",
1671
+ "This checkout driver has no inline surface to host in the sheet"
1672
+ )
1551
1673
  );
1552
1674
  void modal.hide();
1553
1675
  modal.remove();
@@ -1555,7 +1677,12 @@ var CheckoutSheet = defineModal(({ product, surface, intent, kind, onSuccess, on
1555
1677
  }
1556
1678
  return () => {
1557
1679
  if (!resolved.current) {
1558
- onErrorRef.current(chunkQMAZGLGV_cjs.checkoutError("canceled", "Checkout was dismissed before completing"));
1680
+ onErrorRef.current(
1681
+ chunkQMAZGLGV_cjs.checkoutError(
1682
+ "canceled",
1683
+ "Checkout was dismissed before completing"
1684
+ )
1685
+ );
1559
1686
  }
1560
1687
  };
1561
1688
  }, []);
@@ -1582,21 +1709,31 @@ var CheckoutSheet = defineModal(({ product, surface, intent, kind, onSuccess, on
1582
1709
  )
1583
1710
  });
1584
1711
  });
1585
- function trigger(onClick, { asChild, children, className, disabled }) {
1712
+ function trigger(onClick, {
1713
+ asChild,
1714
+ children,
1715
+ className,
1716
+ disabled
1717
+ }) {
1586
1718
  if (asChild && React.isValidElement(children)) {
1587
1719
  const child = children;
1588
1720
  return React.cloneElement(child, { onClick });
1589
1721
  }
1590
- return React.createElement("button", { type: "button", className, disabled, onClick }, children ?? "Continue");
1722
+ return React.createElement(
1723
+ "button",
1724
+ { type: "button", className, disabled, onClick },
1725
+ children ?? "Continue"
1726
+ );
1591
1727
  }
1592
1728
  function Checkout({
1593
- product,
1729
+ offering,
1594
1730
  surface,
1595
1731
  asChild,
1596
1732
  children,
1597
1733
  className,
1598
1734
  ...options
1599
1735
  }) {
1736
+ const product = offering;
1600
1737
  const driver = useDriver();
1601
1738
  const checkout = useCheckout(options);
1602
1739
  const intent = options.intent ?? "purchase";
@@ -1604,7 +1741,10 @@ function Checkout({
1604
1741
  return driver.renderInline ? React.createElement(
1605
1742
  "div",
1606
1743
  { key: product, className },
1607
- driver.renderInline({ product, intent, surface }, checkout.callbacksFor(product, surface))
1744
+ driver.renderInline(
1745
+ { product, intent, surface },
1746
+ checkout.callbacksFor(product, surface)
1747
+ )
1608
1748
  ) : null;
1609
1749
  }
1610
1750
  if (surface === "sheet") {
@@ -1621,7 +1761,12 @@ function Checkout({
1621
1761
  onPaymentAdded: cb.onPaymentAdded
1622
1762
  });
1623
1763
  };
1624
- return trigger(open, { asChild, children, className, disabled: checkout.isLoading });
1764
+ return trigger(open, {
1765
+ asChild,
1766
+ children,
1767
+ className,
1768
+ disabled: checkout.isLoading
1769
+ });
1625
1770
  }
1626
1771
  return trigger(() => checkout.open(product, surface), {
1627
1772
  asChild,
@@ -1630,18 +1775,29 @@ function Checkout({
1630
1775
  disabled: checkout.isLoading
1631
1776
  });
1632
1777
  }
1633
- function Upsell({ product, fallback, asChild, children, className, ...options }) {
1778
+ function Upsell({
1779
+ offering,
1780
+ fallback,
1781
+ asChild,
1782
+ children,
1783
+ className,
1784
+ ...options
1785
+ }) {
1786
+ const product = offering;
1634
1787
  const checkout = useCheckout({
1635
1788
  ...options,
1636
1789
  intent: "upsell",
1637
1790
  recoverySurface: fallback ?? options.recoverySurface
1638
1791
  });
1639
- return trigger(() => void checkout.open(product), {
1640
- asChild,
1641
- children: children ?? "Add to my plan",
1642
- className,
1643
- disabled: checkout.isLoading
1644
- });
1792
+ return trigger(
1793
+ () => void checkout.open(product),
1794
+ {
1795
+ asChild,
1796
+ children: children ?? "Add to my plan",
1797
+ className,
1798
+ disabled: checkout.isLoading
1799
+ }
1800
+ );
1645
1801
  }
1646
1802
  var consumedResumes = /* @__PURE__ */ new Set();
1647
1803
  function CheckoutResume(options = {}) {
@@ -1659,10 +1815,19 @@ function CheckoutResume(options = {}) {
1659
1815
  const cb = callbacksRef.current();
1660
1816
  if (result.ok) {
1661
1817
  url.searchParams.delete("af_checkout");
1662
- window.history.replaceState(window.history.state, "", url.toString());
1818
+ window.history.replaceState(
1819
+ window.history.state,
1820
+ "",
1821
+ url.toString()
1822
+ );
1663
1823
  cb.onSuccess(result);
1664
1824
  } else {
1665
- cb.onError(result.error ?? chunkQMAZGLGV_cjs.checkoutError("unknown", "The checkout could not be verified"));
1825
+ cb.onError(
1826
+ result.error ?? chunkQMAZGLGV_cjs.checkoutError(
1827
+ "unknown",
1828
+ "The checkout could not be verified"
1829
+ )
1830
+ );
1666
1831
  }
1667
1832
  });
1668
1833
  }, []);
@@ -2777,7 +2942,8 @@ var Namespace = class {
2777
2942
  const out = {};
2778
2943
  const all = this.store.getState();
2779
2944
  for (const key in all) {
2780
- if (key.startsWith(this.dot)) out[key.slice(this.dot.length)] = all[key];
2945
+ if (key.startsWith(this.dot))
2946
+ out[key.slice(this.dot.length)] = all[key];
2781
2947
  }
2782
2948
  return out;
2783
2949
  }
@@ -2826,7 +2992,7 @@ function FunnelProvider({
2826
2992
  deferSessionValues = false,
2827
2993
  tracker,
2828
2994
  context: contextOpts,
2829
- products,
2995
+ offerings,
2830
2996
  experiments,
2831
2997
  checkout,
2832
2998
  messages,
@@ -2862,7 +3028,7 @@ function FunnelProvider({
2862
3028
  const value2 = s.get("user.email");
2863
3029
  return typeof value2 === "string" && /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(value2) ? value2 : void 0;
2864
3030
  };
2865
- const catalog = chunkG44BUG6G_cjs.buildCatalog(products ?? []);
3031
+ const catalog = chunkBPOAWI4G_cjs.buildCatalog(offerings ?? []);
2866
3032
  return {
2867
3033
  funnel: createFunnel(s, ctx, busTracker, experiments ?? []),
2868
3034
  store: s,
@@ -2870,7 +3036,13 @@ function FunnelProvider({
2870
3036
  catalog,
2871
3037
  // Slot → catalog-key resolution wraps the email-enriching driver, so the wire charges the real
2872
3038
  // catalog key while pages + analytics keep the durable SLOT identity (req.product).
2873
- driver: driverWithCatalog(driverWithEmail(checkout ?? createMockDriver(), emailForCheckout), catalog),
3039
+ driver: driverWithCatalog(
3040
+ driverWithEmail(
3041
+ checkout ?? createMockDriver(),
3042
+ emailForCheckout
3043
+ ),
3044
+ catalog
3045
+ ),
2874
3046
  tracker: busTracker,
2875
3047
  bus
2876
3048
  };
@@ -2879,7 +3051,8 @@ function FunnelProvider({
2879
3051
  React.useEffect(() => {
2880
3052
  if (!deferSessionValues || !sessionValues) return;
2881
3053
  const updates = {};
2882
- for (const [key, v] of Object.entries(sessionValues)) if (v !== void 0) updates[key] = v;
3054
+ for (const [key, v] of Object.entries(sessionValues))
3055
+ if (v !== void 0) updates[key] = v;
2883
3056
  if (Object.keys(updates).length > 0) value.store.setMany(updates);
2884
3057
  }, []);
2885
3058
  React.useEffect(() => {
@@ -2910,7 +3083,9 @@ var FALLBACK_TRACKER = createConsoleTracker({ silent: true });
2910
3083
  function useFunnelCtx() {
2911
3084
  const ctx = React.useContext(FunnelCtx);
2912
3085
  if (!ctx) {
2913
- throw new Error("useFunnel/useResponse/\u2026 must be used inside <FunnelProvider>");
3086
+ throw new Error(
3087
+ "useFunnel/useResponse/\u2026 must be used inside <FunnelProvider>"
3088
+ );
2914
3089
  }
2915
3090
  return ctx;
2916
3091
  }
@@ -2948,7 +3123,9 @@ function useField(path) {
2948
3123
  const key = path.slice(dot + 1);
2949
3124
  const { funnel, store } = useFunnelCtx();
2950
3125
  if (!(ns in NAMESPACE_PREFIX)) {
2951
- throw new Error(`useField: "${path}" is not a writable namespace (user/responses/data)`);
3126
+ throw new Error(
3127
+ `useField: "${path}" is not a writable namespace (user/responses/data)`
3128
+ );
2952
3129
  }
2953
3130
  const value = useStoreKey(store, `${NAMESPACE_PREFIX[ns]}.${key}`);
2954
3131
  const set = React.useCallback(
@@ -2978,7 +3155,10 @@ function useSystem() {
2978
3155
  function useContextValue(path) {
2979
3156
  const ctx = useContextObject();
2980
3157
  return React.useMemo(
2981
- () => path.split(".").reduce((acc, k) => acc?.[k], ctx),
3158
+ () => path.split(".").reduce(
3159
+ (acc, k) => acc?.[k],
3160
+ ctx
3161
+ ),
2982
3162
  [ctx, path]
2983
3163
  );
2984
3164
  }
@@ -3335,7 +3515,7 @@ function createFunnelTree({
3335
3515
  assets: opts.assets,
3336
3516
  children: React.createElement(FunnelProvider, {
3337
3517
  config,
3338
- products: opts.products ?? [],
3518
+ offerings: opts.offerings ?? [],
3339
3519
  messages: opts.messages ?? messages,
3340
3520
  locale: opts.locale,
3341
3521
  tracker,
@@ -3508,111 +3688,107 @@ function Script({
3508
3688
 
3509
3689
  Object.defineProperty(exports, "assignVariant", {
3510
3690
  enumerable: true,
3511
- get: function () { return chunkG44BUG6G_cjs.assignVariant; }
3691
+ get: function () { return chunkBPOAWI4G_cjs.assignVariant; }
3512
3692
  });
3513
3693
  Object.defineProperty(exports, "bucketingSeed", {
3514
3694
  enumerable: true,
3515
- get: function () { return chunkG44BUG6G_cjs.bucketingSeed; }
3695
+ get: function () { return chunkBPOAWI4G_cjs.bucketingSeed; }
3516
3696
  });
3517
3697
  Object.defineProperty(exports, "buildCatalog", {
3518
3698
  enumerable: true,
3519
- get: function () { return chunkG44BUG6G_cjs.buildCatalog; }
3699
+ get: function () { return chunkBPOAWI4G_cjs.buildCatalog; }
3520
3700
  });
3521
3701
  Object.defineProperty(exports, "compileManifest", {
3522
3702
  enumerable: true,
3523
- get: function () { return chunkG44BUG6G_cjs.compileManifest; }
3703
+ get: function () { return chunkBPOAWI4G_cjs.compileManifest; }
3524
3704
  });
3525
3705
  Object.defineProperty(exports, "currencyExponent", {
3526
3706
  enumerable: true,
3527
- get: function () { return chunkG44BUG6G_cjs.currencyExponent; }
3707
+ get: function () { return chunkBPOAWI4G_cjs.currencyExponent; }
3528
3708
  });
3529
3709
  Object.defineProperty(exports, "defineFunnel", {
3530
3710
  enumerable: true,
3531
- get: function () { return chunkG44BUG6G_cjs.defineFunnel; }
3711
+ get: function () { return chunkBPOAWI4G_cjs.defineFunnel; }
3532
3712
  });
3533
3713
  Object.defineProperty(exports, "definePage", {
3534
3714
  enumerable: true,
3535
- get: function () { return chunkG44BUG6G_cjs.definePage; }
3715
+ get: function () { return chunkBPOAWI4G_cjs.definePage; }
3536
3716
  });
3537
3717
  Object.defineProperty(exports, "entryGuard", {
3538
3718
  enumerable: true,
3539
- get: function () { return chunkG44BUG6G_cjs.entryGuard; }
3719
+ get: function () { return chunkBPOAWI4G_cjs.entryGuard; }
3540
3720
  });
3541
3721
  Object.defineProperty(exports, "evaluateCondition", {
3542
3722
  enumerable: true,
3543
- get: function () { return chunkG44BUG6G_cjs.evaluateCondition; }
3723
+ get: function () { return chunkBPOAWI4G_cjs.evaluateCondition; }
3544
3724
  });
3545
3725
  Object.defineProperty(exports, "evaluateGate", {
3546
3726
  enumerable: true,
3547
- get: function () { return chunkG44BUG6G_cjs.evaluateGate; }
3727
+ get: function () { return chunkBPOAWI4G_cjs.evaluateGate; }
3548
3728
  });
3549
3729
  Object.defineProperty(exports, "expectedPathLength", {
3550
3730
  enumerable: true,
3551
- get: function () { return chunkG44BUG6G_cjs.expectedPathLength; }
3731
+ get: function () { return chunkBPOAWI4G_cjs.expectedPathLength; }
3552
3732
  });
3553
3733
  Object.defineProperty(exports, "fnv1a", {
3554
3734
  enumerable: true,
3555
- get: function () { return chunkG44BUG6G_cjs.fnv1a; }
3735
+ get: function () { return chunkBPOAWI4G_cjs.fnv1a; }
3556
3736
  });
3557
3737
  Object.defineProperty(exports, "formatMoney", {
3558
3738
  enumerable: true,
3559
- get: function () { return chunkG44BUG6G_cjs.formatMoney; }
3739
+ get: function () { return chunkBPOAWI4G_cjs.formatMoney; }
3560
3740
  });
3561
- Object.defineProperty(exports, "formatProduct", {
3741
+ Object.defineProperty(exports, "formatOffering", {
3562
3742
  enumerable: true,
3563
- get: function () { return chunkG44BUG6G_cjs.formatProduct; }
3743
+ get: function () { return chunkBPOAWI4G_cjs.formatOffering; }
3564
3744
  });
3565
3745
  Object.defineProperty(exports, "hashToUnit", {
3566
3746
  enumerable: true,
3567
- get: function () { return chunkG44BUG6G_cjs.hashToUnit; }
3747
+ get: function () { return chunkBPOAWI4G_cjs.hashToUnit; }
3568
3748
  });
3569
3749
  Object.defineProperty(exports, "isRtl", {
3570
3750
  enumerable: true,
3571
- get: function () { return chunkG44BUG6G_cjs.isRtl; }
3751
+ get: function () { return chunkBPOAWI4G_cjs.isRtl; }
3572
3752
  });
3573
3753
  Object.defineProperty(exports, "isVariantKey", {
3574
3754
  enumerable: true,
3575
- get: function () { return chunkG44BUG6G_cjs.isVariantKey; }
3755
+ get: function () { return chunkBPOAWI4G_cjs.isVariantKey; }
3576
3756
  });
3577
3757
  Object.defineProperty(exports, "nextPage", {
3578
3758
  enumerable: true,
3579
- get: function () { return chunkG44BUG6G_cjs.nextPage; }
3759
+ get: function () { return chunkBPOAWI4G_cjs.nextPage; }
3580
3760
  });
3581
3761
  Object.defineProperty(exports, "outgoingKeys", {
3582
3762
  enumerable: true,
3583
- get: function () { return chunkG44BUG6G_cjs.outgoingKeys; }
3763
+ get: function () { return chunkBPOAWI4G_cjs.outgoingKeys; }
3584
3764
  });
3585
3765
  Object.defineProperty(exports, "pageMeta", {
3586
3766
  enumerable: true,
3587
- get: function () { return chunkG44BUG6G_cjs.pageMeta; }
3767
+ get: function () { return chunkBPOAWI4G_cjs.pageMeta; }
3588
3768
  });
3589
3769
  Object.defineProperty(exports, "parseSlotKey", {
3590
3770
  enumerable: true,
3591
- get: function () { return chunkG44BUG6G_cjs.parseSlotKey; }
3771
+ get: function () { return chunkBPOAWI4G_cjs.parseSlotKey; }
3592
3772
  });
3593
3773
  Object.defineProperty(exports, "pickByWeight", {
3594
3774
  enumerable: true,
3595
- get: function () { return chunkG44BUG6G_cjs.pickByWeight; }
3775
+ get: function () { return chunkBPOAWI4G_cjs.pickByWeight; }
3596
3776
  });
3597
3777
  Object.defineProperty(exports, "resolveExperiments", {
3598
3778
  enumerable: true,
3599
- get: function () { return chunkG44BUG6G_cjs.resolveExperiments; }
3779
+ get: function () { return chunkBPOAWI4G_cjs.resolveExperiments; }
3600
3780
  });
3601
3781
  Object.defineProperty(exports, "resolveLocale", {
3602
3782
  enumerable: true,
3603
- get: function () { return chunkG44BUG6G_cjs.resolveLocale; }
3783
+ get: function () { return chunkBPOAWI4G_cjs.resolveLocale; }
3604
3784
  });
3605
- Object.defineProperty(exports, "resolveProduct", {
3785
+ Object.defineProperty(exports, "resolveOffering", {
3606
3786
  enumerable: true,
3607
- get: function () { return chunkG44BUG6G_cjs.resolveProduct; }
3787
+ get: function () { return chunkBPOAWI4G_cjs.resolveOffering; }
3608
3788
  });
3609
3789
  Object.defineProperty(exports, "resolveRoute", {
3610
3790
  enumerable: true,
3611
- get: function () { return chunkG44BUG6G_cjs.resolveRoute; }
3612
- });
3613
- Object.defineProperty(exports, "validateExperiments", {
3614
- enumerable: true,
3615
- get: function () { return chunkG44BUG6G_cjs.validateExperiments; }
3791
+ get: function () { return chunkBPOAWI4G_cjs.resolveRoute; }
3616
3792
  });
3617
3793
  Object.defineProperty(exports, "INLINE_SURFACES", {
3618
3794
  enumerable: true,
@@ -3701,9 +3877,9 @@ exports.useFunnel = useFunnel;
3701
3877
  exports.useLocale = useLocale;
3702
3878
  exports.useModal = useModal;
3703
3879
  exports.useNavigation = useNavigation;
3880
+ exports.useOffering = useOffering;
3881
+ exports.useOfferings = useOfferings;
3704
3882
  exports.usePage = usePage;
3705
- exports.useProduct = useProduct;
3706
- exports.useProducts = useProducts;
3707
3883
  exports.useResponse = useResponse;
3708
3884
  exports.useSystem = useSystem;
3709
3885
  exports.useTracker = useTracker;