@cimplify/sdk 0.8.0 → 0.8.2
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/advanced.d.mts +1 -1
- package/dist/advanced.d.ts +1 -1
- package/dist/advanced.js +41 -5
- package/dist/advanced.mjs +41 -5
- package/dist/{client-tMD3aBuM.d.ts → client-1fzEx2NA.d.ts} +41 -1
- package/dist/{client-I-utsHva.d.mts → client-Bm2VkZJq.d.mts} +41 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +171 -110
- package/dist/index.mjs +171 -110
- package/dist/react.d.mts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +419 -301
- package/dist/react.mjs +208 -94
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React2 = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var React2__default = /*#__PURE__*/_interopDefault(React2);
|
|
9
|
+
|
|
6
10
|
// src/react/index.tsx
|
|
7
11
|
|
|
8
12
|
// src/types/elements.ts
|
|
@@ -16,6 +20,7 @@ var MESSAGE_TYPES = {
|
|
|
16
20
|
// Parent → Iframe
|
|
17
21
|
INIT: "init",
|
|
18
22
|
SET_TOKEN: "set_token",
|
|
23
|
+
SET_CART: "set_cart",
|
|
19
24
|
GET_DATA: "get_data",
|
|
20
25
|
PROCESS_CHECKOUT: "process_checkout",
|
|
21
26
|
ABORT_CHECKOUT: "abort_checkout",
|
|
@@ -33,7 +38,8 @@ var MESSAGE_TYPES = {
|
|
|
33
38
|
CONTACT_PROVIDED: "contact_provided",
|
|
34
39
|
CHECKOUT_STATUS: "checkout_status",
|
|
35
40
|
CHECKOUT_COMPLETE: "checkout_complete",
|
|
36
|
-
ORDER_TYPE_CHANGED: "order_type_changed"
|
|
41
|
+
ORDER_TYPE_CHANGED: "order_type_changed",
|
|
42
|
+
REQUEST_SUBMIT: "request_submit"
|
|
37
43
|
};
|
|
38
44
|
var EVENT_TYPES = {
|
|
39
45
|
READY: "ready",
|
|
@@ -41,7 +47,8 @@ var EVENT_TYPES = {
|
|
|
41
47
|
REQUIRES_OTP: "requires_otp",
|
|
42
48
|
ERROR: "error",
|
|
43
49
|
CHANGE: "change",
|
|
44
|
-
ORDER_TYPE_CHANGED: "order_type_changed"
|
|
50
|
+
ORDER_TYPE_CHANGED: "order_type_changed",
|
|
51
|
+
REQUEST_SUBMIT: "request_submit"
|
|
45
52
|
};
|
|
46
53
|
|
|
47
54
|
// src/ads/identity.ts
|
|
@@ -194,7 +201,7 @@ function deriveAdsApiUrl() {
|
|
|
194
201
|
}
|
|
195
202
|
return "https://api.cimplify.io";
|
|
196
203
|
}
|
|
197
|
-
var AdContext =
|
|
204
|
+
var AdContext = React2.createContext({
|
|
198
205
|
siteId: null,
|
|
199
206
|
config: null,
|
|
200
207
|
isLoading: true,
|
|
@@ -202,7 +209,7 @@ var AdContext = react.createContext({
|
|
|
202
209
|
apiBase: "https://api.cimplify.io"
|
|
203
210
|
});
|
|
204
211
|
function useAds() {
|
|
205
|
-
return
|
|
212
|
+
return React2.useContext(AdContext);
|
|
206
213
|
}
|
|
207
214
|
function AdProvider({
|
|
208
215
|
siteId,
|
|
@@ -211,10 +218,10 @@ function AdProvider({
|
|
|
211
218
|
children
|
|
212
219
|
}) {
|
|
213
220
|
const resolvedApiBase = apiBase || deriveAdsApiUrl();
|
|
214
|
-
const [config, setConfig] =
|
|
215
|
-
const [isLoading, setIsLoading] =
|
|
216
|
-
const [identity, setIdentity] =
|
|
217
|
-
|
|
221
|
+
const [config, setConfig] = React2.useState(null);
|
|
222
|
+
const [isLoading, setIsLoading] = React2.useState(true);
|
|
223
|
+
const [identity, setIdentity] = React2.useState(null);
|
|
224
|
+
React2.useEffect(() => {
|
|
218
225
|
const userIdentity = getUserIdentity(authenticatedAccountId);
|
|
219
226
|
setIdentity(userIdentity);
|
|
220
227
|
fetch(`${resolvedApiBase}/ads/config/${siteId}`).then((r) => r.json()).then((data) => {
|
|
@@ -237,11 +244,11 @@ function Ad({
|
|
|
237
244
|
onClick
|
|
238
245
|
}) {
|
|
239
246
|
const { siteId, config, isLoading, identity, apiBase } = useAds();
|
|
240
|
-
const [ad, setAd] =
|
|
241
|
-
const [error, setError] =
|
|
242
|
-
const impressionTracked =
|
|
243
|
-
const containerRef =
|
|
244
|
-
|
|
247
|
+
const [ad, setAd] = React2.useState(null);
|
|
248
|
+
const [error, setError] = React2.useState(false);
|
|
249
|
+
const impressionTracked = React2.useRef(false);
|
|
250
|
+
const containerRef = React2.useRef(null);
|
|
251
|
+
React2.useEffect(() => {
|
|
245
252
|
if (isLoading || !config?.enabled || !siteId || !identity) return;
|
|
246
253
|
const path = typeof window !== "undefined" ? window.location.pathname : "/";
|
|
247
254
|
const referrer = typeof document !== "undefined" ? document.referrer : "";
|
|
@@ -284,7 +291,7 @@ function Ad({
|
|
|
284
291
|
}
|
|
285
292
|
}).catch(() => setError(true));
|
|
286
293
|
}, [siteId, config, isLoading, slot, identity, apiBase]);
|
|
287
|
-
|
|
294
|
+
React2.useEffect(() => {
|
|
288
295
|
if (!ad || impressionTracked.current || typeof window === "undefined" || !identity) return;
|
|
289
296
|
const observer = new IntersectionObserver(
|
|
290
297
|
([entry]) => {
|
|
@@ -343,7 +350,62 @@ function Ad({
|
|
|
343
350
|
}
|
|
344
351
|
);
|
|
345
352
|
}
|
|
346
|
-
|
|
353
|
+
|
|
354
|
+
// src/utils/cart-transform.ts
|
|
355
|
+
function getSelections(item) {
|
|
356
|
+
if (item.bundle_resolved?.selections?.length) {
|
|
357
|
+
return item.bundle_resolved.selections.map((s) => ({
|
|
358
|
+
name: s.product_name || s.component_id,
|
|
359
|
+
quantity: s.quantity,
|
|
360
|
+
variant_name: s.variant_name
|
|
361
|
+
}));
|
|
362
|
+
}
|
|
363
|
+
if (item.composite_resolved?.selections?.length) {
|
|
364
|
+
return item.composite_resolved.selections.map((s) => ({
|
|
365
|
+
name: s.component_name || s.component_id,
|
|
366
|
+
quantity: s.quantity
|
|
367
|
+
}));
|
|
368
|
+
}
|
|
369
|
+
return void 0;
|
|
370
|
+
}
|
|
371
|
+
function mapItem(item) {
|
|
372
|
+
const result = {
|
|
373
|
+
name: item.name,
|
|
374
|
+
quantity: item.quantity,
|
|
375
|
+
unit_price: String(item.base_price),
|
|
376
|
+
total_price: String(item.total_price),
|
|
377
|
+
line_type: item.line_type
|
|
378
|
+
};
|
|
379
|
+
if (item.image_url) result.image_url = item.image_url;
|
|
380
|
+
const variantName = item.variant_info?.name || item.variant_name || void 0;
|
|
381
|
+
if (variantName) result.variant_name = variantName;
|
|
382
|
+
if (item.scheduled_start) result.scheduled_start = item.scheduled_start;
|
|
383
|
+
if (item.scheduled_end) result.scheduled_end = item.scheduled_end;
|
|
384
|
+
const selections = getSelections(item);
|
|
385
|
+
if (selections) result.selections = selections;
|
|
386
|
+
if (item.add_on_options?.length) {
|
|
387
|
+
result.add_ons = item.add_on_options.map((opt) => ({
|
|
388
|
+
name: opt.name,
|
|
389
|
+
price: String(opt.price ?? "0")
|
|
390
|
+
}));
|
|
391
|
+
}
|
|
392
|
+
if (item.special_instructions) {
|
|
393
|
+
result.special_instructions = item.special_instructions;
|
|
394
|
+
}
|
|
395
|
+
return result;
|
|
396
|
+
}
|
|
397
|
+
function transformToCheckoutCart(cart) {
|
|
398
|
+
return {
|
|
399
|
+
items: cart.items.map(mapItem),
|
|
400
|
+
subtotal: String(cart.pricing.subtotal),
|
|
401
|
+
tax_amount: String(cart.pricing.tax_amount),
|
|
402
|
+
total_discounts: String(cart.pricing.total_discounts),
|
|
403
|
+
service_charge: String(cart.pricing.service_charge),
|
|
404
|
+
total: String(cart.pricing.total_price),
|
|
405
|
+
currency: cart.pricing.currency
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
var SPACE = { sm: 8};
|
|
347
409
|
function shellColors(isDark, primaryColor) {
|
|
348
410
|
return {
|
|
349
411
|
text: isDark ? "#f4f4f5" : "#1a1a1a",
|
|
@@ -397,49 +459,48 @@ function CimplifyCheckout({
|
|
|
397
459
|
demoMode,
|
|
398
460
|
className
|
|
399
461
|
}) {
|
|
400
|
-
const resolvedOrderTypes =
|
|
462
|
+
const resolvedOrderTypes = React2.useMemo(
|
|
401
463
|
() => orderTypes && orderTypes.length > 0 ? orderTypes : ["pickup", "delivery"],
|
|
402
464
|
[orderTypes]
|
|
403
465
|
);
|
|
404
|
-
const [orderType, setOrderType] =
|
|
405
|
-
const [status, setStatus] =
|
|
406
|
-
const [statusText, setStatusText] =
|
|
407
|
-
const [isSubmitting, setIsSubmitting] =
|
|
408
|
-
const [isInitializing, setIsInitializing] =
|
|
409
|
-
const [errorMessage, setErrorMessage] =
|
|
410
|
-
const [resolvedBusinessId, setResolvedBusinessId] =
|
|
411
|
-
const [resolvedCartId, setResolvedCartId] =
|
|
412
|
-
const
|
|
413
|
-
const
|
|
414
|
-
const
|
|
415
|
-
const
|
|
416
|
-
const
|
|
417
|
-
const
|
|
418
|
-
const
|
|
419
|
-
const
|
|
420
|
-
const onErrorRef = react.useRef(onError);
|
|
421
|
-
const onStatusChangeRef = react.useRef(onStatusChange);
|
|
422
|
-
onCompleteRef.current = onComplete;
|
|
423
|
-
onErrorRef.current = onError;
|
|
424
|
-
onStatusChangeRef.current = onStatusChange;
|
|
466
|
+
const [orderType, setOrderType] = React2.useState(resolvedOrderTypes[0] || "pickup");
|
|
467
|
+
const [status, setStatus] = React2.useState(null);
|
|
468
|
+
const [statusText, setStatusText] = React2.useState("");
|
|
469
|
+
const [isSubmitting, setIsSubmitting] = React2.useState(false);
|
|
470
|
+
const [isInitializing, setIsInitializing] = React2.useState(false);
|
|
471
|
+
const [errorMessage, setErrorMessage] = React2.useState(null);
|
|
472
|
+
const [resolvedBusinessId, setResolvedBusinessId] = React2.useState(businessId ?? null);
|
|
473
|
+
const [resolvedCartId, setResolvedCartId] = React2.useState(cartId ?? null);
|
|
474
|
+
const [resolvedCart, setResolvedCart] = React2.useState(null);
|
|
475
|
+
const checkoutMountRef = React2.useRef(null);
|
|
476
|
+
const elementsRef = React2.useRef(null);
|
|
477
|
+
const activeCheckoutRef = React2.useRef(null);
|
|
478
|
+
const initialAppearanceRef = React2.useRef(appearance);
|
|
479
|
+
const hasWarnedInlineAppearanceRef = React2.useRef(false);
|
|
480
|
+
const isMountedRef = React2.useRef(true);
|
|
481
|
+
const demoRunRef = React2.useRef(0);
|
|
425
482
|
const isDemoCheckout = demoMode ?? client.getPublicKey().trim().length === 0;
|
|
426
483
|
const isTestMode = client.isTestMode();
|
|
427
484
|
const primaryColor = appearance?.variables?.primaryColor || "#0a2540";
|
|
428
485
|
const isDark = appearance?.theme === "dark";
|
|
429
|
-
const emitStatus =
|
|
486
|
+
const emitStatus = React2__default.default.useEffectEvent(
|
|
430
487
|
(nextStatus, context = {}) => {
|
|
431
488
|
setStatus(nextStatus);
|
|
432
489
|
setStatusText(context.display_text || "");
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
|
|
490
|
+
onStatusChange?.(nextStatus, context);
|
|
491
|
+
}
|
|
492
|
+
);
|
|
493
|
+
const fireError = React2__default.default.useEffectEvent(
|
|
494
|
+
(error) => {
|
|
495
|
+
onError?.(error);
|
|
496
|
+
}
|
|
436
497
|
);
|
|
437
|
-
|
|
498
|
+
React2.useEffect(() => {
|
|
438
499
|
if (!resolvedOrderTypes.includes(orderType)) {
|
|
439
500
|
setOrderType(resolvedOrderTypes[0] || "pickup");
|
|
440
501
|
}
|
|
441
502
|
}, [resolvedOrderTypes, orderType]);
|
|
442
|
-
|
|
503
|
+
React2.useEffect(() => {
|
|
443
504
|
if (appearance && appearance !== initialAppearanceRef.current && !hasWarnedInlineAppearanceRef.current) {
|
|
444
505
|
hasWarnedInlineAppearanceRef.current = true;
|
|
445
506
|
console.warn(
|
|
@@ -447,7 +508,7 @@ function CimplifyCheckout({
|
|
|
447
508
|
);
|
|
448
509
|
}
|
|
449
510
|
}, [appearance]);
|
|
450
|
-
|
|
511
|
+
React2.useEffect(() => {
|
|
451
512
|
let cancelled = false;
|
|
452
513
|
async function bootstrap() {
|
|
453
514
|
if (isDemoCheckout) {
|
|
@@ -468,6 +529,12 @@ function CimplifyCheckout({
|
|
|
468
529
|
setIsInitializing(false);
|
|
469
530
|
setErrorMessage(null);
|
|
470
531
|
}
|
|
532
|
+
client.cart.get().then((cartResult) => {
|
|
533
|
+
if (!cancelled && cartResult.ok && cartResult.value) {
|
|
534
|
+
setResolvedCart(cartResult.value);
|
|
535
|
+
}
|
|
536
|
+
}).catch(() => {
|
|
537
|
+
});
|
|
471
538
|
return;
|
|
472
539
|
}
|
|
473
540
|
if (!cancelled) {
|
|
@@ -485,7 +552,7 @@ function CimplifyCheckout({
|
|
|
485
552
|
setResolvedCartId(null);
|
|
486
553
|
setErrorMessage(message);
|
|
487
554
|
setIsInitializing(false);
|
|
488
|
-
|
|
555
|
+
fireError({ code: "BUSINESS_ID_REQUIRED", message });
|
|
489
556
|
}
|
|
490
557
|
return;
|
|
491
558
|
}
|
|
@@ -500,11 +567,14 @@ function CimplifyCheckout({
|
|
|
500
567
|
setResolvedCartId(null);
|
|
501
568
|
setErrorMessage(message);
|
|
502
569
|
setIsInitializing(false);
|
|
503
|
-
|
|
570
|
+
fireError({ code: "CART_EMPTY", message });
|
|
504
571
|
}
|
|
505
572
|
return;
|
|
506
573
|
}
|
|
507
574
|
nextCartId = cartResult.value.id;
|
|
575
|
+
if (!cancelled) {
|
|
576
|
+
setResolvedCart(cartResult.value);
|
|
577
|
+
}
|
|
508
578
|
}
|
|
509
579
|
if (!cancelled) {
|
|
510
580
|
setResolvedBusinessId(nextBusinessId);
|
|
@@ -518,7 +588,7 @@ function CimplifyCheckout({
|
|
|
518
588
|
cancelled = true;
|
|
519
589
|
};
|
|
520
590
|
}, [businessId, cartId, client, isDemoCheckout]);
|
|
521
|
-
|
|
591
|
+
React2.useEffect(() => {
|
|
522
592
|
return () => {
|
|
523
593
|
isMountedRef.current = false;
|
|
524
594
|
demoRunRef.current += 1;
|
|
@@ -526,42 +596,12 @@ function CimplifyCheckout({
|
|
|
526
596
|
activeCheckoutRef.current = null;
|
|
527
597
|
};
|
|
528
598
|
}, []);
|
|
529
|
-
|
|
530
|
-
if (isDemoCheckout || !resolvedBusinessId) {
|
|
531
|
-
elementsRef.current = null;
|
|
532
|
-
return;
|
|
533
|
-
}
|
|
534
|
-
const elements = client.elements(resolvedBusinessId, {
|
|
535
|
-
appearance: initialAppearanceRef.current,
|
|
536
|
-
linkUrl
|
|
537
|
-
});
|
|
538
|
-
elementsRef.current = elements;
|
|
539
|
-
const checkout = elements.create("checkout", {
|
|
540
|
-
orderTypes: resolvedOrderTypes,
|
|
541
|
-
defaultOrderType: resolvedOrderTypes[0]
|
|
542
|
-
});
|
|
543
|
-
if (checkoutMountRef.current) {
|
|
544
|
-
checkout.mount(checkoutMountRef.current);
|
|
545
|
-
}
|
|
546
|
-
checkout.on("order_type_changed", (data) => {
|
|
547
|
-
const typed = data;
|
|
548
|
-
if (typed.orderType) {
|
|
549
|
-
setOrderType(typed.orderType);
|
|
550
|
-
}
|
|
551
|
-
});
|
|
552
|
-
return () => {
|
|
553
|
-
activeCheckoutRef.current?.abort();
|
|
554
|
-
activeCheckoutRef.current = null;
|
|
555
|
-
elements.destroy();
|
|
556
|
-
elementsRef.current = null;
|
|
557
|
-
};
|
|
558
|
-
}, [client, resolvedBusinessId, isDemoCheckout]);
|
|
559
|
-
const handleSubmit = react.useCallback(async () => {
|
|
599
|
+
const handleSubmit = React2__default.default.useEffectEvent(async () => {
|
|
560
600
|
if (isSubmitting || isInitializing || !resolvedCartId) {
|
|
561
601
|
if (!resolvedCartId && !isInitializing) {
|
|
562
602
|
const message = "Your cart is empty. Add items before checkout.";
|
|
563
603
|
setErrorMessage(message);
|
|
564
|
-
|
|
604
|
+
fireError({ code: "CART_EMPTY", message });
|
|
565
605
|
}
|
|
566
606
|
return;
|
|
567
607
|
}
|
|
@@ -596,7 +636,7 @@ function CimplifyCheckout({
|
|
|
596
636
|
order_number: result.order?.order_number,
|
|
597
637
|
display_text: statusToLabel("success")
|
|
598
638
|
});
|
|
599
|
-
|
|
639
|
+
onComplete(result);
|
|
600
640
|
} finally {
|
|
601
641
|
if (isMountedRef.current && runId === demoRunRef.current) {
|
|
602
642
|
setIsSubmitting(false);
|
|
@@ -607,7 +647,7 @@ function CimplifyCheckout({
|
|
|
607
647
|
if (!elementsRef.current) {
|
|
608
648
|
const message = "Checkout is still initializing. Please try again.";
|
|
609
649
|
setErrorMessage(message);
|
|
610
|
-
|
|
650
|
+
fireError({ code: "CHECKOUT_NOT_READY", message });
|
|
611
651
|
setIsSubmitting(false);
|
|
612
652
|
return;
|
|
613
653
|
}
|
|
@@ -622,30 +662,65 @@ function CimplifyCheckout({
|
|
|
622
662
|
try {
|
|
623
663
|
const result = await checkout;
|
|
624
664
|
if (result.success) {
|
|
625
|
-
|
|
665
|
+
onComplete(result);
|
|
626
666
|
return;
|
|
627
667
|
}
|
|
628
668
|
const code = result.error?.code || "CHECKOUT_FAILED";
|
|
629
669
|
const message = result.error?.message || "Payment failed.";
|
|
630
670
|
setErrorMessage(message);
|
|
631
|
-
|
|
671
|
+
fireError({ code, message });
|
|
632
672
|
} finally {
|
|
633
673
|
if (isMountedRef.current) {
|
|
634
674
|
activeCheckoutRef.current = null;
|
|
635
675
|
setIsSubmitting(false);
|
|
636
676
|
}
|
|
637
677
|
}
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
678
|
+
});
|
|
679
|
+
React2.useEffect(() => {
|
|
680
|
+
if (isDemoCheckout || !resolvedBusinessId) {
|
|
681
|
+
elementsRef.current = null;
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
const elements = client.elements(resolvedBusinessId, {
|
|
685
|
+
appearance: initialAppearanceRef.current,
|
|
686
|
+
linkUrl
|
|
687
|
+
});
|
|
688
|
+
elementsRef.current = elements;
|
|
689
|
+
const checkout = elements.create("checkout", {
|
|
690
|
+
orderTypes: resolvedOrderTypes,
|
|
691
|
+
defaultOrderType: resolvedOrderTypes[0]
|
|
692
|
+
});
|
|
693
|
+
if (checkoutMountRef.current) {
|
|
694
|
+
checkout.mount(checkoutMountRef.current);
|
|
695
|
+
}
|
|
696
|
+
checkout.on("ready", () => {
|
|
697
|
+
if (resolvedCart) {
|
|
698
|
+
checkout.setCart(transformToCheckoutCart(resolvedCart));
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
checkout.on("order_type_changed", (data) => {
|
|
702
|
+
const typed = data;
|
|
703
|
+
if (typed.orderType) {
|
|
704
|
+
setOrderType(typed.orderType);
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
checkout.on("request_submit", () => {
|
|
708
|
+
void handleSubmit();
|
|
709
|
+
});
|
|
710
|
+
return () => {
|
|
711
|
+
activeCheckoutRef.current?.abort();
|
|
712
|
+
activeCheckoutRef.current = null;
|
|
713
|
+
elements.destroy();
|
|
714
|
+
elementsRef.current = null;
|
|
715
|
+
};
|
|
716
|
+
}, [client, resolvedBusinessId, isDemoCheckout]);
|
|
717
|
+
React2.useEffect(() => {
|
|
718
|
+
if (!resolvedCart || !elementsRef.current) return;
|
|
719
|
+
const checkoutElement = elementsRef.current.getElement("checkout");
|
|
720
|
+
if (checkoutElement) {
|
|
721
|
+
checkoutElement.setCart(transformToCheckoutCart(resolvedCart));
|
|
722
|
+
}
|
|
723
|
+
}, [resolvedCart]);
|
|
649
724
|
const colors = shellColors(isDark ?? false, primaryColor);
|
|
650
725
|
if (isInitializing) {
|
|
651
726
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-status": "", style: { fontSize: 13, color: colors.textSecondary }, children: "Preparing checkout..." }) });
|
|
@@ -668,28 +743,6 @@ function CimplifyCheckout({
|
|
|
668
743
|
}
|
|
669
744
|
),
|
|
670
745
|
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-section": "checkout", children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: isDemoCheckout ? void 0 : checkoutMountRef }) }),
|
|
671
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: SPACE.xl }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
672
|
-
"button",
|
|
673
|
-
{
|
|
674
|
-
type: "button",
|
|
675
|
-
onClick: handleSubmit,
|
|
676
|
-
disabled: isSubmitting,
|
|
677
|
-
style: {
|
|
678
|
-
width: "100%",
|
|
679
|
-
padding: `${SPACE.md}px ${SPACE.lg}px`,
|
|
680
|
-
borderRadius: 8,
|
|
681
|
-
border: "none",
|
|
682
|
-
background: isSubmitting ? colors.textMuted : primaryColor,
|
|
683
|
-
color: "#ffffff",
|
|
684
|
-
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
685
|
-
fontWeight: 600,
|
|
686
|
-
fontSize: 16,
|
|
687
|
-
transition: "all 150ms ease",
|
|
688
|
-
WebkitTapHighlightColor: "transparent"
|
|
689
|
-
},
|
|
690
|
-
children: isSubmitting ? "Processing..." : "Complete Order"
|
|
691
|
-
}
|
|
692
|
-
) }),
|
|
693
746
|
status && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-status": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.textSecondary }, children: statusText || statusToLabel(status) }),
|
|
694
747
|
errorMessage && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-error": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.error }, children: errorMessage })
|
|
695
748
|
] });
|
|
@@ -1299,6 +1352,13 @@ var CartOperations = class {
|
|
|
1299
1352
|
}
|
|
1300
1353
|
};
|
|
1301
1354
|
|
|
1355
|
+
// src/constants.ts
|
|
1356
|
+
var MOBILE_MONEY_PROVIDER = {
|
|
1357
|
+
MTN: "mtn",
|
|
1358
|
+
VODAFONE: "vodafone",
|
|
1359
|
+
AIRTEL: "airtel"
|
|
1360
|
+
};
|
|
1361
|
+
|
|
1302
1362
|
// src/utils/price.ts
|
|
1303
1363
|
function parsePrice(value) {
|
|
1304
1364
|
if (value === void 0 || value === null) {
|
|
@@ -1537,6 +1597,10 @@ async function openCardPopup(provider, checkoutResult, email, currency, signal)
|
|
|
1537
1597
|
}
|
|
1538
1598
|
return { success: false, error: "PROVIDER_UNAVAILABLE" };
|
|
1539
1599
|
}
|
|
1600
|
+
var VALID_MOBILE_MONEY_PROVIDERS = new Set(Object.values(MOBILE_MONEY_PROVIDER));
|
|
1601
|
+
function isValidMobileMoneyProvider(value) {
|
|
1602
|
+
return VALID_MOBILE_MONEY_PROVIDERS.has(value);
|
|
1603
|
+
}
|
|
1540
1604
|
function normalizeAuthorizationType(value) {
|
|
1541
1605
|
return value === "otp" || value === "pin" ? value : void 0;
|
|
1542
1606
|
}
|
|
@@ -1769,6 +1833,16 @@ var CheckoutResolver = class {
|
|
|
1769
1833
|
}
|
|
1770
1834
|
await this.wait(this.pollIntervalMs);
|
|
1771
1835
|
}
|
|
1836
|
+
try {
|
|
1837
|
+
const finalResult = await this.client.checkout.pollPaymentStatus(input.orderId);
|
|
1838
|
+
if (finalResult.ok) {
|
|
1839
|
+
const normalized = normalizeStatusResponse(finalResult.value);
|
|
1840
|
+
if (normalized.paid || isPaymentStatusSuccess(normalized.status)) {
|
|
1841
|
+
return this.finalizeSuccess(latestCheckoutResult);
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
} catch {
|
|
1845
|
+
}
|
|
1772
1846
|
return this.fail(
|
|
1773
1847
|
"PAYMENT_TIMEOUT",
|
|
1774
1848
|
"Payment confirmation timed out. Please retry checkout.",
|
|
@@ -1899,7 +1973,7 @@ var CheckoutResolver = class {
|
|
|
1899
1973
|
};
|
|
1900
1974
|
}
|
|
1901
1975
|
getEnrollmentMobileMoney() {
|
|
1902
|
-
if (this.paymentData?.type === "mobile_money" && this.paymentData.phone_number && this.paymentData.provider) {
|
|
1976
|
+
if (this.paymentData?.type === "mobile_money" && this.paymentData.phone_number && this.paymentData.provider && isValidMobileMoneyProvider(this.paymentData.provider)) {
|
|
1903
1977
|
return {
|
|
1904
1978
|
phone_number: this.paymentData.phone_number,
|
|
1905
1979
|
provider: this.paymentData.provider,
|
|
@@ -2973,8 +3047,10 @@ var CimplifyElements = class {
|
|
|
2973
3047
|
false
|
|
2974
3048
|
);
|
|
2975
3049
|
}
|
|
3050
|
+
this.checkoutInProgress = true;
|
|
2976
3051
|
if (!options.cart_id) {
|
|
2977
3052
|
console.debug("[cimplify:checkout] BLOCKED: no cart_id");
|
|
3053
|
+
this.checkoutInProgress = false;
|
|
2978
3054
|
return toCheckoutError(
|
|
2979
3055
|
"INVALID_CART",
|
|
2980
3056
|
"A valid cart is required before checkout can start.",
|
|
@@ -2983,6 +3059,7 @@ var CimplifyElements = class {
|
|
|
2983
3059
|
}
|
|
2984
3060
|
if (!options.order_type) {
|
|
2985
3061
|
console.debug("[cimplify:checkout] BLOCKED: no order_type");
|
|
3062
|
+
this.checkoutInProgress = false;
|
|
2986
3063
|
return toCheckoutError(
|
|
2987
3064
|
"ORDER_TYPE_REQUIRED",
|
|
2988
3065
|
"Order type is required before checkout can start.",
|
|
@@ -2992,6 +3069,7 @@ var CimplifyElements = class {
|
|
|
2992
3069
|
const checkoutElement = this.elements.get(ELEMENT_TYPES.CHECKOUT) || this.elements.get(ELEMENT_TYPES.PAYMENT);
|
|
2993
3070
|
if (!checkoutElement) {
|
|
2994
3071
|
console.debug("[cimplify:checkout] BLOCKED: no checkout element");
|
|
3072
|
+
this.checkoutInProgress = false;
|
|
2995
3073
|
return toCheckoutError(
|
|
2996
3074
|
"NO_PAYMENT_ELEMENT",
|
|
2997
3075
|
"Checkout element must be mounted before checkout.",
|
|
@@ -3000,6 +3078,7 @@ var CimplifyElements = class {
|
|
|
3000
3078
|
}
|
|
3001
3079
|
if (!checkoutElement.isMounted()) {
|
|
3002
3080
|
console.debug("[cimplify:checkout] BLOCKED: checkout element not mounted");
|
|
3081
|
+
this.checkoutInProgress = false;
|
|
3003
3082
|
return toCheckoutError(
|
|
3004
3083
|
"PAYMENT_NOT_MOUNTED",
|
|
3005
3084
|
"Checkout element must be mounted before checkout.",
|
|
@@ -3011,6 +3090,7 @@ var CimplifyElements = class {
|
|
|
3011
3090
|
const authElement = this.elements.get(ELEMENT_TYPES.AUTH);
|
|
3012
3091
|
if (authElement && !this.accessToken) {
|
|
3013
3092
|
console.debug("[cimplify:checkout] BLOCKED: auth incomplete");
|
|
3093
|
+
this.checkoutInProgress = false;
|
|
3014
3094
|
return toCheckoutError(
|
|
3015
3095
|
"AUTH_INCOMPLETE",
|
|
3016
3096
|
"Authentication must complete before checkout can start.",
|
|
@@ -3048,7 +3128,6 @@ var CimplifyElements = class {
|
|
|
3048
3128
|
};
|
|
3049
3129
|
const timeoutMs = options.timeout_ms ?? 18e4;
|
|
3050
3130
|
const paymentWindow = checkoutElement.getContentWindow();
|
|
3051
|
-
this.checkoutInProgress = true;
|
|
3052
3131
|
return new Promise((resolve) => {
|
|
3053
3132
|
let settled = false;
|
|
3054
3133
|
const cleanup = () => {
|
|
@@ -3343,6 +3422,9 @@ var CimplifyElement = class {
|
|
|
3343
3422
|
this.sendMessage({ type: MESSAGE_TYPES.GET_DATA });
|
|
3344
3423
|
});
|
|
3345
3424
|
}
|
|
3425
|
+
setCart(cart) {
|
|
3426
|
+
this.sendMessage({ type: MESSAGE_TYPES.SET_CART, cart });
|
|
3427
|
+
}
|
|
3346
3428
|
sendMessage(message) {
|
|
3347
3429
|
if (this.iframe?.contentWindow) {
|
|
3348
3430
|
this.iframe.contentWindow.postMessage(message, this.linkUrl);
|
|
@@ -3398,7 +3480,8 @@ var CimplifyElement = class {
|
|
|
3398
3480
|
prefillEmail: this.options.prefillEmail,
|
|
3399
3481
|
appearance: this.parent.getAppearance(),
|
|
3400
3482
|
orderTypes: this.options.orderTypes,
|
|
3401
|
-
defaultOrderType: this.options.defaultOrderType
|
|
3483
|
+
defaultOrderType: this.options.defaultOrderType,
|
|
3484
|
+
renderSubmitButton: true
|
|
3402
3485
|
});
|
|
3403
3486
|
const token = this.parent.getAccessToken();
|
|
3404
3487
|
if (token && this.type !== ELEMENT_TYPES.AUTH) {
|
|
@@ -3465,6 +3548,9 @@ var CimplifyElement = class {
|
|
|
3465
3548
|
case MESSAGE_TYPES.ORDER_TYPE_CHANGED:
|
|
3466
3549
|
this.emit(EVENT_TYPES.ORDER_TYPE_CHANGED, { orderType: message.orderType });
|
|
3467
3550
|
break;
|
|
3551
|
+
case MESSAGE_TYPES.REQUEST_SUBMIT:
|
|
3552
|
+
this.emit(EVENT_TYPES.REQUEST_SUBMIT, {});
|
|
3553
|
+
break;
|
|
3468
3554
|
}
|
|
3469
3555
|
}
|
|
3470
3556
|
emit(event, data) {
|
|
@@ -3487,6 +3573,7 @@ var ACCESS_TOKEN_STORAGE_KEY = "cimplify_access_token";
|
|
|
3487
3573
|
var SESSION_TOKEN_STORAGE_KEY = "cimplify_session_token";
|
|
3488
3574
|
var ORDER_TOKEN_PREFIX = "cimplify_ot_";
|
|
3489
3575
|
var SESSION_TOKEN_HEADER = "x-session-token";
|
|
3576
|
+
var ORDER_TOKEN_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
3490
3577
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
3491
3578
|
var DEFAULT_MAX_RETRIES = 3;
|
|
3492
3579
|
var DEFAULT_RETRY_DELAY_MS = 1e3;
|
|
@@ -3636,12 +3723,27 @@ var CimplifyClient = class {
|
|
|
3636
3723
|
}
|
|
3637
3724
|
setOrderToken(orderId, token) {
|
|
3638
3725
|
if (typeof window !== "undefined" && window.localStorage) {
|
|
3639
|
-
|
|
3726
|
+
try {
|
|
3727
|
+
const entry = JSON.stringify({ token, storedAt: Date.now() });
|
|
3728
|
+
localStorage.setItem(`${ORDER_TOKEN_PREFIX}${orderId}`, entry);
|
|
3729
|
+
} catch {
|
|
3730
|
+
}
|
|
3640
3731
|
}
|
|
3641
3732
|
}
|
|
3642
3733
|
getOrderToken(orderId) {
|
|
3643
3734
|
if (typeof window !== "undefined" && window.localStorage) {
|
|
3644
|
-
|
|
3735
|
+
try {
|
|
3736
|
+
const raw = localStorage.getItem(`${ORDER_TOKEN_PREFIX}${orderId}`);
|
|
3737
|
+
if (!raw) return null;
|
|
3738
|
+
const entry = JSON.parse(raw);
|
|
3739
|
+
if (Date.now() - entry.storedAt > ORDER_TOKEN_TTL_MS) {
|
|
3740
|
+
localStorage.removeItem(`${ORDER_TOKEN_PREFIX}${orderId}`);
|
|
3741
|
+
return null;
|
|
3742
|
+
}
|
|
3743
|
+
return entry.token;
|
|
3744
|
+
} catch {
|
|
3745
|
+
return null;
|
|
3746
|
+
}
|
|
3645
3747
|
}
|
|
3646
3748
|
return null;
|
|
3647
3749
|
}
|
|
@@ -3717,10 +3819,13 @@ var CimplifyClient = class {
|
|
|
3717
3819
|
}
|
|
3718
3820
|
saveAccessToken(token) {
|
|
3719
3821
|
if (typeof window !== "undefined" && window.localStorage) {
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3822
|
+
try {
|
|
3823
|
+
if (token) {
|
|
3824
|
+
localStorage.setItem(ACCESS_TOKEN_STORAGE_KEY, token);
|
|
3825
|
+
} else {
|
|
3826
|
+
localStorage.removeItem(ACCESS_TOKEN_STORAGE_KEY);
|
|
3827
|
+
}
|
|
3828
|
+
} catch {
|
|
3724
3829
|
}
|
|
3725
3830
|
}
|
|
3726
3831
|
}
|
|
@@ -3793,6 +3898,19 @@ var CimplifyClient = class {
|
|
|
3793
3898
|
});
|
|
3794
3899
|
return response;
|
|
3795
3900
|
}
|
|
3901
|
+
if (response.status === 429 && attempt < this.maxRetries) {
|
|
3902
|
+
retryCount++;
|
|
3903
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
3904
|
+
const delay = retryAfter ? Math.min(parseInt(retryAfter, 10) * 1e3, 3e4) || this.retryDelay * Math.pow(2, attempt) : this.retryDelay * Math.pow(2, attempt);
|
|
3905
|
+
this.hooks.onRetry?.({
|
|
3906
|
+
...context,
|
|
3907
|
+
attempt: retryCount,
|
|
3908
|
+
delayMs: delay,
|
|
3909
|
+
error: new Error(`Rate limited: ${response.status}`)
|
|
3910
|
+
});
|
|
3911
|
+
await sleep(delay);
|
|
3912
|
+
continue;
|
|
3913
|
+
}
|
|
3796
3914
|
if (response.status >= 400 && response.status < 500) {
|
|
3797
3915
|
this.hooks.onRequestError?.({
|
|
3798
3916
|
...context,
|
|
@@ -4116,23 +4234,23 @@ function resolveInitialLocation(locations) {
|
|
|
4116
4234
|
}
|
|
4117
4235
|
return locations[0];
|
|
4118
4236
|
}
|
|
4119
|
-
var CimplifyContext =
|
|
4237
|
+
var CimplifyContext = React2.createContext(null);
|
|
4120
4238
|
function CimplifyProvider({
|
|
4121
4239
|
client,
|
|
4122
4240
|
children,
|
|
4123
4241
|
onLocationChange
|
|
4124
4242
|
}) {
|
|
4125
|
-
const resolvedClient =
|
|
4126
|
-
const onLocationChangeRef =
|
|
4127
|
-
const [business, setBusiness] =
|
|
4128
|
-
const [locations, setLocations] =
|
|
4129
|
-
const [currentLocation, setCurrentLocationState] =
|
|
4130
|
-
const [isReady, setIsReady] =
|
|
4131
|
-
|
|
4243
|
+
const resolvedClient = React2.useMemo(() => client ?? createDefaultClient(), [client]);
|
|
4244
|
+
const onLocationChangeRef = React2.useRef(onLocationChange);
|
|
4245
|
+
const [business, setBusiness] = React2.useState(null);
|
|
4246
|
+
const [locations, setLocations] = React2.useState([]);
|
|
4247
|
+
const [currentLocation, setCurrentLocationState] = React2.useState(null);
|
|
4248
|
+
const [isReady, setIsReady] = React2.useState(false);
|
|
4249
|
+
React2.useEffect(() => {
|
|
4132
4250
|
onLocationChangeRef.current = onLocationChange;
|
|
4133
4251
|
}, [onLocationChange]);
|
|
4134
4252
|
const isDemoMode = resolvedClient.getPublicKey().trim().length === 0;
|
|
4135
|
-
const setCurrentLocation =
|
|
4253
|
+
const setCurrentLocation = React2.useCallback(
|
|
4136
4254
|
(location) => {
|
|
4137
4255
|
setCurrentLocationState(location);
|
|
4138
4256
|
resolvedClient.setLocationId(location.id);
|
|
@@ -4141,7 +4259,7 @@ function CimplifyProvider({
|
|
|
4141
4259
|
},
|
|
4142
4260
|
[resolvedClient]
|
|
4143
4261
|
);
|
|
4144
|
-
|
|
4262
|
+
React2.useEffect(() => {
|
|
4145
4263
|
let cancelled = false;
|
|
4146
4264
|
async function bootstrap() {
|
|
4147
4265
|
setIsReady(false);
|
|
@@ -4197,7 +4315,7 @@ function CimplifyProvider({
|
|
|
4197
4315
|
cancelled = true;
|
|
4198
4316
|
};
|
|
4199
4317
|
}, [resolvedClient, isDemoMode]);
|
|
4200
|
-
const contextValue =
|
|
4318
|
+
const contextValue = React2.useMemo(
|
|
4201
4319
|
() => ({
|
|
4202
4320
|
client: resolvedClient,
|
|
4203
4321
|
business,
|
|
@@ -4222,14 +4340,14 @@ function CimplifyProvider({
|
|
|
4222
4340
|
return /* @__PURE__ */ jsxRuntime.jsx(CimplifyContext.Provider, { value: contextValue, children });
|
|
4223
4341
|
}
|
|
4224
4342
|
function useCimplify() {
|
|
4225
|
-
const context =
|
|
4343
|
+
const context = React2.useContext(CimplifyContext);
|
|
4226
4344
|
if (!context) {
|
|
4227
4345
|
throw new Error("useCimplify must be used within CimplifyProvider");
|
|
4228
4346
|
}
|
|
4229
4347
|
return context;
|
|
4230
4348
|
}
|
|
4231
4349
|
function useOptionalCimplify() {
|
|
4232
|
-
return
|
|
4350
|
+
return React2.useContext(CimplifyContext);
|
|
4233
4351
|
}
|
|
4234
4352
|
var productsCache = /* @__PURE__ */ new Map();
|
|
4235
4353
|
var productsInflight = /* @__PURE__ */ new Map();
|
|
@@ -4248,9 +4366,9 @@ function useProducts(options = {}) {
|
|
|
4248
4366
|
}
|
|
4249
4367
|
const enabled = options.enabled ?? true;
|
|
4250
4368
|
const locationId = client.getLocationId();
|
|
4251
|
-
const previousLocationIdRef =
|
|
4252
|
-
const requestIdRef =
|
|
4253
|
-
const queryOptions =
|
|
4369
|
+
const previousLocationIdRef = React2.useRef(locationId);
|
|
4370
|
+
const requestIdRef = React2.useRef(0);
|
|
4371
|
+
const queryOptions = React2.useMemo(
|
|
4254
4372
|
() => ({
|
|
4255
4373
|
category: options.category,
|
|
4256
4374
|
collection: options.collection,
|
|
@@ -4260,25 +4378,25 @@ function useProducts(options = {}) {
|
|
|
4260
4378
|
}),
|
|
4261
4379
|
[options.category, options.collection, options.featured, options.limit, options.search]
|
|
4262
4380
|
);
|
|
4263
|
-
const cacheKey =
|
|
4381
|
+
const cacheKey = React2.useMemo(
|
|
4264
4382
|
() => buildProductsCacheKey(client, locationId, queryOptions),
|
|
4265
4383
|
[client, locationId, queryOptions]
|
|
4266
4384
|
);
|
|
4267
4385
|
const cached = productsCache.get(cacheKey);
|
|
4268
|
-
const [products, setProducts] =
|
|
4269
|
-
const [isComplete, setIsComplete] =
|
|
4270
|
-
const [totalAvailable, setTotalAvailable] =
|
|
4271
|
-
const [pagination, setPagination] =
|
|
4272
|
-
const [isLoading, setIsLoading] =
|
|
4273
|
-
const [error, setError] =
|
|
4274
|
-
|
|
4386
|
+
const [products, setProducts] = React2.useState(cached?.products ?? []);
|
|
4387
|
+
const [isComplete, setIsComplete] = React2.useState(cached?.is_complete ?? true);
|
|
4388
|
+
const [totalAvailable, setTotalAvailable] = React2.useState(cached?.total_available);
|
|
4389
|
+
const [pagination, setPagination] = React2.useState(cached?.pagination);
|
|
4390
|
+
const [isLoading, setIsLoading] = React2.useState(enabled && !cached);
|
|
4391
|
+
const [error, setError] = React2.useState(null);
|
|
4392
|
+
React2.useEffect(() => {
|
|
4275
4393
|
if (previousLocationIdRef.current !== locationId) {
|
|
4276
4394
|
productsCache.clear();
|
|
4277
4395
|
productsInflight.clear();
|
|
4278
4396
|
previousLocationIdRef.current = locationId;
|
|
4279
4397
|
}
|
|
4280
4398
|
}, [locationId]);
|
|
4281
|
-
const load =
|
|
4399
|
+
const load = React2.useCallback(
|
|
4282
4400
|
async (force = false) => {
|
|
4283
4401
|
if (!enabled) {
|
|
4284
4402
|
setIsLoading(false);
|
|
@@ -4341,10 +4459,10 @@ function useProducts(options = {}) {
|
|
|
4341
4459
|
},
|
|
4342
4460
|
[cacheKey, client, enabled, queryOptions]
|
|
4343
4461
|
);
|
|
4344
|
-
|
|
4462
|
+
React2.useEffect(() => {
|
|
4345
4463
|
void load(false);
|
|
4346
4464
|
}, [load]);
|
|
4347
|
-
const refetch =
|
|
4465
|
+
const refetch = React2.useCallback(async () => {
|
|
4348
4466
|
productsCache.delete(cacheKey);
|
|
4349
4467
|
await load(true);
|
|
4350
4468
|
}, [cacheKey, load]);
|
|
@@ -4378,27 +4496,27 @@ function useProduct(slugOrId, options = {}) {
|
|
|
4378
4496
|
}
|
|
4379
4497
|
const enabled = options.enabled ?? true;
|
|
4380
4498
|
const locationId = client.getLocationId();
|
|
4381
|
-
const previousLocationIdRef =
|
|
4382
|
-
const requestIdRef =
|
|
4383
|
-
const normalizedSlugOrId =
|
|
4384
|
-
const cacheKey =
|
|
4499
|
+
const previousLocationIdRef = React2.useRef(locationId);
|
|
4500
|
+
const requestIdRef = React2.useRef(0);
|
|
4501
|
+
const normalizedSlugOrId = React2.useMemo(() => (slugOrId || "").trim(), [slugOrId]);
|
|
4502
|
+
const cacheKey = React2.useMemo(
|
|
4385
4503
|
() => buildProductCacheKey(client, locationId, normalizedSlugOrId),
|
|
4386
4504
|
[client, locationId, normalizedSlugOrId]
|
|
4387
4505
|
);
|
|
4388
4506
|
const cached = productCache.get(cacheKey);
|
|
4389
|
-
const [product, setProduct] =
|
|
4390
|
-
const [isLoading, setIsLoading] =
|
|
4507
|
+
const [product, setProduct] = React2.useState(cached?.product ?? null);
|
|
4508
|
+
const [isLoading, setIsLoading] = React2.useState(
|
|
4391
4509
|
enabled && normalizedSlugOrId.length > 0 && !cached
|
|
4392
4510
|
);
|
|
4393
|
-
const [error, setError] =
|
|
4394
|
-
|
|
4511
|
+
const [error, setError] = React2.useState(null);
|
|
4512
|
+
React2.useEffect(() => {
|
|
4395
4513
|
if (previousLocationIdRef.current !== locationId) {
|
|
4396
4514
|
productCache.clear();
|
|
4397
4515
|
productInflight.clear();
|
|
4398
4516
|
previousLocationIdRef.current = locationId;
|
|
4399
4517
|
}
|
|
4400
4518
|
}, [locationId]);
|
|
4401
|
-
const load =
|
|
4519
|
+
const load = React2.useCallback(
|
|
4402
4520
|
async (force = false) => {
|
|
4403
4521
|
if (!enabled || normalizedSlugOrId.length === 0) {
|
|
4404
4522
|
setProduct(null);
|
|
@@ -4451,10 +4569,10 @@ function useProduct(slugOrId, options = {}) {
|
|
|
4451
4569
|
},
|
|
4452
4570
|
[cacheKey, client, enabled, normalizedSlugOrId]
|
|
4453
4571
|
);
|
|
4454
|
-
|
|
4572
|
+
React2.useEffect(() => {
|
|
4455
4573
|
void load(false);
|
|
4456
4574
|
}, [load]);
|
|
4457
|
-
const refetch =
|
|
4575
|
+
const refetch = React2.useCallback(async () => {
|
|
4458
4576
|
productCache.delete(cacheKey);
|
|
4459
4577
|
await load(true);
|
|
4460
4578
|
}, [cacheKey, load]);
|
|
@@ -4472,12 +4590,12 @@ function useCategories(options = {}) {
|
|
|
4472
4590
|
throw new Error("useCategories must be used within CimplifyProvider or passed { client }.");
|
|
4473
4591
|
}
|
|
4474
4592
|
const enabled = options.enabled ?? true;
|
|
4475
|
-
const cacheKey =
|
|
4593
|
+
const cacheKey = React2.useMemo(() => buildCategoriesCacheKey(client), [client]);
|
|
4476
4594
|
const cached = categoriesCache.get(cacheKey);
|
|
4477
|
-
const [categories, setCategories] =
|
|
4478
|
-
const [isLoading, setIsLoading] =
|
|
4479
|
-
const [error, setError] =
|
|
4480
|
-
const load =
|
|
4595
|
+
const [categories, setCategories] = React2.useState(cached ?? []);
|
|
4596
|
+
const [isLoading, setIsLoading] = React2.useState(enabled && !cached);
|
|
4597
|
+
const [error, setError] = React2.useState(null);
|
|
4598
|
+
const load = React2.useCallback(
|
|
4481
4599
|
async (force = false) => {
|
|
4482
4600
|
if (!enabled) {
|
|
4483
4601
|
setIsLoading(false);
|
|
@@ -4521,10 +4639,10 @@ function useCategories(options = {}) {
|
|
|
4521
4639
|
},
|
|
4522
4640
|
[cacheKey, client, enabled]
|
|
4523
4641
|
);
|
|
4524
|
-
|
|
4642
|
+
React2.useEffect(() => {
|
|
4525
4643
|
void load(false);
|
|
4526
4644
|
}, [load]);
|
|
4527
|
-
const refetch =
|
|
4645
|
+
const refetch = React2.useCallback(async () => {
|
|
4528
4646
|
categoriesCache.delete(cacheKey);
|
|
4529
4647
|
await load(true);
|
|
4530
4648
|
}, [cacheKey, load]);
|
|
@@ -5045,7 +5163,7 @@ function useCart(options = {}) {
|
|
|
5045
5163
|
const locationId = options.locationId ?? client.getLocationId();
|
|
5046
5164
|
const isDemoMode = options.demoMode ?? context?.isDemoMode ?? client.getPublicKey().trim().length === 0;
|
|
5047
5165
|
const currency = options.currency ?? context?.currency ?? "USD";
|
|
5048
|
-
const store =
|
|
5166
|
+
const store = React2.useMemo(
|
|
5049
5167
|
() => getOrCreateStore({
|
|
5050
5168
|
client,
|
|
5051
5169
|
locationId,
|
|
@@ -5054,43 +5172,43 @@ function useCart(options = {}) {
|
|
|
5054
5172
|
}),
|
|
5055
5173
|
[client, currency, isDemoMode, locationId]
|
|
5056
5174
|
);
|
|
5057
|
-
const snapshot =
|
|
5175
|
+
const snapshot = React2.useSyncExternalStore(
|
|
5058
5176
|
store.subscribe,
|
|
5059
5177
|
store.getSnapshot,
|
|
5060
5178
|
store.getSnapshot
|
|
5061
5179
|
);
|
|
5062
|
-
|
|
5180
|
+
React2.useEffect(() => {
|
|
5063
5181
|
void store.initialize();
|
|
5064
5182
|
}, [store]);
|
|
5065
|
-
const addItem =
|
|
5183
|
+
const addItem = React2.useCallback(
|
|
5066
5184
|
async (product, quantity, addOptions) => {
|
|
5067
5185
|
await store.addItem(product, quantity, addOptions);
|
|
5068
5186
|
},
|
|
5069
5187
|
[store]
|
|
5070
5188
|
);
|
|
5071
|
-
const removeItem =
|
|
5189
|
+
const removeItem = React2.useCallback(
|
|
5072
5190
|
async (itemId) => {
|
|
5073
5191
|
await store.removeItem(itemId);
|
|
5074
5192
|
},
|
|
5075
5193
|
[store]
|
|
5076
5194
|
);
|
|
5077
|
-
const updateQuantity =
|
|
5195
|
+
const updateQuantity = React2.useCallback(
|
|
5078
5196
|
async (itemId, quantity) => {
|
|
5079
5197
|
await store.updateQuantity(itemId, quantity);
|
|
5080
5198
|
},
|
|
5081
5199
|
[store]
|
|
5082
5200
|
);
|
|
5083
|
-
const clearCart =
|
|
5201
|
+
const clearCart = React2.useCallback(async () => {
|
|
5084
5202
|
await store.clearCart();
|
|
5085
5203
|
}, [store]);
|
|
5086
|
-
const sync =
|
|
5204
|
+
const sync = React2.useCallback(async () => {
|
|
5087
5205
|
try {
|
|
5088
5206
|
await store.sync();
|
|
5089
5207
|
} catch (syncError) {
|
|
5090
5208
|
throw syncError;
|
|
5091
5209
|
}
|
|
5092
5210
|
}, [store]);
|
|
5093
|
-
const itemCount =
|
|
5211
|
+
const itemCount = React2.useMemo(
|
|
5094
5212
|
() => snapshot.items.reduce((sum, item) => sum + item.quantity, 0),
|
|
5095
5213
|
[snapshot.items]
|
|
5096
5214
|
);
|
|
@@ -5121,22 +5239,22 @@ function useOrder(orderId, options = {}) {
|
|
|
5121
5239
|
if (!client) {
|
|
5122
5240
|
throw new Error("useOrder must be used within CimplifyProvider or passed { client }.");
|
|
5123
5241
|
}
|
|
5124
|
-
const normalizedOrderId =
|
|
5242
|
+
const normalizedOrderId = React2.useMemo(() => (orderId || "").trim(), [orderId]);
|
|
5125
5243
|
const enabled = options.enabled ?? true;
|
|
5126
5244
|
const poll = options.poll ?? false;
|
|
5127
5245
|
const pollInterval = options.pollInterval ?? 5e3;
|
|
5128
|
-
const requestIdRef =
|
|
5129
|
-
const cacheKey =
|
|
5246
|
+
const requestIdRef = React2.useRef(0);
|
|
5247
|
+
const cacheKey = React2.useMemo(
|
|
5130
5248
|
() => buildOrderCacheKey(client, normalizedOrderId),
|
|
5131
5249
|
[client, normalizedOrderId]
|
|
5132
5250
|
);
|
|
5133
5251
|
const cached = orderCache.get(cacheKey);
|
|
5134
|
-
const [order, setOrder] =
|
|
5135
|
-
const [isLoading, setIsLoading] =
|
|
5252
|
+
const [order, setOrder] = React2.useState(cached?.order ?? null);
|
|
5253
|
+
const [isLoading, setIsLoading] = React2.useState(
|
|
5136
5254
|
enabled && normalizedOrderId.length > 0 && !cached
|
|
5137
5255
|
);
|
|
5138
|
-
const [error, setError] =
|
|
5139
|
-
const load =
|
|
5256
|
+
const [error, setError] = React2.useState(null);
|
|
5257
|
+
const load = React2.useCallback(
|
|
5140
5258
|
async (force = false) => {
|
|
5141
5259
|
if (!enabled || normalizedOrderId.length === 0) {
|
|
5142
5260
|
setOrder(null);
|
|
@@ -5189,10 +5307,10 @@ function useOrder(orderId, options = {}) {
|
|
|
5189
5307
|
},
|
|
5190
5308
|
[cacheKey, client, enabled, normalizedOrderId]
|
|
5191
5309
|
);
|
|
5192
|
-
|
|
5310
|
+
React2.useEffect(() => {
|
|
5193
5311
|
void load(false);
|
|
5194
5312
|
}, [load]);
|
|
5195
|
-
|
|
5313
|
+
React2.useEffect(() => {
|
|
5196
5314
|
if (!poll || !enabled || normalizedOrderId.length === 0) {
|
|
5197
5315
|
return;
|
|
5198
5316
|
}
|
|
@@ -5203,7 +5321,7 @@ function useOrder(orderId, options = {}) {
|
|
|
5203
5321
|
window.clearInterval(timer);
|
|
5204
5322
|
};
|
|
5205
5323
|
}, [enabled, load, normalizedOrderId.length, poll, pollInterval]);
|
|
5206
|
-
const refetch =
|
|
5324
|
+
const refetch = React2.useCallback(async () => {
|
|
5207
5325
|
orderCache.delete(cacheKey);
|
|
5208
5326
|
await load(true);
|
|
5209
5327
|
}, [cacheKey, load]);
|
|
@@ -5254,10 +5372,10 @@ function useLocations(options = {}) {
|
|
|
5254
5372
|
};
|
|
5255
5373
|
}
|
|
5256
5374
|
const client = options.client;
|
|
5257
|
-
const [locations, setLocations] =
|
|
5258
|
-
const [currentLocation, setCurrentLocationState] =
|
|
5259
|
-
const [isLoading, setIsLoading] =
|
|
5260
|
-
const setCurrentLocation =
|
|
5375
|
+
const [locations, setLocations] = React2.useState([]);
|
|
5376
|
+
const [currentLocation, setCurrentLocationState] = React2.useState(null);
|
|
5377
|
+
const [isLoading, setIsLoading] = React2.useState(true);
|
|
5378
|
+
const setCurrentLocation = React2.useCallback(
|
|
5261
5379
|
(location) => {
|
|
5262
5380
|
setCurrentLocationState(location);
|
|
5263
5381
|
if (client) {
|
|
@@ -5267,7 +5385,7 @@ function useLocations(options = {}) {
|
|
|
5267
5385
|
},
|
|
5268
5386
|
[client]
|
|
5269
5387
|
);
|
|
5270
|
-
|
|
5388
|
+
React2.useEffect(() => {
|
|
5271
5389
|
if (!client) {
|
|
5272
5390
|
setLocations([]);
|
|
5273
5391
|
setCurrentLocationState(null);
|
|
@@ -5325,24 +5443,24 @@ function useCollections(options = {}) {
|
|
|
5325
5443
|
}
|
|
5326
5444
|
const enabled = options.enabled ?? true;
|
|
5327
5445
|
const locationId = client.getLocationId();
|
|
5328
|
-
const previousLocationIdRef =
|
|
5329
|
-
const requestIdRef =
|
|
5330
|
-
const cacheKey =
|
|
5446
|
+
const previousLocationIdRef = React2.useRef(locationId);
|
|
5447
|
+
const requestIdRef = React2.useRef(0);
|
|
5448
|
+
const cacheKey = React2.useMemo(
|
|
5331
5449
|
() => buildCollectionsCacheKey(client, locationId),
|
|
5332
5450
|
[client, locationId]
|
|
5333
5451
|
);
|
|
5334
5452
|
const cached = collectionsCache.get(cacheKey);
|
|
5335
|
-
const [collections, setCollections] =
|
|
5336
|
-
const [isLoading, setIsLoading] =
|
|
5337
|
-
const [error, setError] =
|
|
5338
|
-
|
|
5453
|
+
const [collections, setCollections] = React2.useState(cached?.collections ?? []);
|
|
5454
|
+
const [isLoading, setIsLoading] = React2.useState(enabled && !cached);
|
|
5455
|
+
const [error, setError] = React2.useState(null);
|
|
5456
|
+
React2.useEffect(() => {
|
|
5339
5457
|
if (previousLocationIdRef.current !== locationId) {
|
|
5340
5458
|
collectionsCache.clear();
|
|
5341
5459
|
collectionsInflight.clear();
|
|
5342
5460
|
previousLocationIdRef.current = locationId;
|
|
5343
5461
|
}
|
|
5344
5462
|
}, [locationId]);
|
|
5345
|
-
const load =
|
|
5463
|
+
const load = React2.useCallback(
|
|
5346
5464
|
async (force = false) => {
|
|
5347
5465
|
if (!enabled) {
|
|
5348
5466
|
setIsLoading(false);
|
|
@@ -5392,10 +5510,10 @@ function useCollections(options = {}) {
|
|
|
5392
5510
|
},
|
|
5393
5511
|
[cacheKey, client, enabled]
|
|
5394
5512
|
);
|
|
5395
|
-
|
|
5513
|
+
React2.useEffect(() => {
|
|
5396
5514
|
void load(false);
|
|
5397
5515
|
}, [load]);
|
|
5398
|
-
const refetch =
|
|
5516
|
+
const refetch = React2.useCallback(async () => {
|
|
5399
5517
|
collectionsCache.delete(cacheKey);
|
|
5400
5518
|
await load(true);
|
|
5401
5519
|
}, [cacheKey, load]);
|
|
@@ -5421,28 +5539,28 @@ function useCollection(idOrSlug, options = {}) {
|
|
|
5421
5539
|
}
|
|
5422
5540
|
const enabled = options.enabled ?? true;
|
|
5423
5541
|
const locationId = client.getLocationId();
|
|
5424
|
-
const previousLocationIdRef =
|
|
5425
|
-
const requestIdRef =
|
|
5426
|
-
const normalizedIdOrSlug =
|
|
5427
|
-
const cacheKey =
|
|
5542
|
+
const previousLocationIdRef = React2.useRef(locationId);
|
|
5543
|
+
const requestIdRef = React2.useRef(0);
|
|
5544
|
+
const normalizedIdOrSlug = React2.useMemo(() => (idOrSlug || "").trim(), [idOrSlug]);
|
|
5545
|
+
const cacheKey = React2.useMemo(
|
|
5428
5546
|
() => buildCollectionCacheKey(client, locationId, normalizedIdOrSlug),
|
|
5429
5547
|
[client, locationId, normalizedIdOrSlug]
|
|
5430
5548
|
);
|
|
5431
5549
|
const cached = collectionCache.get(cacheKey);
|
|
5432
|
-
const [collection, setCollection] =
|
|
5433
|
-
const [products, setProducts] =
|
|
5434
|
-
const [isLoading, setIsLoading] =
|
|
5550
|
+
const [collection, setCollection] = React2.useState(cached?.collection ?? null);
|
|
5551
|
+
const [products, setProducts] = React2.useState(cached?.products ?? []);
|
|
5552
|
+
const [isLoading, setIsLoading] = React2.useState(
|
|
5435
5553
|
enabled && normalizedIdOrSlug.length > 0 && !cached
|
|
5436
5554
|
);
|
|
5437
|
-
const [error, setError] =
|
|
5438
|
-
|
|
5555
|
+
const [error, setError] = React2.useState(null);
|
|
5556
|
+
React2.useEffect(() => {
|
|
5439
5557
|
if (previousLocationIdRef.current !== locationId) {
|
|
5440
5558
|
collectionCache.clear();
|
|
5441
5559
|
collectionInflight.clear();
|
|
5442
5560
|
previousLocationIdRef.current = locationId;
|
|
5443
5561
|
}
|
|
5444
5562
|
}, [locationId]);
|
|
5445
|
-
const load =
|
|
5563
|
+
const load = React2.useCallback(
|
|
5446
5564
|
async (force = false) => {
|
|
5447
5565
|
if (!enabled || normalizedIdOrSlug.length === 0) {
|
|
5448
5566
|
setCollection(null);
|
|
@@ -5505,10 +5623,10 @@ function useCollection(idOrSlug, options = {}) {
|
|
|
5505
5623
|
},
|
|
5506
5624
|
[cacheKey, client, enabled, normalizedIdOrSlug]
|
|
5507
5625
|
);
|
|
5508
|
-
|
|
5626
|
+
React2.useEffect(() => {
|
|
5509
5627
|
void load(false);
|
|
5510
5628
|
}, [load]);
|
|
5511
|
-
const refetch =
|
|
5629
|
+
const refetch = React2.useCallback(async () => {
|
|
5512
5630
|
collectionCache.delete(cacheKey);
|
|
5513
5631
|
await load(true);
|
|
5514
5632
|
}, [cacheKey, load]);
|
|
@@ -5534,27 +5652,27 @@ function useBundle(idOrSlug, options = {}) {
|
|
|
5534
5652
|
}
|
|
5535
5653
|
const enabled = options.enabled ?? true;
|
|
5536
5654
|
const locationId = client.getLocationId();
|
|
5537
|
-
const previousLocationIdRef =
|
|
5538
|
-
const requestIdRef =
|
|
5539
|
-
const normalizedIdOrSlug =
|
|
5540
|
-
const cacheKey =
|
|
5655
|
+
const previousLocationIdRef = React2.useRef(locationId);
|
|
5656
|
+
const requestIdRef = React2.useRef(0);
|
|
5657
|
+
const normalizedIdOrSlug = React2.useMemo(() => (idOrSlug || "").trim(), [idOrSlug]);
|
|
5658
|
+
const cacheKey = React2.useMemo(
|
|
5541
5659
|
() => buildBundleCacheKey(client, locationId, normalizedIdOrSlug),
|
|
5542
5660
|
[client, locationId, normalizedIdOrSlug]
|
|
5543
5661
|
);
|
|
5544
5662
|
const cached = bundleCache.get(cacheKey);
|
|
5545
|
-
const [bundle, setBundle] =
|
|
5546
|
-
const [isLoading, setIsLoading] =
|
|
5663
|
+
const [bundle, setBundle] = React2.useState(cached?.bundle ?? null);
|
|
5664
|
+
const [isLoading, setIsLoading] = React2.useState(
|
|
5547
5665
|
enabled && normalizedIdOrSlug.length > 0 && !cached
|
|
5548
5666
|
);
|
|
5549
|
-
const [error, setError] =
|
|
5550
|
-
|
|
5667
|
+
const [error, setError] = React2.useState(null);
|
|
5668
|
+
React2.useEffect(() => {
|
|
5551
5669
|
if (previousLocationIdRef.current !== locationId) {
|
|
5552
5670
|
bundleCache.clear();
|
|
5553
5671
|
bundleInflight.clear();
|
|
5554
5672
|
previousLocationIdRef.current = locationId;
|
|
5555
5673
|
}
|
|
5556
5674
|
}, [locationId]);
|
|
5557
|
-
const load =
|
|
5675
|
+
const load = React2.useCallback(
|
|
5558
5676
|
async (force = false) => {
|
|
5559
5677
|
if (!enabled || normalizedIdOrSlug.length === 0) {
|
|
5560
5678
|
setBundle(null);
|
|
@@ -5605,10 +5723,10 @@ function useBundle(idOrSlug, options = {}) {
|
|
|
5605
5723
|
},
|
|
5606
5724
|
[cacheKey, client, enabled, normalizedIdOrSlug]
|
|
5607
5725
|
);
|
|
5608
|
-
|
|
5726
|
+
React2.useEffect(() => {
|
|
5609
5727
|
void load(false);
|
|
5610
5728
|
}, [load]);
|
|
5611
|
-
const refetch =
|
|
5729
|
+
const refetch = React2.useCallback(async () => {
|
|
5612
5730
|
bundleCache.delete(cacheKey);
|
|
5613
5731
|
await load(true);
|
|
5614
5732
|
}, [cacheKey, load]);
|
|
@@ -5638,37 +5756,37 @@ function useComposite(idOrProductId, options = {}) {
|
|
|
5638
5756
|
}
|
|
5639
5757
|
const enabled = options.enabled ?? true;
|
|
5640
5758
|
const locationId = client.getLocationId();
|
|
5641
|
-
const previousLocationIdRef =
|
|
5642
|
-
const requestIdRef =
|
|
5643
|
-
const priceRequestIdRef =
|
|
5644
|
-
const normalizedIdOrProductId =
|
|
5759
|
+
const previousLocationIdRef = React2.useRef(locationId);
|
|
5760
|
+
const requestIdRef = React2.useRef(0);
|
|
5761
|
+
const priceRequestIdRef = React2.useRef(0);
|
|
5762
|
+
const normalizedIdOrProductId = React2.useMemo(
|
|
5645
5763
|
() => (idOrProductId || "").trim(),
|
|
5646
5764
|
[idOrProductId]
|
|
5647
5765
|
);
|
|
5648
|
-
const byProductId =
|
|
5766
|
+
const byProductId = React2.useMemo(
|
|
5649
5767
|
() => shouldFetchByProductId(normalizedIdOrProductId, options.byProductId),
|
|
5650
5768
|
[normalizedIdOrProductId, options.byProductId]
|
|
5651
5769
|
);
|
|
5652
|
-
const cacheKey =
|
|
5770
|
+
const cacheKey = React2.useMemo(
|
|
5653
5771
|
() => buildCompositeCacheKey(client, locationId, normalizedIdOrProductId, byProductId),
|
|
5654
5772
|
[byProductId, client, locationId, normalizedIdOrProductId]
|
|
5655
5773
|
);
|
|
5656
5774
|
const cached = compositeCache.get(cacheKey);
|
|
5657
|
-
const [composite, setComposite] =
|
|
5658
|
-
const [isLoading, setIsLoading] =
|
|
5775
|
+
const [composite, setComposite] = React2.useState(cached?.composite ?? null);
|
|
5776
|
+
const [isLoading, setIsLoading] = React2.useState(
|
|
5659
5777
|
enabled && normalizedIdOrProductId.length > 0 && !cached
|
|
5660
5778
|
);
|
|
5661
|
-
const [error, setError] =
|
|
5662
|
-
const [priceResult, setPriceResult] =
|
|
5663
|
-
const [isPriceLoading, setIsPriceLoading] =
|
|
5664
|
-
|
|
5779
|
+
const [error, setError] = React2.useState(null);
|
|
5780
|
+
const [priceResult, setPriceResult] = React2.useState(null);
|
|
5781
|
+
const [isPriceLoading, setIsPriceLoading] = React2.useState(false);
|
|
5782
|
+
React2.useEffect(() => {
|
|
5665
5783
|
if (previousLocationIdRef.current !== locationId) {
|
|
5666
5784
|
compositeCache.clear();
|
|
5667
5785
|
compositeInflight.clear();
|
|
5668
5786
|
previousLocationIdRef.current = locationId;
|
|
5669
5787
|
}
|
|
5670
5788
|
}, [locationId]);
|
|
5671
|
-
const load =
|
|
5789
|
+
const load = React2.useCallback(
|
|
5672
5790
|
async (force = false) => {
|
|
5673
5791
|
if (!enabled || normalizedIdOrProductId.length === 0) {
|
|
5674
5792
|
setComposite(null);
|
|
@@ -5721,10 +5839,10 @@ function useComposite(idOrProductId, options = {}) {
|
|
|
5721
5839
|
},
|
|
5722
5840
|
[byProductId, cacheKey, client, enabled, normalizedIdOrProductId]
|
|
5723
5841
|
);
|
|
5724
|
-
|
|
5842
|
+
React2.useEffect(() => {
|
|
5725
5843
|
void load(false);
|
|
5726
5844
|
}, [load]);
|
|
5727
|
-
const calculatePrice =
|
|
5845
|
+
const calculatePrice = React2.useCallback(
|
|
5728
5846
|
async (selections, overrideLocationId) => {
|
|
5729
5847
|
if (!composite) {
|
|
5730
5848
|
return null;
|
|
@@ -5758,7 +5876,7 @@ function useComposite(idOrProductId, options = {}) {
|
|
|
5758
5876
|
},
|
|
5759
5877
|
[client, composite]
|
|
5760
5878
|
);
|
|
5761
|
-
const refetch =
|
|
5879
|
+
const refetch = React2.useCallback(async () => {
|
|
5762
5880
|
compositeCache.delete(cacheKey);
|
|
5763
5881
|
await load(true);
|
|
5764
5882
|
}, [cacheKey, load]);
|
|
@@ -5773,13 +5891,13 @@ function useSearch(options = {}) {
|
|
|
5773
5891
|
const minLength = Math.max(0, options.minLength ?? 2);
|
|
5774
5892
|
const debounceMs = Math.max(0, options.debounceMs ?? 300);
|
|
5775
5893
|
const limit = Math.max(1, options.limit ?? 20);
|
|
5776
|
-
const [query, setQueryState] =
|
|
5777
|
-
const [results, setResults] =
|
|
5778
|
-
const [isLoading, setIsLoading] =
|
|
5779
|
-
const [error, setError] =
|
|
5780
|
-
const requestIdRef =
|
|
5781
|
-
const timerRef =
|
|
5782
|
-
|
|
5894
|
+
const [query, setQueryState] = React2.useState("");
|
|
5895
|
+
const [results, setResults] = React2.useState([]);
|
|
5896
|
+
const [isLoading, setIsLoading] = React2.useState(false);
|
|
5897
|
+
const [error, setError] = React2.useState(null);
|
|
5898
|
+
const requestIdRef = React2.useRef(0);
|
|
5899
|
+
const timerRef = React2.useRef(null);
|
|
5900
|
+
React2.useEffect(() => {
|
|
5783
5901
|
if (timerRef.current) {
|
|
5784
5902
|
clearTimeout(timerRef.current);
|
|
5785
5903
|
timerRef.current = null;
|
|
@@ -5826,10 +5944,10 @@ function useSearch(options = {}) {
|
|
|
5826
5944
|
}
|
|
5827
5945
|
};
|
|
5828
5946
|
}, [client, debounceMs, limit, minLength, options.category, query]);
|
|
5829
|
-
const setQuery =
|
|
5947
|
+
const setQuery = React2.useCallback((nextQuery) => {
|
|
5830
5948
|
setQueryState(nextQuery);
|
|
5831
5949
|
}, []);
|
|
5832
|
-
const clear =
|
|
5950
|
+
const clear = React2.useCallback(() => {
|
|
5833
5951
|
requestIdRef.current += 1;
|
|
5834
5952
|
if (timerRef.current) {
|
|
5835
5953
|
clearTimeout(timerRef.current);
|
|
@@ -5885,28 +6003,28 @@ function useQuote(input, options = {}) {
|
|
|
5885
6003
|
const autoRefresh = options.autoRefresh ?? true;
|
|
5886
6004
|
const refreshBeforeExpiryMs = Math.max(0, options.refreshBeforeExpiryMs ?? 3e4);
|
|
5887
6005
|
const locationId = client.getLocationId();
|
|
5888
|
-
const requestIdRef =
|
|
5889
|
-
const refreshTimerRef =
|
|
5890
|
-
const expiryTimerRef =
|
|
5891
|
-
const inputSignature =
|
|
5892
|
-
const normalizedInput =
|
|
6006
|
+
const requestIdRef = React2.useRef(0);
|
|
6007
|
+
const refreshTimerRef = React2.useRef(null);
|
|
6008
|
+
const expiryTimerRef = React2.useRef(null);
|
|
6009
|
+
const inputSignature = React2.useMemo(() => JSON.stringify(input ?? null), [input]);
|
|
6010
|
+
const normalizedInput = React2.useMemo(() => {
|
|
5893
6011
|
if (!input) {
|
|
5894
6012
|
return null;
|
|
5895
6013
|
}
|
|
5896
6014
|
const normalized = normalizeInput(input, locationId);
|
|
5897
6015
|
return normalized.product_id.length > 0 ? normalized : null;
|
|
5898
6016
|
}, [inputSignature, locationId]);
|
|
5899
|
-
const cacheKey =
|
|
6017
|
+
const cacheKey = React2.useMemo(
|
|
5900
6018
|
() => buildQuoteCacheKey(client, locationId, inputSignature),
|
|
5901
6019
|
[client, inputSignature, locationId]
|
|
5902
6020
|
);
|
|
5903
6021
|
const cached = quoteCache.get(cacheKey);
|
|
5904
|
-
const [quote, setQuote] =
|
|
5905
|
-
const [isLoading, setIsLoading] =
|
|
5906
|
-
const [error, setError] =
|
|
5907
|
-
const [isExpired, setIsExpired] =
|
|
5908
|
-
const [messages, setMessages] =
|
|
5909
|
-
const load =
|
|
6022
|
+
const [quote, setQuote] = React2.useState(cached?.quote ?? null);
|
|
6023
|
+
const [isLoading, setIsLoading] = React2.useState(enabled && normalizedInput !== null && !cached);
|
|
6024
|
+
const [error, setError] = React2.useState(null);
|
|
6025
|
+
const [isExpired, setIsExpired] = React2.useState(isQuoteExpired(cached?.quote ?? null));
|
|
6026
|
+
const [messages, setMessages] = React2.useState(cached?.quote?.ui_messages ?? []);
|
|
6027
|
+
const load = React2.useCallback(
|
|
5910
6028
|
async (force = false) => {
|
|
5911
6029
|
if (!enabled || !normalizedInput) {
|
|
5912
6030
|
setQuote(null);
|
|
@@ -5964,10 +6082,10 @@ function useQuote(input, options = {}) {
|
|
|
5964
6082
|
},
|
|
5965
6083
|
[cacheKey, client, enabled, normalizedInput]
|
|
5966
6084
|
);
|
|
5967
|
-
|
|
6085
|
+
React2.useEffect(() => {
|
|
5968
6086
|
void load(false);
|
|
5969
6087
|
}, [load]);
|
|
5970
|
-
const refresh =
|
|
6088
|
+
const refresh = React2.useCallback(async () => {
|
|
5971
6089
|
if (!enabled || !normalizedInput) {
|
|
5972
6090
|
return;
|
|
5973
6091
|
}
|
|
@@ -6004,7 +6122,7 @@ function useQuote(input, options = {}) {
|
|
|
6004
6122
|
}
|
|
6005
6123
|
}
|
|
6006
6124
|
}, [cacheKey, client, enabled, load, normalizedInput, quote]);
|
|
6007
|
-
|
|
6125
|
+
React2.useEffect(() => {
|
|
6008
6126
|
if (expiryTimerRef.current) {
|
|
6009
6127
|
clearTimeout(expiryTimerRef.current);
|
|
6010
6128
|
expiryTimerRef.current = null;
|
|
@@ -6028,7 +6146,7 @@ function useQuote(input, options = {}) {
|
|
|
6028
6146
|
}
|
|
6029
6147
|
};
|
|
6030
6148
|
}, [quote?.expires_at, quote?.quote_id]);
|
|
6031
|
-
|
|
6149
|
+
React2.useEffect(() => {
|
|
6032
6150
|
if (refreshTimerRef.current) {
|
|
6033
6151
|
clearTimeout(refreshTimerRef.current);
|
|
6034
6152
|
refreshTimerRef.current = null;
|
|
@@ -6053,15 +6171,15 @@ function useQuote(input, options = {}) {
|
|
|
6053
6171
|
}, [autoRefresh, enabled, quote?.expires_at, quote?.quote_id, refresh, refreshBeforeExpiryMs]);
|
|
6054
6172
|
return { quote, isLoading, error, refresh, isExpired, messages };
|
|
6055
6173
|
}
|
|
6056
|
-
var ElementsContext =
|
|
6174
|
+
var ElementsContext = React2.createContext({
|
|
6057
6175
|
elements: null,
|
|
6058
6176
|
isReady: false
|
|
6059
6177
|
});
|
|
6060
6178
|
function useElements() {
|
|
6061
|
-
return
|
|
6179
|
+
return React2.useContext(ElementsContext).elements;
|
|
6062
6180
|
}
|
|
6063
6181
|
function useElementsReady() {
|
|
6064
|
-
return
|
|
6182
|
+
return React2.useContext(ElementsContext).isReady;
|
|
6065
6183
|
}
|
|
6066
6184
|
function ElementsProvider({
|
|
6067
6185
|
client,
|
|
@@ -6069,10 +6187,10 @@ function ElementsProvider({
|
|
|
6069
6187
|
options,
|
|
6070
6188
|
children
|
|
6071
6189
|
}) {
|
|
6072
|
-
const [elements, setElements] =
|
|
6073
|
-
const [isReady, setIsReady] =
|
|
6074
|
-
const initialOptionsRef =
|
|
6075
|
-
|
|
6190
|
+
const [elements, setElements] = React2.useState(null);
|
|
6191
|
+
const [isReady, setIsReady] = React2.useState(false);
|
|
6192
|
+
const initialOptionsRef = React2.useRef(options);
|
|
6193
|
+
React2.useEffect(() => {
|
|
6076
6194
|
let cancelled = false;
|
|
6077
6195
|
let instance = null;
|
|
6078
6196
|
setIsReady(false);
|
|
@@ -6113,20 +6231,20 @@ function AuthElement({
|
|
|
6113
6231
|
onRequiresOtp,
|
|
6114
6232
|
onError
|
|
6115
6233
|
}) {
|
|
6116
|
-
const containerRef =
|
|
6117
|
-
const elementRef =
|
|
6234
|
+
const containerRef = React2.useRef(null);
|
|
6235
|
+
const elementRef = React2.useRef(null);
|
|
6118
6236
|
const elements = useElements();
|
|
6119
|
-
const onReadyRef =
|
|
6120
|
-
const onAuthenticatedRef =
|
|
6121
|
-
const onRequiresOtpRef =
|
|
6122
|
-
const onErrorRef =
|
|
6123
|
-
|
|
6237
|
+
const onReadyRef = React2.useRef(onReady);
|
|
6238
|
+
const onAuthenticatedRef = React2.useRef(onAuthenticated);
|
|
6239
|
+
const onRequiresOtpRef = React2.useRef(onRequiresOtp);
|
|
6240
|
+
const onErrorRef = React2.useRef(onError);
|
|
6241
|
+
React2.useEffect(() => {
|
|
6124
6242
|
onReadyRef.current = onReady;
|
|
6125
6243
|
onAuthenticatedRef.current = onAuthenticated;
|
|
6126
6244
|
onRequiresOtpRef.current = onRequiresOtp;
|
|
6127
6245
|
onErrorRef.current = onError;
|
|
6128
6246
|
}, [onReady, onAuthenticated, onRequiresOtp, onError]);
|
|
6129
|
-
|
|
6247
|
+
React2.useEffect(() => {
|
|
6130
6248
|
if (!elements || !containerRef.current) return;
|
|
6131
6249
|
const element = elements.create(ELEMENT_TYPES.AUTH, { prefillEmail });
|
|
6132
6250
|
elementRef.current = element;
|
|
@@ -6156,18 +6274,18 @@ function AddressElement({
|
|
|
6156
6274
|
onChange,
|
|
6157
6275
|
onError
|
|
6158
6276
|
}) {
|
|
6159
|
-
const containerRef =
|
|
6160
|
-
const elementRef =
|
|
6277
|
+
const containerRef = React2.useRef(null);
|
|
6278
|
+
const elementRef = React2.useRef(null);
|
|
6161
6279
|
const elements = useElements();
|
|
6162
|
-
const onReadyRef =
|
|
6163
|
-
const onChangeRef =
|
|
6164
|
-
const onErrorRef =
|
|
6165
|
-
|
|
6280
|
+
const onReadyRef = React2.useRef(onReady);
|
|
6281
|
+
const onChangeRef = React2.useRef(onChange);
|
|
6282
|
+
const onErrorRef = React2.useRef(onError);
|
|
6283
|
+
React2.useEffect(() => {
|
|
6166
6284
|
onReadyRef.current = onReady;
|
|
6167
6285
|
onChangeRef.current = onChange;
|
|
6168
6286
|
onErrorRef.current = onError;
|
|
6169
6287
|
}, [onReady, onChange, onError]);
|
|
6170
|
-
|
|
6288
|
+
React2.useEffect(() => {
|
|
6171
6289
|
if (!elements || !containerRef.current) return;
|
|
6172
6290
|
const element = elements.create(ELEMENT_TYPES.ADDRESS, { mode });
|
|
6173
6291
|
elementRef.current = element;
|
|
@@ -6194,18 +6312,18 @@ function PaymentElement({
|
|
|
6194
6312
|
onChange,
|
|
6195
6313
|
onError
|
|
6196
6314
|
}) {
|
|
6197
|
-
const containerRef =
|
|
6198
|
-
const elementRef =
|
|
6315
|
+
const containerRef = React2.useRef(null);
|
|
6316
|
+
const elementRef = React2.useRef(null);
|
|
6199
6317
|
const elements = useElements();
|
|
6200
|
-
const onReadyRef =
|
|
6201
|
-
const onChangeRef =
|
|
6202
|
-
const onErrorRef =
|
|
6203
|
-
|
|
6318
|
+
const onReadyRef = React2.useRef(onReady);
|
|
6319
|
+
const onChangeRef = React2.useRef(onChange);
|
|
6320
|
+
const onErrorRef = React2.useRef(onError);
|
|
6321
|
+
React2.useEffect(() => {
|
|
6204
6322
|
onReadyRef.current = onReady;
|
|
6205
6323
|
onChangeRef.current = onChange;
|
|
6206
6324
|
onErrorRef.current = onError;
|
|
6207
6325
|
}, [onReady, onChange, onError]);
|
|
6208
|
-
|
|
6326
|
+
React2.useEffect(() => {
|
|
6209
6327
|
if (!elements || !containerRef.current) return;
|
|
6210
6328
|
const element = elements.create(ELEMENT_TYPES.PAYMENT, { amount, currency });
|
|
6211
6329
|
elementRef.current = element;
|
|
@@ -6225,8 +6343,8 @@ function PaymentElement({
|
|
|
6225
6343
|
}
|
|
6226
6344
|
function useCheckout() {
|
|
6227
6345
|
const elements = useElements();
|
|
6228
|
-
const [isLoading, setIsLoading] =
|
|
6229
|
-
const submit =
|
|
6346
|
+
const [isLoading, setIsLoading] = React2.useState(false);
|
|
6347
|
+
const submit = React2.useCallback(
|
|
6230
6348
|
async (data) => {
|
|
6231
6349
|
if (!elements) {
|
|
6232
6350
|
return { success: false, error: { code: "NO_ELEMENTS", message: "Elements not initialized" } };
|
|
@@ -6240,7 +6358,7 @@ function useCheckout() {
|
|
|
6240
6358
|
},
|
|
6241
6359
|
[elements]
|
|
6242
6360
|
);
|
|
6243
|
-
const process =
|
|
6361
|
+
const process = React2.useCallback(
|
|
6244
6362
|
async (options) => {
|
|
6245
6363
|
if (!elements) {
|
|
6246
6364
|
return {
|