@appfunnel-dev/sdk 2.0.0-canary.5 → 2.0.0-canary.8
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/README.md +1 -1
- package/dist/{capabilities-7_hy5f5G.d.cts → capabilities-CsnkVwna.d.cts} +34 -1
- package/dist/{capabilities-7_hy5f5G.d.ts → capabilities-CsnkVwna.d.ts} +34 -1
- package/dist/{checkout-7Dy6IedP.d.ts → checkout-3PkKwPd7.d.ts} +14 -14
- package/dist/{checkout-Dz8cGkB_.d.cts → checkout-Cg20l53c.d.cts} +14 -14
- package/dist/{chunk-VAOR77NW.cjs → chunk-FY3TMSRU.cjs} +7 -7
- package/dist/{chunk-VAOR77NW.cjs.map → chunk-FY3TMSRU.cjs.map} +1 -1
- package/dist/{chunk-CFFMZYPE.js → chunk-PWXMQGO6.js} +3 -3
- package/dist/{chunk-CFFMZYPE.js.map → chunk-PWXMQGO6.js.map} +1 -1
- package/dist/{chunk-TNLRQPVY.js → chunk-RVJLR4RS.js} +36 -8
- package/dist/chunk-RVJLR4RS.js.map +1 -0
- package/dist/{chunk-QMAZGLGV.cjs → chunk-RY3LOSVZ.cjs} +37 -7
- package/dist/chunk-RY3LOSVZ.cjs.map +1 -0
- package/dist/{chunk-AXXG3ODP.js → chunk-VW2HVPR4.js} +63 -90
- package/dist/chunk-VW2HVPR4.js.map +1 -0
- package/dist/{chunk-G44BUG6G.cjs → chunk-Y4YNJ2EX.cjs} +65 -93
- package/dist/chunk-Y4YNJ2EX.cjs.map +1 -0
- package/dist/driver-paddle.cjs +22 -22
- package/dist/driver-paddle.d.cts +2 -2
- package/dist/driver-paddle.d.ts +2 -2
- package/dist/driver-paddle.js +2 -2
- package/dist/driver-stripe.cjs +264 -212
- package/dist/driver-stripe.cjs.map +1 -1
- package/dist/driver-stripe.d.cts +19 -3
- package/dist/driver-stripe.d.ts +19 -3
- package/dist/driver-stripe.js +244 -193
- package/dist/driver-stripe.js.map +1 -1
- package/dist/index.cjs +310 -134
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -25
- package/dist/index.d.ts +25 -25
- package/dist/index.js +262 -82
- package/dist/index.js.map +1 -1
- package/dist/{manifest-Dl7faaKe.d.cts → manifest-B3Tdab0M.d.cts} +157 -85
- package/dist/{manifest-Dl7faaKe.d.ts → manifest-B3Tdab0M.d.ts} +157 -85
- package/dist/manifest-entry.cjs +118 -49
- package/dist/manifest-entry.cjs.map +1 -1
- package/dist/manifest-entry.d.cts +12 -29
- package/dist/manifest-entry.d.ts +12 -29
- package/dist/manifest-entry.js +79 -14
- package/dist/manifest-entry.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-AXXG3ODP.js.map +0 -1
- package/dist/chunk-G44BUG6G.cjs.map +0 -1
- package/dist/chunk-QMAZGLGV.cjs.map +0 -1
- package/dist/chunk-TNLRQPVY.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { isRtl,
|
|
2
|
-
export { assignVariant, bucketingSeed, buildCatalog, compileManifest, currencyExponent, defineFunnel, definePage, entryGuard, evaluateCondition, evaluateGate, expectedPathLength, fnv1a, formatMoney,
|
|
1
|
+
import { isRtl, formatOffering, bucketingSeed, resolveExperiments, entryGuard, evaluateGate, expectedPathLength, nextPage, outgoingKeys, buildCatalog, resolveLocale } from './chunk-VW2HVPR4.js';
|
|
2
|
+
export { assignVariant, bucketingSeed, buildCatalog, compileManifest, currencyExponent, defineFunnel, definePage, entryGuard, evaluateCondition, evaluateGate, expectedPathLength, fnv1a, formatMoney, formatOffering, hashToUnit, isRtl, isVariantKey, nextPage, outgoingKeys, pageMeta, parseSlotKey, pickByWeight, resolveExperiments, resolveLocale, resolveOffering, resolveRoute } from './chunk-VW2HVPR4.js';
|
|
3
3
|
import { AF_PROTOCOL } from './chunk-ZZJG4EYL.js';
|
|
4
|
-
import { checkoutError, isInlineSurface, PROVIDER_PROFILES } from './chunk-
|
|
5
|
-
export { INLINE_SURFACES, PROVIDER_PROFILES, checkoutError, isInlineSurface, isMerchantOfRecord, isOrchestrator, surfacesFor, validateCheckout, validateUpsell } from './chunk-
|
|
4
|
+
import { checkoutError, isInlineSurface, PROVIDER_PROFILES } from './chunk-RVJLR4RS.js';
|
|
5
|
+
export { INLINE_SURFACES, PROVIDER_PROFILES, checkoutError, isInlineSurface, isMerchantOfRecord, isOrchestrator, surfacesFor, validateCheckout, validateUpsell } from './chunk-RVJLR4RS.js';
|
|
6
6
|
import './chunk-G3PMV62Z.js';
|
|
7
7
|
import React, { createContext, createElement, useCallback, useContext, useMemo, lazy, useRef, useState, useEffect, useTransition, Suspense, Fragment, isValidElement, cloneElement, useReducer, useSyncExternalStore } from 'react';
|
|
8
8
|
import ReactDOM, { createPortal } from 'react-dom';
|
|
@@ -387,7 +387,9 @@ function createBus(accessors, now2 = () => Date.now()) {
|
|
|
387
387
|
const currentNav = () => {
|
|
388
388
|
if (!nav && !warnedNoNav) {
|
|
389
389
|
warnedNoNav = true;
|
|
390
|
-
console.warn(
|
|
390
|
+
console.warn(
|
|
391
|
+
"[appfunnel] window.appfunnel navigation called before the funnel flow mounted \u2014 ignored"
|
|
392
|
+
);
|
|
391
393
|
}
|
|
392
394
|
return nav;
|
|
393
395
|
};
|
|
@@ -402,7 +404,18 @@ function createBus(accessors, now2 = () => Date.now()) {
|
|
|
402
404
|
const goNext = () => currentNav()?.goNext();
|
|
403
405
|
const goPrevious = () => currentNav()?.goPrevious();
|
|
404
406
|
const navigation = () => nav?.snapshot() ?? null;
|
|
405
|
-
return {
|
|
407
|
+
return {
|
|
408
|
+
on,
|
|
409
|
+
off,
|
|
410
|
+
events,
|
|
411
|
+
emit,
|
|
412
|
+
registerNavigation,
|
|
413
|
+
goTo,
|
|
414
|
+
goNext,
|
|
415
|
+
goPrevious,
|
|
416
|
+
navigation,
|
|
417
|
+
...accessors
|
|
418
|
+
};
|
|
406
419
|
}
|
|
407
420
|
function withBus(tracker, bus) {
|
|
408
421
|
return {
|
|
@@ -577,17 +590,20 @@ function useCatalog() {
|
|
|
577
590
|
return useContext(CatalogContext) ?? EMPTY;
|
|
578
591
|
}
|
|
579
592
|
var EMPTY = /* @__PURE__ */ new Map();
|
|
580
|
-
function
|
|
593
|
+
function useOffering(id) {
|
|
581
594
|
const catalog = useCatalog();
|
|
582
595
|
const locale = useActiveLocale();
|
|
583
596
|
const resolved = id ? catalog.get(id) : void 0;
|
|
584
|
-
return useMemo(
|
|
597
|
+
return useMemo(
|
|
598
|
+
() => resolved ? formatOffering(resolved, locale) : void 0,
|
|
599
|
+
[resolved, locale]
|
|
600
|
+
);
|
|
585
601
|
}
|
|
586
|
-
function
|
|
602
|
+
function useOfferings() {
|
|
587
603
|
const catalog = useCatalog();
|
|
588
604
|
const locale = useActiveLocale();
|
|
589
605
|
return useMemo(
|
|
590
|
-
() => Array.from(catalog.values()).map((r) =>
|
|
606
|
+
() => Array.from(catalog.values()).map((r) => formatOffering(r, locale)),
|
|
591
607
|
[catalog, locale]
|
|
592
608
|
);
|
|
593
609
|
}
|
|
@@ -779,8 +795,12 @@ function FunnelView({
|
|
|
779
795
|
[experiments, pageByKey]
|
|
780
796
|
);
|
|
781
797
|
const flow = useMemo(
|
|
782
|
-
() => flowPages.map((p) =>
|
|
783
|
-
|
|
798
|
+
() => flowPages.map((p) => {
|
|
799
|
+
const servedVariant = experiments.render[p.key];
|
|
800
|
+
const variantNext = servedVariant ? pageByKey.get(servedVariant)?.meta?.next : void 0;
|
|
801
|
+
return variantNext ? { key: p.key, meta: { ...p.meta ?? {}, next: variantNext } } : { key: p.key, meta: p.meta };
|
|
802
|
+
}),
|
|
803
|
+
[flowPages, experiments, pageByKey]
|
|
784
804
|
);
|
|
785
805
|
const [history, setHistory] = useState(() => {
|
|
786
806
|
const start = flowPages[0]?.key;
|
|
@@ -1004,7 +1024,7 @@ function EmbedBridge() {
|
|
|
1004
1024
|
function usePage() {
|
|
1005
1025
|
return useNavigation().page;
|
|
1006
1026
|
}
|
|
1007
|
-
var symModalId = /* @__PURE__ */ Symbol("
|
|
1027
|
+
var symModalId = /* @__PURE__ */ Symbol("AppfunnelModalId");
|
|
1008
1028
|
var initialState = {};
|
|
1009
1029
|
var ModalStateContext = createContext(initialState);
|
|
1010
1030
|
var ModalIdContext = createContext(null);
|
|
@@ -1019,7 +1039,9 @@ var runtimeStack = [];
|
|
|
1019
1039
|
var dispatch = (action) => {
|
|
1020
1040
|
const top = runtimeStack[runtimeStack.length - 1];
|
|
1021
1041
|
if (!top) {
|
|
1022
|
-
throw new Error(
|
|
1042
|
+
throw new Error(
|
|
1043
|
+
"No modal dispatch \u2014 render inside <FunnelProvider> (which mounts the modal runtime)."
|
|
1044
|
+
);
|
|
1023
1045
|
}
|
|
1024
1046
|
top(action);
|
|
1025
1047
|
};
|
|
@@ -1118,26 +1140,42 @@ function useModal(modal, args) {
|
|
|
1118
1140
|
const d = useContext(ModalDispatchContext) ?? dispatch;
|
|
1119
1141
|
const isComponent = !!modal && typeof modal !== "string";
|
|
1120
1142
|
const id = modal ? idOf(modal) : contextId;
|
|
1121
|
-
if (!id)
|
|
1143
|
+
if (!id)
|
|
1144
|
+
throw new Error(
|
|
1145
|
+
"useModal: no modal id (call inside a defineModal component, or pass an id/component)."
|
|
1146
|
+
);
|
|
1122
1147
|
useEffect(() => {
|
|
1123
|
-
if (isComponent && !REGISTRY[id])
|
|
1148
|
+
if (isComponent && !REGISTRY[id])
|
|
1149
|
+
registerModal(id, modal, args);
|
|
1124
1150
|
}, [isComponent, id, modal, args]);
|
|
1125
1151
|
const info = modals[id];
|
|
1126
|
-
const show = useCallback(
|
|
1152
|
+
const show = useCallback(
|
|
1153
|
+
(a) => showModalVia(d, id, a),
|
|
1154
|
+
[d, id]
|
|
1155
|
+
);
|
|
1127
1156
|
const hide = useCallback(() => hideModalVia(d, id), [d, id]);
|
|
1128
1157
|
const remove = useCallback(() => removeModalVia(d, id), [d, id]);
|
|
1129
|
-
const resolve = useCallback(
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1158
|
+
const resolve = useCallback(
|
|
1159
|
+
(v) => {
|
|
1160
|
+
modalCallbacks[id]?.resolve(v);
|
|
1161
|
+
delete modalCallbacks[id];
|
|
1162
|
+
},
|
|
1163
|
+
[id]
|
|
1164
|
+
);
|
|
1165
|
+
const reject = useCallback(
|
|
1166
|
+
(v) => {
|
|
1167
|
+
modalCallbacks[id]?.reject(v);
|
|
1168
|
+
delete modalCallbacks[id];
|
|
1169
|
+
},
|
|
1170
|
+
[id]
|
|
1171
|
+
);
|
|
1172
|
+
const resolveHide = useCallback(
|
|
1173
|
+
(v) => {
|
|
1174
|
+
hideCallbacks[id]?.resolve(v);
|
|
1175
|
+
delete hideCallbacks[id];
|
|
1176
|
+
},
|
|
1177
|
+
[id]
|
|
1178
|
+
);
|
|
1141
1179
|
return useMemo(
|
|
1142
1180
|
() => ({
|
|
1143
1181
|
id,
|
|
@@ -1151,11 +1189,27 @@ function useModal(modal, args) {
|
|
|
1151
1189
|
reject,
|
|
1152
1190
|
resolveHide
|
|
1153
1191
|
}),
|
|
1154
|
-
[
|
|
1192
|
+
[
|
|
1193
|
+
id,
|
|
1194
|
+
info?.args,
|
|
1195
|
+
info?.visible,
|
|
1196
|
+
info?.keepMounted,
|
|
1197
|
+
show,
|
|
1198
|
+
hide,
|
|
1199
|
+
remove,
|
|
1200
|
+
resolve,
|
|
1201
|
+
reject,
|
|
1202
|
+
resolveHide
|
|
1203
|
+
]
|
|
1155
1204
|
);
|
|
1156
1205
|
}
|
|
1157
1206
|
function defineModal(Comp) {
|
|
1158
|
-
return function Wrapped({
|
|
1207
|
+
return function Wrapped({
|
|
1208
|
+
id,
|
|
1209
|
+
defaultVisible,
|
|
1210
|
+
keepMounted,
|
|
1211
|
+
...props
|
|
1212
|
+
}) {
|
|
1159
1213
|
const { args, show } = useModal(id);
|
|
1160
1214
|
const modals = useContext(ModalStateContext);
|
|
1161
1215
|
const d = useContext(ModalDispatchContext) ?? dispatch;
|
|
@@ -1188,7 +1242,9 @@ function ModalRoot() {
|
|
|
1188
1242
|
return createElement(
|
|
1189
1243
|
"div",
|
|
1190
1244
|
{ "data-appfunnel-modal-root": "" },
|
|
1191
|
-
...toRender.map(
|
|
1245
|
+
...toRender.map(
|
|
1246
|
+
(t) => createElement(t.comp, { key: t.id, id: t.id, ...t.props })
|
|
1247
|
+
)
|
|
1192
1248
|
);
|
|
1193
1249
|
}
|
|
1194
1250
|
function ModalRuntime({ children }) {
|
|
@@ -1316,12 +1372,20 @@ function Modal(props) {
|
|
|
1316
1372
|
|
|
1317
1373
|
// src/commerce/checkout.tsx
|
|
1318
1374
|
function createMockDriver(provider = "stripe", options = {}) {
|
|
1319
|
-
const success = options.result ?? {
|
|
1320
|
-
|
|
1375
|
+
const success = options.result ?? {
|
|
1376
|
+
ok: true,
|
|
1377
|
+
amountMinor: 0,
|
|
1378
|
+
currency: "USD"
|
|
1379
|
+
};
|
|
1380
|
+
const offError = typeof options.failOffSession === "object" ? options.failOffSession : checkoutError(
|
|
1381
|
+
"authentication_required",
|
|
1382
|
+
"off-session charge declined (mock)"
|
|
1383
|
+
);
|
|
1321
1384
|
return {
|
|
1322
1385
|
provider,
|
|
1323
1386
|
start: (req) => {
|
|
1324
|
-
if (options.failOffSession && !req.surface)
|
|
1387
|
+
if (options.failOffSession && !req.surface)
|
|
1388
|
+
return Promise.resolve({ ok: false, error: offError });
|
|
1325
1389
|
return Promise.resolve(success);
|
|
1326
1390
|
},
|
|
1327
1391
|
renderInline: (req, cb) => createElement(
|
|
@@ -1332,7 +1396,13 @@ function createMockDriver(provider = "stripe", options = {}) {
|
|
|
1332
1396
|
onClick: () => {
|
|
1333
1397
|
cb.onStart?.();
|
|
1334
1398
|
if (success.ok) cb.onSuccess(success);
|
|
1335
|
-
else
|
|
1399
|
+
else
|
|
1400
|
+
cb.onError(
|
|
1401
|
+
success.error ?? checkoutError(
|
|
1402
|
+
"processing_error",
|
|
1403
|
+
"failed (mock)"
|
|
1404
|
+
)
|
|
1405
|
+
);
|
|
1336
1406
|
}
|
|
1337
1407
|
},
|
|
1338
1408
|
`Pay (mock ${req.surface})`
|
|
@@ -1390,11 +1460,11 @@ function useCheckout(opts = {}) {
|
|
|
1390
1460
|
[catalog, kind]
|
|
1391
1461
|
);
|
|
1392
1462
|
const recovering = useRef(false);
|
|
1393
|
-
const failRef = useRef(
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
async () => ({ ok: false })
|
|
1463
|
+
const failRef = useRef(
|
|
1464
|
+
() => {
|
|
1465
|
+
}
|
|
1397
1466
|
);
|
|
1467
|
+
const attemptRef = useRef(async () => ({ ok: false }));
|
|
1398
1468
|
const succeed = useCallback(
|
|
1399
1469
|
(result, product) => {
|
|
1400
1470
|
setStatus("success");
|
|
@@ -1408,7 +1478,12 @@ function useCheckout(opts = {}) {
|
|
|
1408
1478
|
// server-minted (browser↔CAPI dedup); undefined if none
|
|
1409
1479
|
});
|
|
1410
1480
|
if (isSubscription) {
|
|
1411
|
-
tracker.track("subscription.created", {
|
|
1481
|
+
tracker.track("subscription.created", {
|
|
1482
|
+
amount,
|
|
1483
|
+
currency: result.currency,
|
|
1484
|
+
productId,
|
|
1485
|
+
eventId: result.eventId
|
|
1486
|
+
});
|
|
1412
1487
|
}
|
|
1413
1488
|
opts.onSuccess?.(result);
|
|
1414
1489
|
if (advance) nav.next();
|
|
@@ -1422,14 +1497,25 @@ function useCheckout(opts = {}) {
|
|
|
1422
1497
|
setStatus("loading");
|
|
1423
1498
|
setError(null);
|
|
1424
1499
|
const { productId, amount, currency } = productFacts(product);
|
|
1425
|
-
tracker.track("checkout.start", {
|
|
1500
|
+
tracker.track("checkout.start", {
|
|
1501
|
+
productId,
|
|
1502
|
+
amount,
|
|
1503
|
+
currency,
|
|
1504
|
+
surface,
|
|
1505
|
+
eventId: newEventId()
|
|
1506
|
+
});
|
|
1426
1507
|
},
|
|
1427
1508
|
[tracker, productFacts]
|
|
1428
1509
|
);
|
|
1429
1510
|
const paymentAdded = useCallback(
|
|
1430
1511
|
(product) => {
|
|
1431
1512
|
const { productId, amount, currency } = productFacts(product);
|
|
1432
|
-
tracker.track("checkout.payment_added", {
|
|
1513
|
+
tracker.track("checkout.payment_added", {
|
|
1514
|
+
productId,
|
|
1515
|
+
amount,
|
|
1516
|
+
currency,
|
|
1517
|
+
eventId: newEventId()
|
|
1518
|
+
});
|
|
1433
1519
|
},
|
|
1434
1520
|
[tracker, productFacts]
|
|
1435
1521
|
);
|
|
@@ -1452,7 +1538,9 @@ function useCheckout(opts = {}) {
|
|
|
1452
1538
|
}
|
|
1453
1539
|
};
|
|
1454
1540
|
failRef.current = (err, product) => {
|
|
1455
|
-
setStatus(
|
|
1541
|
+
setStatus(
|
|
1542
|
+
err.category === "authentication_required" ? "requires_action" : "error"
|
|
1543
|
+
);
|
|
1456
1544
|
setError(err);
|
|
1457
1545
|
tracker.track("checkout.failed", {
|
|
1458
1546
|
category: err.category,
|
|
@@ -1483,35 +1571,59 @@ function useCheckout(opts = {}) {
|
|
|
1483
1571
|
if (!product) return;
|
|
1484
1572
|
recovering.current = true;
|
|
1485
1573
|
if (!surface) {
|
|
1486
|
-
if (intent === "upsell")
|
|
1487
|
-
|
|
1574
|
+
if (intent === "upsell")
|
|
1575
|
+
void attemptRef.current(product);
|
|
1576
|
+
else
|
|
1577
|
+
startRecovery(
|
|
1578
|
+
product,
|
|
1579
|
+
PROVIDER_PROFILES[driver.provider]?.surfaces.sheet ? "sheet" : "popup"
|
|
1580
|
+
);
|
|
1488
1581
|
return;
|
|
1489
1582
|
}
|
|
1490
1583
|
startRecovery(product, surface);
|
|
1491
1584
|
}
|
|
1492
1585
|
};
|
|
1493
|
-
void showModal(
|
|
1586
|
+
void showModal(
|
|
1587
|
+
route.modal,
|
|
1588
|
+
props
|
|
1589
|
+
);
|
|
1494
1590
|
} else if ("fallback" in route) {
|
|
1495
|
-
if (product && !recovering.current)
|
|
1591
|
+
if (product && !recovering.current)
|
|
1592
|
+
startRecovery(product, route.fallback);
|
|
1496
1593
|
}
|
|
1497
1594
|
};
|
|
1498
1595
|
attemptRef.current = async (product, surface) => {
|
|
1499
1596
|
begin(product, surface);
|
|
1500
1597
|
try {
|
|
1501
|
-
const result = await driver.start({
|
|
1598
|
+
const result = await driver.start({
|
|
1599
|
+
product,
|
|
1600
|
+
intent,
|
|
1601
|
+
surface,
|
|
1602
|
+
kind
|
|
1603
|
+
});
|
|
1502
1604
|
if (result.ok) succeedRef.current(result, product);
|
|
1503
|
-
else
|
|
1605
|
+
else
|
|
1606
|
+
failRef.current(
|
|
1607
|
+
result.error ?? checkoutError("unknown", "Checkout failed"),
|
|
1608
|
+
product
|
|
1609
|
+
);
|
|
1504
1610
|
return result;
|
|
1505
1611
|
} catch (e) {
|
|
1506
|
-
const err = checkoutError(
|
|
1612
|
+
const err = checkoutError(
|
|
1613
|
+
"processing_error",
|
|
1614
|
+
e instanceof Error ? e.message : "Checkout failed"
|
|
1615
|
+
);
|
|
1507
1616
|
failRef.current(err, product);
|
|
1508
1617
|
return { ok: false, error: err };
|
|
1509
1618
|
}
|
|
1510
1619
|
};
|
|
1511
|
-
const open = useCallback(
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1620
|
+
const open = useCallback(
|
|
1621
|
+
async (product, surface) => {
|
|
1622
|
+
recovering.current = false;
|
|
1623
|
+
return attemptRef.current(product, surface);
|
|
1624
|
+
},
|
|
1625
|
+
[]
|
|
1626
|
+
);
|
|
1515
1627
|
const callbacksFor = useCallback(
|
|
1516
1628
|
(product, surface) => ({
|
|
1517
1629
|
onStart: () => {
|
|
@@ -1529,7 +1641,14 @@ function useCheckout(opts = {}) {
|
|
|
1529
1641
|
setStatus("idle");
|
|
1530
1642
|
setError(null);
|
|
1531
1643
|
}, []);
|
|
1532
|
-
return {
|
|
1644
|
+
return {
|
|
1645
|
+
open,
|
|
1646
|
+
status,
|
|
1647
|
+
error,
|
|
1648
|
+
isLoading: status === "loading",
|
|
1649
|
+
reset,
|
|
1650
|
+
callbacksFor
|
|
1651
|
+
};
|
|
1533
1652
|
}
|
|
1534
1653
|
var CheckoutSheet = defineModal(({ product, surface, intent, kind, onSuccess, onError, onPaymentAdded }) => {
|
|
1535
1654
|
const driver = useDriver();
|
|
@@ -1542,7 +1661,10 @@ var CheckoutSheet = defineModal(({ product, surface, intent, kind, onSuccess, on
|
|
|
1542
1661
|
if (!hostable) {
|
|
1543
1662
|
resolved.current = true;
|
|
1544
1663
|
onErrorRef.current(
|
|
1545
|
-
checkoutError(
|
|
1664
|
+
checkoutError(
|
|
1665
|
+
"processing_error",
|
|
1666
|
+
"This checkout driver has no inline surface to host in the sheet"
|
|
1667
|
+
)
|
|
1546
1668
|
);
|
|
1547
1669
|
void modal.hide();
|
|
1548
1670
|
modal.remove();
|
|
@@ -1550,7 +1672,12 @@ var CheckoutSheet = defineModal(({ product, surface, intent, kind, onSuccess, on
|
|
|
1550
1672
|
}
|
|
1551
1673
|
return () => {
|
|
1552
1674
|
if (!resolved.current) {
|
|
1553
|
-
onErrorRef.current(
|
|
1675
|
+
onErrorRef.current(
|
|
1676
|
+
checkoutError(
|
|
1677
|
+
"canceled",
|
|
1678
|
+
"Checkout was dismissed before completing"
|
|
1679
|
+
)
|
|
1680
|
+
);
|
|
1554
1681
|
}
|
|
1555
1682
|
};
|
|
1556
1683
|
}, []);
|
|
@@ -1577,21 +1704,31 @@ var CheckoutSheet = defineModal(({ product, surface, intent, kind, onSuccess, on
|
|
|
1577
1704
|
)
|
|
1578
1705
|
});
|
|
1579
1706
|
});
|
|
1580
|
-
function trigger(onClick, {
|
|
1707
|
+
function trigger(onClick, {
|
|
1708
|
+
asChild,
|
|
1709
|
+
children,
|
|
1710
|
+
className,
|
|
1711
|
+
disabled
|
|
1712
|
+
}) {
|
|
1581
1713
|
if (asChild && isValidElement(children)) {
|
|
1582
1714
|
const child = children;
|
|
1583
1715
|
return cloneElement(child, { onClick });
|
|
1584
1716
|
}
|
|
1585
|
-
return createElement(
|
|
1717
|
+
return createElement(
|
|
1718
|
+
"button",
|
|
1719
|
+
{ type: "button", className, disabled, onClick },
|
|
1720
|
+
children ?? "Continue"
|
|
1721
|
+
);
|
|
1586
1722
|
}
|
|
1587
1723
|
function Checkout({
|
|
1588
|
-
|
|
1724
|
+
offering,
|
|
1589
1725
|
surface,
|
|
1590
1726
|
asChild,
|
|
1591
1727
|
children,
|
|
1592
1728
|
className,
|
|
1593
1729
|
...options
|
|
1594
1730
|
}) {
|
|
1731
|
+
const product = offering;
|
|
1595
1732
|
const driver = useDriver();
|
|
1596
1733
|
const checkout = useCheckout(options);
|
|
1597
1734
|
const intent = options.intent ?? "purchase";
|
|
@@ -1599,7 +1736,10 @@ function Checkout({
|
|
|
1599
1736
|
return driver.renderInline ? createElement(
|
|
1600
1737
|
"div",
|
|
1601
1738
|
{ key: product, className },
|
|
1602
|
-
driver.renderInline(
|
|
1739
|
+
driver.renderInline(
|
|
1740
|
+
{ product, intent, surface },
|
|
1741
|
+
checkout.callbacksFor(product, surface)
|
|
1742
|
+
)
|
|
1603
1743
|
) : null;
|
|
1604
1744
|
}
|
|
1605
1745
|
if (surface === "sheet") {
|
|
@@ -1616,7 +1756,12 @@ function Checkout({
|
|
|
1616
1756
|
onPaymentAdded: cb.onPaymentAdded
|
|
1617
1757
|
});
|
|
1618
1758
|
};
|
|
1619
|
-
return trigger(open, {
|
|
1759
|
+
return trigger(open, {
|
|
1760
|
+
asChild,
|
|
1761
|
+
children,
|
|
1762
|
+
className,
|
|
1763
|
+
disabled: checkout.isLoading
|
|
1764
|
+
});
|
|
1620
1765
|
}
|
|
1621
1766
|
return trigger(() => checkout.open(product, surface), {
|
|
1622
1767
|
asChild,
|
|
@@ -1625,18 +1770,29 @@ function Checkout({
|
|
|
1625
1770
|
disabled: checkout.isLoading
|
|
1626
1771
|
});
|
|
1627
1772
|
}
|
|
1628
|
-
function Upsell({
|
|
1773
|
+
function Upsell({
|
|
1774
|
+
offering,
|
|
1775
|
+
fallback,
|
|
1776
|
+
asChild,
|
|
1777
|
+
children,
|
|
1778
|
+
className,
|
|
1779
|
+
...options
|
|
1780
|
+
}) {
|
|
1781
|
+
const product = offering;
|
|
1629
1782
|
const checkout = useCheckout({
|
|
1630
1783
|
...options,
|
|
1631
1784
|
intent: "upsell",
|
|
1632
1785
|
recoverySurface: fallback ?? options.recoverySurface
|
|
1633
1786
|
});
|
|
1634
|
-
return trigger(
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1787
|
+
return trigger(
|
|
1788
|
+
() => void checkout.open(product),
|
|
1789
|
+
{
|
|
1790
|
+
asChild,
|
|
1791
|
+
children: children ?? "Add to my plan",
|
|
1792
|
+
className,
|
|
1793
|
+
disabled: checkout.isLoading
|
|
1794
|
+
}
|
|
1795
|
+
);
|
|
1640
1796
|
}
|
|
1641
1797
|
var consumedResumes = /* @__PURE__ */ new Set();
|
|
1642
1798
|
function CheckoutResume(options = {}) {
|
|
@@ -1654,10 +1810,19 @@ function CheckoutResume(options = {}) {
|
|
|
1654
1810
|
const cb = callbacksRef.current();
|
|
1655
1811
|
if (result.ok) {
|
|
1656
1812
|
url.searchParams.delete("af_checkout");
|
|
1657
|
-
window.history.replaceState(
|
|
1813
|
+
window.history.replaceState(
|
|
1814
|
+
window.history.state,
|
|
1815
|
+
"",
|
|
1816
|
+
url.toString()
|
|
1817
|
+
);
|
|
1658
1818
|
cb.onSuccess(result);
|
|
1659
1819
|
} else {
|
|
1660
|
-
cb.onError(
|
|
1820
|
+
cb.onError(
|
|
1821
|
+
result.error ?? checkoutError(
|
|
1822
|
+
"unknown",
|
|
1823
|
+
"The checkout could not be verified"
|
|
1824
|
+
)
|
|
1825
|
+
);
|
|
1661
1826
|
}
|
|
1662
1827
|
});
|
|
1663
1828
|
}, []);
|
|
@@ -2772,7 +2937,8 @@ var Namespace = class {
|
|
|
2772
2937
|
const out = {};
|
|
2773
2938
|
const all = this.store.getState();
|
|
2774
2939
|
for (const key in all) {
|
|
2775
|
-
if (key.startsWith(this.dot))
|
|
2940
|
+
if (key.startsWith(this.dot))
|
|
2941
|
+
out[key.slice(this.dot.length)] = all[key];
|
|
2776
2942
|
}
|
|
2777
2943
|
return out;
|
|
2778
2944
|
}
|
|
@@ -2821,7 +2987,7 @@ function FunnelProvider({
|
|
|
2821
2987
|
deferSessionValues = false,
|
|
2822
2988
|
tracker,
|
|
2823
2989
|
context: contextOpts,
|
|
2824
|
-
|
|
2990
|
+
offerings,
|
|
2825
2991
|
experiments,
|
|
2826
2992
|
checkout,
|
|
2827
2993
|
messages,
|
|
@@ -2857,7 +3023,7 @@ function FunnelProvider({
|
|
|
2857
3023
|
const value2 = s.get("user.email");
|
|
2858
3024
|
return typeof value2 === "string" && /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(value2) ? value2 : void 0;
|
|
2859
3025
|
};
|
|
2860
|
-
const catalog = buildCatalog(
|
|
3026
|
+
const catalog = buildCatalog(offerings ?? []);
|
|
2861
3027
|
return {
|
|
2862
3028
|
funnel: createFunnel(s, ctx, busTracker, experiments ?? []),
|
|
2863
3029
|
store: s,
|
|
@@ -2865,7 +3031,13 @@ function FunnelProvider({
|
|
|
2865
3031
|
catalog,
|
|
2866
3032
|
// Slot → catalog-key resolution wraps the email-enriching driver, so the wire charges the real
|
|
2867
3033
|
// catalog key while pages + analytics keep the durable SLOT identity (req.product).
|
|
2868
|
-
driver: driverWithCatalog(
|
|
3034
|
+
driver: driverWithCatalog(
|
|
3035
|
+
driverWithEmail(
|
|
3036
|
+
checkout ?? createMockDriver(),
|
|
3037
|
+
emailForCheckout
|
|
3038
|
+
),
|
|
3039
|
+
catalog
|
|
3040
|
+
),
|
|
2869
3041
|
tracker: busTracker,
|
|
2870
3042
|
bus
|
|
2871
3043
|
};
|
|
@@ -2874,7 +3046,8 @@ function FunnelProvider({
|
|
|
2874
3046
|
useEffect(() => {
|
|
2875
3047
|
if (!deferSessionValues || !sessionValues) return;
|
|
2876
3048
|
const updates = {};
|
|
2877
|
-
for (const [key, v] of Object.entries(sessionValues))
|
|
3049
|
+
for (const [key, v] of Object.entries(sessionValues))
|
|
3050
|
+
if (v !== void 0) updates[key] = v;
|
|
2878
3051
|
if (Object.keys(updates).length > 0) value.store.setMany(updates);
|
|
2879
3052
|
}, []);
|
|
2880
3053
|
useEffect(() => {
|
|
@@ -2905,7 +3078,9 @@ var FALLBACK_TRACKER = createConsoleTracker({ silent: true });
|
|
|
2905
3078
|
function useFunnelCtx() {
|
|
2906
3079
|
const ctx = useContext(FunnelCtx);
|
|
2907
3080
|
if (!ctx) {
|
|
2908
|
-
throw new Error(
|
|
3081
|
+
throw new Error(
|
|
3082
|
+
"useFunnel/useResponse/\u2026 must be used inside <FunnelProvider>"
|
|
3083
|
+
);
|
|
2909
3084
|
}
|
|
2910
3085
|
return ctx;
|
|
2911
3086
|
}
|
|
@@ -2943,7 +3118,9 @@ function useField(path) {
|
|
|
2943
3118
|
const key = path.slice(dot + 1);
|
|
2944
3119
|
const { funnel, store } = useFunnelCtx();
|
|
2945
3120
|
if (!(ns in NAMESPACE_PREFIX)) {
|
|
2946
|
-
throw new Error(
|
|
3121
|
+
throw new Error(
|
|
3122
|
+
`useField: "${path}" is not a writable namespace (user/responses/data)`
|
|
3123
|
+
);
|
|
2947
3124
|
}
|
|
2948
3125
|
const value = useStoreKey(store, `${NAMESPACE_PREFIX[ns]}.${key}`);
|
|
2949
3126
|
const set = useCallback(
|
|
@@ -2973,7 +3150,10 @@ function useSystem() {
|
|
|
2973
3150
|
function useContextValue(path) {
|
|
2974
3151
|
const ctx = useContextObject();
|
|
2975
3152
|
return useMemo(
|
|
2976
|
-
() => path.split(".").reduce(
|
|
3153
|
+
() => path.split(".").reduce(
|
|
3154
|
+
(acc, k) => acc?.[k],
|
|
3155
|
+
ctx
|
|
3156
|
+
),
|
|
2977
3157
|
[ctx, path]
|
|
2978
3158
|
);
|
|
2979
3159
|
}
|
|
@@ -3330,7 +3510,7 @@ function createFunnelTree({
|
|
|
3330
3510
|
assets: opts.assets,
|
|
3331
3511
|
children: createElement(FunnelProvider, {
|
|
3332
3512
|
config,
|
|
3333
|
-
|
|
3513
|
+
offerings: opts.offerings ?? [],
|
|
3334
3514
|
messages: opts.messages ?? messages,
|
|
3335
3515
|
locale: opts.locale,
|
|
3336
3516
|
tracker,
|
|
@@ -3501,6 +3681,6 @@ function Script({
|
|
|
3501
3681
|
return null;
|
|
3502
3682
|
}
|
|
3503
3683
|
|
|
3504
|
-
export { AssetsContext, AssetsProvider, Back, Checkout, CheckoutResume, Choice, EVENT_CATALOG, FunnelProvider, FunnelToaster, FunnelView, Modal, Next, Script, Sheet, Upsell, VariableStore, attachBus, buildAcquisition, buildContext, createBus, createConsoleTracker, createFunnelStore, createFunnelTree, createMockDriver, createPlatformTracker, defineModal, driverWithEmail, hideModal, integrationEvents, isIntegrationEvent, isTrackableEvent, newEventId, registerModal, removeModal, showModal, toast, unregisterModal, useActiveLocale, useAsset, useAssets, useCheckout, useClickIds, useContextValue, useData, useDevice, useExperiment, useField, useFunnel, useLocale, useModal, useNavigation,
|
|
3684
|
+
export { AssetsContext, AssetsProvider, Back, Checkout, CheckoutResume, Choice, EVENT_CATALOG, FunnelProvider, FunnelToaster, FunnelView, Modal, Next, Script, Sheet, Upsell, VariableStore, attachBus, buildAcquisition, buildContext, createBus, createConsoleTracker, createFunnelStore, createFunnelTree, createMockDriver, createPlatformTracker, defineModal, driverWithEmail, hideModal, integrationEvents, isIntegrationEvent, isTrackableEvent, newEventId, registerModal, removeModal, showModal, toast, unregisterModal, useActiveLocale, useAsset, useAssets, useCheckout, useClickIds, useContextValue, useData, useDevice, useExperiment, useField, useFunnel, useLocale, useModal, useNavigation, useOffering, useOfferings, usePage, useResponse, useSystem, useTracker, useTranslation, useUserAttribute, useUtm, withBus };
|
|
3505
3685
|
//# sourceMappingURL=index.js.map
|
|
3506
3686
|
//# sourceMappingURL=index.js.map
|