@cimplify/sdk 0.8.1 → 0.8.3
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 +32 -2
- package/dist/advanced.mjs +32 -2
- package/dist/{client-bq-xxzM7.d.mts → client-DnAfLDhV.d.mts} +38 -1
- package/dist/{client-BJFeYCB2.d.ts → client-hKTJv1I1.d.ts} +38 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +174 -111
- package/dist/index.mjs +174 -111
- package/dist/react.d.mts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +421 -285
- package/dist/react.mjs +210 -78
- 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",
|
|
@@ -196,7 +201,7 @@ function deriveAdsApiUrl() {
|
|
|
196
201
|
}
|
|
197
202
|
return "https://api.cimplify.io";
|
|
198
203
|
}
|
|
199
|
-
var AdContext =
|
|
204
|
+
var AdContext = React2.createContext({
|
|
200
205
|
siteId: null,
|
|
201
206
|
config: null,
|
|
202
207
|
isLoading: true,
|
|
@@ -204,7 +209,7 @@ var AdContext = react.createContext({
|
|
|
204
209
|
apiBase: "https://api.cimplify.io"
|
|
205
210
|
});
|
|
206
211
|
function useAds() {
|
|
207
|
-
return
|
|
212
|
+
return React2.useContext(AdContext);
|
|
208
213
|
}
|
|
209
214
|
function AdProvider({
|
|
210
215
|
siteId,
|
|
@@ -213,10 +218,10 @@ function AdProvider({
|
|
|
213
218
|
children
|
|
214
219
|
}) {
|
|
215
220
|
const resolvedApiBase = apiBase || deriveAdsApiUrl();
|
|
216
|
-
const [config, setConfig] =
|
|
217
|
-
const [isLoading, setIsLoading] =
|
|
218
|
-
const [identity, setIdentity] =
|
|
219
|
-
|
|
221
|
+
const [config, setConfig] = React2.useState(null);
|
|
222
|
+
const [isLoading, setIsLoading] = React2.useState(true);
|
|
223
|
+
const [identity, setIdentity] = React2.useState(null);
|
|
224
|
+
React2.useEffect(() => {
|
|
220
225
|
const userIdentity = getUserIdentity(authenticatedAccountId);
|
|
221
226
|
setIdentity(userIdentity);
|
|
222
227
|
fetch(`${resolvedApiBase}/ads/config/${siteId}`).then((r) => r.json()).then((data) => {
|
|
@@ -239,11 +244,11 @@ function Ad({
|
|
|
239
244
|
onClick
|
|
240
245
|
}) {
|
|
241
246
|
const { siteId, config, isLoading, identity, apiBase } = useAds();
|
|
242
|
-
const [ad, setAd] =
|
|
243
|
-
const [error, setError] =
|
|
244
|
-
const impressionTracked =
|
|
245
|
-
const containerRef =
|
|
246
|
-
|
|
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(() => {
|
|
247
252
|
if (isLoading || !config?.enabled || !siteId || !identity) return;
|
|
248
253
|
const path = typeof window !== "undefined" ? window.location.pathname : "/";
|
|
249
254
|
const referrer = typeof document !== "undefined" ? document.referrer : "";
|
|
@@ -286,7 +291,7 @@ function Ad({
|
|
|
286
291
|
}
|
|
287
292
|
}).catch(() => setError(true));
|
|
288
293
|
}, [siteId, config, isLoading, slot, identity, apiBase]);
|
|
289
|
-
|
|
294
|
+
React2.useEffect(() => {
|
|
290
295
|
if (!ad || impressionTracked.current || typeof window === "undefined" || !identity) return;
|
|
291
296
|
const observer = new IntersectionObserver(
|
|
292
297
|
([entry]) => {
|
|
@@ -345,6 +350,61 @@ function Ad({
|
|
|
345
350
|
}
|
|
346
351
|
);
|
|
347
352
|
}
|
|
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
|
+
}
|
|
348
408
|
var SPACE = { sm: 8};
|
|
349
409
|
function shellColors(isDark, primaryColor) {
|
|
350
410
|
return {
|
|
@@ -399,51 +459,48 @@ function CimplifyCheckout({
|
|
|
399
459
|
demoMode,
|
|
400
460
|
className
|
|
401
461
|
}) {
|
|
402
|
-
const resolvedOrderTypes =
|
|
462
|
+
const resolvedOrderTypes = React2.useMemo(
|
|
403
463
|
() => orderTypes && orderTypes.length > 0 ? orderTypes : ["pickup", "delivery"],
|
|
404
464
|
[orderTypes]
|
|
405
465
|
);
|
|
406
|
-
const [orderType, setOrderType] =
|
|
407
|
-
const [status, setStatus] =
|
|
408
|
-
const [statusText, setStatusText] =
|
|
409
|
-
const [isSubmitting, setIsSubmitting] =
|
|
410
|
-
const [isInitializing, setIsInitializing] =
|
|
411
|
-
const [errorMessage, setErrorMessage] =
|
|
412
|
-
const [resolvedBusinessId, setResolvedBusinessId] =
|
|
413
|
-
const [resolvedCartId, setResolvedCartId] =
|
|
414
|
-
const
|
|
415
|
-
const
|
|
416
|
-
const
|
|
417
|
-
const
|
|
418
|
-
const
|
|
419
|
-
const
|
|
420
|
-
const
|
|
421
|
-
const
|
|
422
|
-
const onErrorRef = react.useRef(onError);
|
|
423
|
-
const onStatusChangeRef = react.useRef(onStatusChange);
|
|
424
|
-
const handleSubmitRef = react.useRef(async () => {
|
|
425
|
-
});
|
|
426
|
-
onCompleteRef.current = onComplete;
|
|
427
|
-
onErrorRef.current = onError;
|
|
428
|
-
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);
|
|
429
482
|
const isDemoCheckout = demoMode ?? client.getPublicKey().trim().length === 0;
|
|
430
483
|
const isTestMode = client.isTestMode();
|
|
431
484
|
const primaryColor = appearance?.variables?.primaryColor || "#0a2540";
|
|
432
485
|
const isDark = appearance?.theme === "dark";
|
|
433
|
-
const emitStatus =
|
|
486
|
+
const emitStatus = React2__default.default.useEffectEvent(
|
|
434
487
|
(nextStatus, context = {}) => {
|
|
435
488
|
setStatus(nextStatus);
|
|
436
489
|
setStatusText(context.display_text || "");
|
|
437
|
-
|
|
438
|
-
}
|
|
439
|
-
[]
|
|
490
|
+
onStatusChange?.(nextStatus, context);
|
|
491
|
+
}
|
|
440
492
|
);
|
|
441
|
-
|
|
493
|
+
const fireError = React2__default.default.useEffectEvent(
|
|
494
|
+
(error) => {
|
|
495
|
+
onError?.(error);
|
|
496
|
+
}
|
|
497
|
+
);
|
|
498
|
+
React2.useEffect(() => {
|
|
442
499
|
if (!resolvedOrderTypes.includes(orderType)) {
|
|
443
500
|
setOrderType(resolvedOrderTypes[0] || "pickup");
|
|
444
501
|
}
|
|
445
502
|
}, [resolvedOrderTypes, orderType]);
|
|
446
|
-
|
|
503
|
+
React2.useEffect(() => {
|
|
447
504
|
if (appearance && appearance !== initialAppearanceRef.current && !hasWarnedInlineAppearanceRef.current) {
|
|
448
505
|
hasWarnedInlineAppearanceRef.current = true;
|
|
449
506
|
console.warn(
|
|
@@ -451,7 +508,7 @@ function CimplifyCheckout({
|
|
|
451
508
|
);
|
|
452
509
|
}
|
|
453
510
|
}, [appearance]);
|
|
454
|
-
|
|
511
|
+
React2.useEffect(() => {
|
|
455
512
|
let cancelled = false;
|
|
456
513
|
async function bootstrap() {
|
|
457
514
|
if (isDemoCheckout) {
|
|
@@ -472,6 +529,12 @@ function CimplifyCheckout({
|
|
|
472
529
|
setIsInitializing(false);
|
|
473
530
|
setErrorMessage(null);
|
|
474
531
|
}
|
|
532
|
+
client.cart.get().then((cartResult) => {
|
|
533
|
+
if (!cancelled && cartResult.ok && cartResult.value) {
|
|
534
|
+
setResolvedCart(cartResult.value);
|
|
535
|
+
}
|
|
536
|
+
}).catch(() => {
|
|
537
|
+
});
|
|
475
538
|
return;
|
|
476
539
|
}
|
|
477
540
|
if (!cancelled) {
|
|
@@ -489,7 +552,7 @@ function CimplifyCheckout({
|
|
|
489
552
|
setResolvedCartId(null);
|
|
490
553
|
setErrorMessage(message);
|
|
491
554
|
setIsInitializing(false);
|
|
492
|
-
|
|
555
|
+
fireError({ code: "BUSINESS_ID_REQUIRED", message });
|
|
493
556
|
}
|
|
494
557
|
return;
|
|
495
558
|
}
|
|
@@ -504,11 +567,14 @@ function CimplifyCheckout({
|
|
|
504
567
|
setResolvedCartId(null);
|
|
505
568
|
setErrorMessage(message);
|
|
506
569
|
setIsInitializing(false);
|
|
507
|
-
|
|
570
|
+
fireError({ code: "CART_EMPTY", message });
|
|
508
571
|
}
|
|
509
572
|
return;
|
|
510
573
|
}
|
|
511
574
|
nextCartId = cartResult.value.id;
|
|
575
|
+
if (!cancelled) {
|
|
576
|
+
setResolvedCart(cartResult.value);
|
|
577
|
+
}
|
|
512
578
|
}
|
|
513
579
|
if (!cancelled) {
|
|
514
580
|
setResolvedBusinessId(nextBusinessId);
|
|
@@ -522,7 +588,7 @@ function CimplifyCheckout({
|
|
|
522
588
|
cancelled = true;
|
|
523
589
|
};
|
|
524
590
|
}, [businessId, cartId, client, isDemoCheckout]);
|
|
525
|
-
|
|
591
|
+
React2.useEffect(() => {
|
|
526
592
|
return () => {
|
|
527
593
|
isMountedRef.current = false;
|
|
528
594
|
demoRunRef.current += 1;
|
|
@@ -530,45 +596,12 @@ function CimplifyCheckout({
|
|
|
530
596
|
activeCheckoutRef.current = null;
|
|
531
597
|
};
|
|
532
598
|
}, []);
|
|
533
|
-
|
|
534
|
-
if (isDemoCheckout || !resolvedBusinessId) {
|
|
535
|
-
elementsRef.current = null;
|
|
536
|
-
return;
|
|
537
|
-
}
|
|
538
|
-
const elements = client.elements(resolvedBusinessId, {
|
|
539
|
-
appearance: initialAppearanceRef.current,
|
|
540
|
-
linkUrl
|
|
541
|
-
});
|
|
542
|
-
elementsRef.current = elements;
|
|
543
|
-
const checkout = elements.create("checkout", {
|
|
544
|
-
orderTypes: resolvedOrderTypes,
|
|
545
|
-
defaultOrderType: resolvedOrderTypes[0]
|
|
546
|
-
});
|
|
547
|
-
if (checkoutMountRef.current) {
|
|
548
|
-
checkout.mount(checkoutMountRef.current);
|
|
549
|
-
}
|
|
550
|
-
checkout.on("order_type_changed", (data) => {
|
|
551
|
-
const typed = data;
|
|
552
|
-
if (typed.orderType) {
|
|
553
|
-
setOrderType(typed.orderType);
|
|
554
|
-
}
|
|
555
|
-
});
|
|
556
|
-
checkout.on("request_submit", () => {
|
|
557
|
-
void handleSubmitRef.current();
|
|
558
|
-
});
|
|
559
|
-
return () => {
|
|
560
|
-
activeCheckoutRef.current?.abort();
|
|
561
|
-
activeCheckoutRef.current = null;
|
|
562
|
-
elements.destroy();
|
|
563
|
-
elementsRef.current = null;
|
|
564
|
-
};
|
|
565
|
-
}, [client, resolvedBusinessId, isDemoCheckout]);
|
|
566
|
-
const handleSubmit = react.useCallback(async () => {
|
|
599
|
+
const handleSubmit = React2__default.default.useEffectEvent(async () => {
|
|
567
600
|
if (isSubmitting || isInitializing || !resolvedCartId) {
|
|
568
601
|
if (!resolvedCartId && !isInitializing) {
|
|
569
602
|
const message = "Your cart is empty. Add items before checkout.";
|
|
570
603
|
setErrorMessage(message);
|
|
571
|
-
|
|
604
|
+
fireError({ code: "CART_EMPTY", message });
|
|
572
605
|
}
|
|
573
606
|
return;
|
|
574
607
|
}
|
|
@@ -603,7 +636,7 @@ function CimplifyCheckout({
|
|
|
603
636
|
order_number: result.order?.order_number,
|
|
604
637
|
display_text: statusToLabel("success")
|
|
605
638
|
});
|
|
606
|
-
|
|
639
|
+
onComplete(result);
|
|
607
640
|
} finally {
|
|
608
641
|
if (isMountedRef.current && runId === demoRunRef.current) {
|
|
609
642
|
setIsSubmitting(false);
|
|
@@ -614,7 +647,7 @@ function CimplifyCheckout({
|
|
|
614
647
|
if (!elementsRef.current) {
|
|
615
648
|
const message = "Checkout is still initializing. Please try again.";
|
|
616
649
|
setErrorMessage(message);
|
|
617
|
-
|
|
650
|
+
fireError({ code: "CHECKOUT_NOT_READY", message });
|
|
618
651
|
setIsSubmitting(false);
|
|
619
652
|
return;
|
|
620
653
|
}
|
|
@@ -629,31 +662,65 @@ function CimplifyCheckout({
|
|
|
629
662
|
try {
|
|
630
663
|
const result = await checkout;
|
|
631
664
|
if (result.success) {
|
|
632
|
-
|
|
665
|
+
onComplete(result);
|
|
633
666
|
return;
|
|
634
667
|
}
|
|
635
668
|
const code = result.error?.code || "CHECKOUT_FAILED";
|
|
636
669
|
const message = result.error?.message || "Payment failed.";
|
|
637
670
|
setErrorMessage(message);
|
|
638
|
-
|
|
671
|
+
fireError({ code, message });
|
|
639
672
|
} finally {
|
|
640
673
|
if (isMountedRef.current) {
|
|
641
674
|
activeCheckoutRef.current = null;
|
|
642
675
|
setIsSubmitting(false);
|
|
643
676
|
}
|
|
644
677
|
}
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
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]);
|
|
657
724
|
const colors = shellColors(isDark ?? false, primaryColor);
|
|
658
725
|
if (isInitializing) {
|
|
659
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..." }) });
|
|
@@ -1285,6 +1352,13 @@ var CartOperations = class {
|
|
|
1285
1352
|
}
|
|
1286
1353
|
};
|
|
1287
1354
|
|
|
1355
|
+
// src/constants.ts
|
|
1356
|
+
var MOBILE_MONEY_PROVIDER = {
|
|
1357
|
+
MTN: "mtn",
|
|
1358
|
+
VODAFONE: "vodafone",
|
|
1359
|
+
AIRTEL: "airtel"
|
|
1360
|
+
};
|
|
1361
|
+
|
|
1288
1362
|
// src/utils/price.ts
|
|
1289
1363
|
function parsePrice(value) {
|
|
1290
1364
|
if (value === void 0 || value === null) {
|
|
@@ -1523,6 +1597,10 @@ async function openCardPopup(provider, checkoutResult, email, currency, signal)
|
|
|
1523
1597
|
}
|
|
1524
1598
|
return { success: false, error: "PROVIDER_UNAVAILABLE" };
|
|
1525
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
|
+
}
|
|
1526
1604
|
function normalizeAuthorizationType(value) {
|
|
1527
1605
|
return value === "otp" || value === "pin" ? value : void 0;
|
|
1528
1606
|
}
|
|
@@ -1755,6 +1833,16 @@ var CheckoutResolver = class {
|
|
|
1755
1833
|
}
|
|
1756
1834
|
await this.wait(this.pollIntervalMs);
|
|
1757
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
|
+
}
|
|
1758
1846
|
return this.fail(
|
|
1759
1847
|
"PAYMENT_TIMEOUT",
|
|
1760
1848
|
"Payment confirmation timed out. Please retry checkout.",
|
|
@@ -1885,7 +1973,7 @@ var CheckoutResolver = class {
|
|
|
1885
1973
|
};
|
|
1886
1974
|
}
|
|
1887
1975
|
getEnrollmentMobileMoney() {
|
|
1888
|
-
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)) {
|
|
1889
1977
|
return {
|
|
1890
1978
|
phone_number: this.paymentData.phone_number,
|
|
1891
1979
|
provider: this.paymentData.provider,
|
|
@@ -2959,8 +3047,10 @@ var CimplifyElements = class {
|
|
|
2959
3047
|
false
|
|
2960
3048
|
);
|
|
2961
3049
|
}
|
|
3050
|
+
this.checkoutInProgress = true;
|
|
2962
3051
|
if (!options.cart_id) {
|
|
2963
3052
|
console.debug("[cimplify:checkout] BLOCKED: no cart_id");
|
|
3053
|
+
this.checkoutInProgress = false;
|
|
2964
3054
|
return toCheckoutError(
|
|
2965
3055
|
"INVALID_CART",
|
|
2966
3056
|
"A valid cart is required before checkout can start.",
|
|
@@ -2969,6 +3059,7 @@ var CimplifyElements = class {
|
|
|
2969
3059
|
}
|
|
2970
3060
|
if (!options.order_type) {
|
|
2971
3061
|
console.debug("[cimplify:checkout] BLOCKED: no order_type");
|
|
3062
|
+
this.checkoutInProgress = false;
|
|
2972
3063
|
return toCheckoutError(
|
|
2973
3064
|
"ORDER_TYPE_REQUIRED",
|
|
2974
3065
|
"Order type is required before checkout can start.",
|
|
@@ -2978,6 +3069,7 @@ var CimplifyElements = class {
|
|
|
2978
3069
|
const checkoutElement = this.elements.get(ELEMENT_TYPES.CHECKOUT) || this.elements.get(ELEMENT_TYPES.PAYMENT);
|
|
2979
3070
|
if (!checkoutElement) {
|
|
2980
3071
|
console.debug("[cimplify:checkout] BLOCKED: no checkout element");
|
|
3072
|
+
this.checkoutInProgress = false;
|
|
2981
3073
|
return toCheckoutError(
|
|
2982
3074
|
"NO_PAYMENT_ELEMENT",
|
|
2983
3075
|
"Checkout element must be mounted before checkout.",
|
|
@@ -2986,6 +3078,7 @@ var CimplifyElements = class {
|
|
|
2986
3078
|
}
|
|
2987
3079
|
if (!checkoutElement.isMounted()) {
|
|
2988
3080
|
console.debug("[cimplify:checkout] BLOCKED: checkout element not mounted");
|
|
3081
|
+
this.checkoutInProgress = false;
|
|
2989
3082
|
return toCheckoutError(
|
|
2990
3083
|
"PAYMENT_NOT_MOUNTED",
|
|
2991
3084
|
"Checkout element must be mounted before checkout.",
|
|
@@ -2997,6 +3090,7 @@ var CimplifyElements = class {
|
|
|
2997
3090
|
const authElement = this.elements.get(ELEMENT_TYPES.AUTH);
|
|
2998
3091
|
if (authElement && !this.accessToken) {
|
|
2999
3092
|
console.debug("[cimplify:checkout] BLOCKED: auth incomplete");
|
|
3093
|
+
this.checkoutInProgress = false;
|
|
3000
3094
|
return toCheckoutError(
|
|
3001
3095
|
"AUTH_INCOMPLETE",
|
|
3002
3096
|
"Authentication must complete before checkout can start.",
|
|
@@ -3034,7 +3128,6 @@ var CimplifyElements = class {
|
|
|
3034
3128
|
};
|
|
3035
3129
|
const timeoutMs = options.timeout_ms ?? 18e4;
|
|
3036
3130
|
const paymentWindow = checkoutElement.getContentWindow();
|
|
3037
|
-
this.checkoutInProgress = true;
|
|
3038
3131
|
return new Promise((resolve) => {
|
|
3039
3132
|
let settled = false;
|
|
3040
3133
|
const cleanup = () => {
|
|
@@ -3329,6 +3422,9 @@ var CimplifyElement = class {
|
|
|
3329
3422
|
this.sendMessage({ type: MESSAGE_TYPES.GET_DATA });
|
|
3330
3423
|
});
|
|
3331
3424
|
}
|
|
3425
|
+
setCart(cart) {
|
|
3426
|
+
this.sendMessage({ type: MESSAGE_TYPES.SET_CART, cart });
|
|
3427
|
+
}
|
|
3332
3428
|
sendMessage(message) {
|
|
3333
3429
|
if (this.iframe?.contentWindow) {
|
|
3334
3430
|
this.iframe.contentWindow.postMessage(message, this.linkUrl);
|
|
@@ -3477,6 +3573,7 @@ var ACCESS_TOKEN_STORAGE_KEY = "cimplify_access_token";
|
|
|
3477
3573
|
var SESSION_TOKEN_STORAGE_KEY = "cimplify_session_token";
|
|
3478
3574
|
var ORDER_TOKEN_PREFIX = "cimplify_ot_";
|
|
3479
3575
|
var SESSION_TOKEN_HEADER = "x-session-token";
|
|
3576
|
+
var ORDER_TOKEN_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
3480
3577
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
3481
3578
|
var DEFAULT_MAX_RETRIES = 3;
|
|
3482
3579
|
var DEFAULT_RETRY_DELAY_MS = 1e3;
|
|
@@ -3583,6 +3680,14 @@ var CimplifyClient = class {
|
|
|
3583
3680
|
);
|
|
3584
3681
|
}
|
|
3585
3682
|
}
|
|
3683
|
+
/** Build a full URL, appending context params (e.g. location_id) as query parameters. */
|
|
3684
|
+
buildUrl(base, path) {
|
|
3685
|
+
const url = `${base}${path}`;
|
|
3686
|
+
const locationId = this.context.location_id;
|
|
3687
|
+
if (!locationId) return url;
|
|
3688
|
+
const separator = url.includes("?") ? "&" : "?";
|
|
3689
|
+
return `${url}${separator}location_id=${encodeURIComponent(locationId)}`;
|
|
3690
|
+
}
|
|
3586
3691
|
/** @deprecated Use getAccessToken() instead */
|
|
3587
3692
|
getSessionToken() {
|
|
3588
3693
|
return this.accessToken;
|
|
@@ -3626,12 +3731,27 @@ var CimplifyClient = class {
|
|
|
3626
3731
|
}
|
|
3627
3732
|
setOrderToken(orderId, token) {
|
|
3628
3733
|
if (typeof window !== "undefined" && window.localStorage) {
|
|
3629
|
-
|
|
3734
|
+
try {
|
|
3735
|
+
const entry = JSON.stringify({ token, storedAt: Date.now() });
|
|
3736
|
+
localStorage.setItem(`${ORDER_TOKEN_PREFIX}${orderId}`, entry);
|
|
3737
|
+
} catch {
|
|
3738
|
+
}
|
|
3630
3739
|
}
|
|
3631
3740
|
}
|
|
3632
3741
|
getOrderToken(orderId) {
|
|
3633
3742
|
if (typeof window !== "undefined" && window.localStorage) {
|
|
3634
|
-
|
|
3743
|
+
try {
|
|
3744
|
+
const raw = localStorage.getItem(`${ORDER_TOKEN_PREFIX}${orderId}`);
|
|
3745
|
+
if (!raw) return null;
|
|
3746
|
+
const entry = JSON.parse(raw);
|
|
3747
|
+
if (Date.now() - entry.storedAt > ORDER_TOKEN_TTL_MS) {
|
|
3748
|
+
localStorage.removeItem(`${ORDER_TOKEN_PREFIX}${orderId}`);
|
|
3749
|
+
return null;
|
|
3750
|
+
}
|
|
3751
|
+
return entry.token;
|
|
3752
|
+
} catch {
|
|
3753
|
+
return null;
|
|
3754
|
+
}
|
|
3635
3755
|
}
|
|
3636
3756
|
return null;
|
|
3637
3757
|
}
|
|
@@ -3707,10 +3827,13 @@ var CimplifyClient = class {
|
|
|
3707
3827
|
}
|
|
3708
3828
|
saveAccessToken(token) {
|
|
3709
3829
|
if (typeof window !== "undefined" && window.localStorage) {
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3830
|
+
try {
|
|
3831
|
+
if (token) {
|
|
3832
|
+
localStorage.setItem(ACCESS_TOKEN_STORAGE_KEY, token);
|
|
3833
|
+
} else {
|
|
3834
|
+
localStorage.removeItem(ACCESS_TOKEN_STORAGE_KEY);
|
|
3835
|
+
}
|
|
3836
|
+
} catch {
|
|
3714
3837
|
}
|
|
3715
3838
|
}
|
|
3716
3839
|
}
|
|
@@ -3783,6 +3906,19 @@ var CimplifyClient = class {
|
|
|
3783
3906
|
});
|
|
3784
3907
|
return response;
|
|
3785
3908
|
}
|
|
3909
|
+
if (response.status === 429 && attempt < this.maxRetries) {
|
|
3910
|
+
retryCount++;
|
|
3911
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
3912
|
+
const delay = retryAfter ? Math.min(parseInt(retryAfter, 10) * 1e3, 3e4) || this.retryDelay * Math.pow(2, attempt) : this.retryDelay * Math.pow(2, attempt);
|
|
3913
|
+
this.hooks.onRetry?.({
|
|
3914
|
+
...context,
|
|
3915
|
+
attempt: retryCount,
|
|
3916
|
+
delayMs: delay,
|
|
3917
|
+
error: new Error(`Rate limited: ${response.status}`)
|
|
3918
|
+
});
|
|
3919
|
+
await sleep(delay);
|
|
3920
|
+
continue;
|
|
3921
|
+
}
|
|
3786
3922
|
if (response.status >= 400 && response.status < 500) {
|
|
3787
3923
|
this.hooks.onRequestError?.({
|
|
3788
3924
|
...context,
|
|
@@ -3875,7 +4011,7 @@ var CimplifyClient = class {
|
|
|
3875
4011
|
async get(path) {
|
|
3876
4012
|
const key = this.getDedupeKey("get", path);
|
|
3877
4013
|
return this.deduplicatedRequest(key, async () => {
|
|
3878
|
-
const response = await this.resilientFetch(
|
|
4014
|
+
const response = await this.resilientFetch(this.buildUrl(this.baseUrl, path), {
|
|
3879
4015
|
method: "GET",
|
|
3880
4016
|
credentials: this.credentials,
|
|
3881
4017
|
headers: this.getHeaders()
|
|
@@ -3884,7 +4020,7 @@ var CimplifyClient = class {
|
|
|
3884
4020
|
});
|
|
3885
4021
|
}
|
|
3886
4022
|
async post(path, body) {
|
|
3887
|
-
const response = await this.resilientFetch(
|
|
4023
|
+
const response = await this.resilientFetch(this.buildUrl(this.baseUrl, path), {
|
|
3888
4024
|
method: "POST",
|
|
3889
4025
|
credentials: this.credentials,
|
|
3890
4026
|
headers: this.getHeaders(),
|
|
@@ -3893,7 +4029,7 @@ var CimplifyClient = class {
|
|
|
3893
4029
|
return this.handleRestResponse(response);
|
|
3894
4030
|
}
|
|
3895
4031
|
async patch(path, body) {
|
|
3896
|
-
const response = await this.resilientFetch(
|
|
4032
|
+
const response = await this.resilientFetch(this.buildUrl(this.baseUrl, path), {
|
|
3897
4033
|
method: "PATCH",
|
|
3898
4034
|
credentials: this.credentials,
|
|
3899
4035
|
headers: this.getHeaders(),
|
|
@@ -3902,7 +4038,7 @@ var CimplifyClient = class {
|
|
|
3902
4038
|
return this.handleRestResponse(response);
|
|
3903
4039
|
}
|
|
3904
4040
|
async delete(path) {
|
|
3905
|
-
const response = await this.resilientFetch(
|
|
4041
|
+
const response = await this.resilientFetch(this.buildUrl(this.baseUrl, path), {
|
|
3906
4042
|
method: "DELETE",
|
|
3907
4043
|
credentials: this.credentials,
|
|
3908
4044
|
headers: this.getHeaders()
|
|
@@ -4106,23 +4242,23 @@ function resolveInitialLocation(locations) {
|
|
|
4106
4242
|
}
|
|
4107
4243
|
return locations[0];
|
|
4108
4244
|
}
|
|
4109
|
-
var CimplifyContext =
|
|
4245
|
+
var CimplifyContext = React2.createContext(null);
|
|
4110
4246
|
function CimplifyProvider({
|
|
4111
4247
|
client,
|
|
4112
4248
|
children,
|
|
4113
4249
|
onLocationChange
|
|
4114
4250
|
}) {
|
|
4115
|
-
const resolvedClient =
|
|
4116
|
-
const onLocationChangeRef =
|
|
4117
|
-
const [business, setBusiness] =
|
|
4118
|
-
const [locations, setLocations] =
|
|
4119
|
-
const [currentLocation, setCurrentLocationState] =
|
|
4120
|
-
const [isReady, setIsReady] =
|
|
4121
|
-
|
|
4251
|
+
const resolvedClient = React2.useMemo(() => client ?? createDefaultClient(), [client]);
|
|
4252
|
+
const onLocationChangeRef = React2.useRef(onLocationChange);
|
|
4253
|
+
const [business, setBusiness] = React2.useState(null);
|
|
4254
|
+
const [locations, setLocations] = React2.useState([]);
|
|
4255
|
+
const [currentLocation, setCurrentLocationState] = React2.useState(null);
|
|
4256
|
+
const [isReady, setIsReady] = React2.useState(false);
|
|
4257
|
+
React2.useEffect(() => {
|
|
4122
4258
|
onLocationChangeRef.current = onLocationChange;
|
|
4123
4259
|
}, [onLocationChange]);
|
|
4124
4260
|
const isDemoMode = resolvedClient.getPublicKey().trim().length === 0;
|
|
4125
|
-
const setCurrentLocation =
|
|
4261
|
+
const setCurrentLocation = React2.useCallback(
|
|
4126
4262
|
(location) => {
|
|
4127
4263
|
setCurrentLocationState(location);
|
|
4128
4264
|
resolvedClient.setLocationId(location.id);
|
|
@@ -4131,7 +4267,7 @@ function CimplifyProvider({
|
|
|
4131
4267
|
},
|
|
4132
4268
|
[resolvedClient]
|
|
4133
4269
|
);
|
|
4134
|
-
|
|
4270
|
+
React2.useEffect(() => {
|
|
4135
4271
|
let cancelled = false;
|
|
4136
4272
|
async function bootstrap() {
|
|
4137
4273
|
setIsReady(false);
|
|
@@ -4187,7 +4323,7 @@ function CimplifyProvider({
|
|
|
4187
4323
|
cancelled = true;
|
|
4188
4324
|
};
|
|
4189
4325
|
}, [resolvedClient, isDemoMode]);
|
|
4190
|
-
const contextValue =
|
|
4326
|
+
const contextValue = React2.useMemo(
|
|
4191
4327
|
() => ({
|
|
4192
4328
|
client: resolvedClient,
|
|
4193
4329
|
business,
|
|
@@ -4212,14 +4348,14 @@ function CimplifyProvider({
|
|
|
4212
4348
|
return /* @__PURE__ */ jsxRuntime.jsx(CimplifyContext.Provider, { value: contextValue, children });
|
|
4213
4349
|
}
|
|
4214
4350
|
function useCimplify() {
|
|
4215
|
-
const context =
|
|
4351
|
+
const context = React2.useContext(CimplifyContext);
|
|
4216
4352
|
if (!context) {
|
|
4217
4353
|
throw new Error("useCimplify must be used within CimplifyProvider");
|
|
4218
4354
|
}
|
|
4219
4355
|
return context;
|
|
4220
4356
|
}
|
|
4221
4357
|
function useOptionalCimplify() {
|
|
4222
|
-
return
|
|
4358
|
+
return React2.useContext(CimplifyContext);
|
|
4223
4359
|
}
|
|
4224
4360
|
var productsCache = /* @__PURE__ */ new Map();
|
|
4225
4361
|
var productsInflight = /* @__PURE__ */ new Map();
|
|
@@ -4238,9 +4374,9 @@ function useProducts(options = {}) {
|
|
|
4238
4374
|
}
|
|
4239
4375
|
const enabled = options.enabled ?? true;
|
|
4240
4376
|
const locationId = client.getLocationId();
|
|
4241
|
-
const previousLocationIdRef =
|
|
4242
|
-
const requestIdRef =
|
|
4243
|
-
const queryOptions =
|
|
4377
|
+
const previousLocationIdRef = React2.useRef(locationId);
|
|
4378
|
+
const requestIdRef = React2.useRef(0);
|
|
4379
|
+
const queryOptions = React2.useMemo(
|
|
4244
4380
|
() => ({
|
|
4245
4381
|
category: options.category,
|
|
4246
4382
|
collection: options.collection,
|
|
@@ -4250,25 +4386,25 @@ function useProducts(options = {}) {
|
|
|
4250
4386
|
}),
|
|
4251
4387
|
[options.category, options.collection, options.featured, options.limit, options.search]
|
|
4252
4388
|
);
|
|
4253
|
-
const cacheKey =
|
|
4389
|
+
const cacheKey = React2.useMemo(
|
|
4254
4390
|
() => buildProductsCacheKey(client, locationId, queryOptions),
|
|
4255
4391
|
[client, locationId, queryOptions]
|
|
4256
4392
|
);
|
|
4257
4393
|
const cached = productsCache.get(cacheKey);
|
|
4258
|
-
const [products, setProducts] =
|
|
4259
|
-
const [isComplete, setIsComplete] =
|
|
4260
|
-
const [totalAvailable, setTotalAvailable] =
|
|
4261
|
-
const [pagination, setPagination] =
|
|
4262
|
-
const [isLoading, setIsLoading] =
|
|
4263
|
-
const [error, setError] =
|
|
4264
|
-
|
|
4394
|
+
const [products, setProducts] = React2.useState(cached?.products ?? []);
|
|
4395
|
+
const [isComplete, setIsComplete] = React2.useState(cached?.is_complete ?? true);
|
|
4396
|
+
const [totalAvailable, setTotalAvailable] = React2.useState(cached?.total_available);
|
|
4397
|
+
const [pagination, setPagination] = React2.useState(cached?.pagination);
|
|
4398
|
+
const [isLoading, setIsLoading] = React2.useState(enabled && !cached);
|
|
4399
|
+
const [error, setError] = React2.useState(null);
|
|
4400
|
+
React2.useEffect(() => {
|
|
4265
4401
|
if (previousLocationIdRef.current !== locationId) {
|
|
4266
4402
|
productsCache.clear();
|
|
4267
4403
|
productsInflight.clear();
|
|
4268
4404
|
previousLocationIdRef.current = locationId;
|
|
4269
4405
|
}
|
|
4270
4406
|
}, [locationId]);
|
|
4271
|
-
const load =
|
|
4407
|
+
const load = React2.useCallback(
|
|
4272
4408
|
async (force = false) => {
|
|
4273
4409
|
if (!enabled) {
|
|
4274
4410
|
setIsLoading(false);
|
|
@@ -4331,10 +4467,10 @@ function useProducts(options = {}) {
|
|
|
4331
4467
|
},
|
|
4332
4468
|
[cacheKey, client, enabled, queryOptions]
|
|
4333
4469
|
);
|
|
4334
|
-
|
|
4470
|
+
React2.useEffect(() => {
|
|
4335
4471
|
void load(false);
|
|
4336
4472
|
}, [load]);
|
|
4337
|
-
const refetch =
|
|
4473
|
+
const refetch = React2.useCallback(async () => {
|
|
4338
4474
|
productsCache.delete(cacheKey);
|
|
4339
4475
|
await load(true);
|
|
4340
4476
|
}, [cacheKey, load]);
|
|
@@ -4368,27 +4504,27 @@ function useProduct(slugOrId, options = {}) {
|
|
|
4368
4504
|
}
|
|
4369
4505
|
const enabled = options.enabled ?? true;
|
|
4370
4506
|
const locationId = client.getLocationId();
|
|
4371
|
-
const previousLocationIdRef =
|
|
4372
|
-
const requestIdRef =
|
|
4373
|
-
const normalizedSlugOrId =
|
|
4374
|
-
const cacheKey =
|
|
4507
|
+
const previousLocationIdRef = React2.useRef(locationId);
|
|
4508
|
+
const requestIdRef = React2.useRef(0);
|
|
4509
|
+
const normalizedSlugOrId = React2.useMemo(() => (slugOrId || "").trim(), [slugOrId]);
|
|
4510
|
+
const cacheKey = React2.useMemo(
|
|
4375
4511
|
() => buildProductCacheKey(client, locationId, normalizedSlugOrId),
|
|
4376
4512
|
[client, locationId, normalizedSlugOrId]
|
|
4377
4513
|
);
|
|
4378
4514
|
const cached = productCache.get(cacheKey);
|
|
4379
|
-
const [product, setProduct] =
|
|
4380
|
-
const [isLoading, setIsLoading] =
|
|
4515
|
+
const [product, setProduct] = React2.useState(cached?.product ?? null);
|
|
4516
|
+
const [isLoading, setIsLoading] = React2.useState(
|
|
4381
4517
|
enabled && normalizedSlugOrId.length > 0 && !cached
|
|
4382
4518
|
);
|
|
4383
|
-
const [error, setError] =
|
|
4384
|
-
|
|
4519
|
+
const [error, setError] = React2.useState(null);
|
|
4520
|
+
React2.useEffect(() => {
|
|
4385
4521
|
if (previousLocationIdRef.current !== locationId) {
|
|
4386
4522
|
productCache.clear();
|
|
4387
4523
|
productInflight.clear();
|
|
4388
4524
|
previousLocationIdRef.current = locationId;
|
|
4389
4525
|
}
|
|
4390
4526
|
}, [locationId]);
|
|
4391
|
-
const load =
|
|
4527
|
+
const load = React2.useCallback(
|
|
4392
4528
|
async (force = false) => {
|
|
4393
4529
|
if (!enabled || normalizedSlugOrId.length === 0) {
|
|
4394
4530
|
setProduct(null);
|
|
@@ -4441,10 +4577,10 @@ function useProduct(slugOrId, options = {}) {
|
|
|
4441
4577
|
},
|
|
4442
4578
|
[cacheKey, client, enabled, normalizedSlugOrId]
|
|
4443
4579
|
);
|
|
4444
|
-
|
|
4580
|
+
React2.useEffect(() => {
|
|
4445
4581
|
void load(false);
|
|
4446
4582
|
}, [load]);
|
|
4447
|
-
const refetch =
|
|
4583
|
+
const refetch = React2.useCallback(async () => {
|
|
4448
4584
|
productCache.delete(cacheKey);
|
|
4449
4585
|
await load(true);
|
|
4450
4586
|
}, [cacheKey, load]);
|
|
@@ -4462,12 +4598,12 @@ function useCategories(options = {}) {
|
|
|
4462
4598
|
throw new Error("useCategories must be used within CimplifyProvider or passed { client }.");
|
|
4463
4599
|
}
|
|
4464
4600
|
const enabled = options.enabled ?? true;
|
|
4465
|
-
const cacheKey =
|
|
4601
|
+
const cacheKey = React2.useMemo(() => buildCategoriesCacheKey(client), [client]);
|
|
4466
4602
|
const cached = categoriesCache.get(cacheKey);
|
|
4467
|
-
const [categories, setCategories] =
|
|
4468
|
-
const [isLoading, setIsLoading] =
|
|
4469
|
-
const [error, setError] =
|
|
4470
|
-
const load =
|
|
4603
|
+
const [categories, setCategories] = React2.useState(cached ?? []);
|
|
4604
|
+
const [isLoading, setIsLoading] = React2.useState(enabled && !cached);
|
|
4605
|
+
const [error, setError] = React2.useState(null);
|
|
4606
|
+
const load = React2.useCallback(
|
|
4471
4607
|
async (force = false) => {
|
|
4472
4608
|
if (!enabled) {
|
|
4473
4609
|
setIsLoading(false);
|
|
@@ -4511,10 +4647,10 @@ function useCategories(options = {}) {
|
|
|
4511
4647
|
},
|
|
4512
4648
|
[cacheKey, client, enabled]
|
|
4513
4649
|
);
|
|
4514
|
-
|
|
4650
|
+
React2.useEffect(() => {
|
|
4515
4651
|
void load(false);
|
|
4516
4652
|
}, [load]);
|
|
4517
|
-
const refetch =
|
|
4653
|
+
const refetch = React2.useCallback(async () => {
|
|
4518
4654
|
categoriesCache.delete(cacheKey);
|
|
4519
4655
|
await load(true);
|
|
4520
4656
|
}, [cacheKey, load]);
|
|
@@ -5035,7 +5171,7 @@ function useCart(options = {}) {
|
|
|
5035
5171
|
const locationId = options.locationId ?? client.getLocationId();
|
|
5036
5172
|
const isDemoMode = options.demoMode ?? context?.isDemoMode ?? client.getPublicKey().trim().length === 0;
|
|
5037
5173
|
const currency = options.currency ?? context?.currency ?? "USD";
|
|
5038
|
-
const store =
|
|
5174
|
+
const store = React2.useMemo(
|
|
5039
5175
|
() => getOrCreateStore({
|
|
5040
5176
|
client,
|
|
5041
5177
|
locationId,
|
|
@@ -5044,43 +5180,43 @@ function useCart(options = {}) {
|
|
|
5044
5180
|
}),
|
|
5045
5181
|
[client, currency, isDemoMode, locationId]
|
|
5046
5182
|
);
|
|
5047
|
-
const snapshot =
|
|
5183
|
+
const snapshot = React2.useSyncExternalStore(
|
|
5048
5184
|
store.subscribe,
|
|
5049
5185
|
store.getSnapshot,
|
|
5050
5186
|
store.getSnapshot
|
|
5051
5187
|
);
|
|
5052
|
-
|
|
5188
|
+
React2.useEffect(() => {
|
|
5053
5189
|
void store.initialize();
|
|
5054
5190
|
}, [store]);
|
|
5055
|
-
const addItem =
|
|
5191
|
+
const addItem = React2.useCallback(
|
|
5056
5192
|
async (product, quantity, addOptions) => {
|
|
5057
5193
|
await store.addItem(product, quantity, addOptions);
|
|
5058
5194
|
},
|
|
5059
5195
|
[store]
|
|
5060
5196
|
);
|
|
5061
|
-
const removeItem =
|
|
5197
|
+
const removeItem = React2.useCallback(
|
|
5062
5198
|
async (itemId) => {
|
|
5063
5199
|
await store.removeItem(itemId);
|
|
5064
5200
|
},
|
|
5065
5201
|
[store]
|
|
5066
5202
|
);
|
|
5067
|
-
const updateQuantity =
|
|
5203
|
+
const updateQuantity = React2.useCallback(
|
|
5068
5204
|
async (itemId, quantity) => {
|
|
5069
5205
|
await store.updateQuantity(itemId, quantity);
|
|
5070
5206
|
},
|
|
5071
5207
|
[store]
|
|
5072
5208
|
);
|
|
5073
|
-
const clearCart =
|
|
5209
|
+
const clearCart = React2.useCallback(async () => {
|
|
5074
5210
|
await store.clearCart();
|
|
5075
5211
|
}, [store]);
|
|
5076
|
-
const sync =
|
|
5212
|
+
const sync = React2.useCallback(async () => {
|
|
5077
5213
|
try {
|
|
5078
5214
|
await store.sync();
|
|
5079
5215
|
} catch (syncError) {
|
|
5080
5216
|
throw syncError;
|
|
5081
5217
|
}
|
|
5082
5218
|
}, [store]);
|
|
5083
|
-
const itemCount =
|
|
5219
|
+
const itemCount = React2.useMemo(
|
|
5084
5220
|
() => snapshot.items.reduce((sum, item) => sum + item.quantity, 0),
|
|
5085
5221
|
[snapshot.items]
|
|
5086
5222
|
);
|
|
@@ -5111,22 +5247,22 @@ function useOrder(orderId, options = {}) {
|
|
|
5111
5247
|
if (!client) {
|
|
5112
5248
|
throw new Error("useOrder must be used within CimplifyProvider or passed { client }.");
|
|
5113
5249
|
}
|
|
5114
|
-
const normalizedOrderId =
|
|
5250
|
+
const normalizedOrderId = React2.useMemo(() => (orderId || "").trim(), [orderId]);
|
|
5115
5251
|
const enabled = options.enabled ?? true;
|
|
5116
5252
|
const poll = options.poll ?? false;
|
|
5117
5253
|
const pollInterval = options.pollInterval ?? 5e3;
|
|
5118
|
-
const requestIdRef =
|
|
5119
|
-
const cacheKey =
|
|
5254
|
+
const requestIdRef = React2.useRef(0);
|
|
5255
|
+
const cacheKey = React2.useMemo(
|
|
5120
5256
|
() => buildOrderCacheKey(client, normalizedOrderId),
|
|
5121
5257
|
[client, normalizedOrderId]
|
|
5122
5258
|
);
|
|
5123
5259
|
const cached = orderCache.get(cacheKey);
|
|
5124
|
-
const [order, setOrder] =
|
|
5125
|
-
const [isLoading, setIsLoading] =
|
|
5260
|
+
const [order, setOrder] = React2.useState(cached?.order ?? null);
|
|
5261
|
+
const [isLoading, setIsLoading] = React2.useState(
|
|
5126
5262
|
enabled && normalizedOrderId.length > 0 && !cached
|
|
5127
5263
|
);
|
|
5128
|
-
const [error, setError] =
|
|
5129
|
-
const load =
|
|
5264
|
+
const [error, setError] = React2.useState(null);
|
|
5265
|
+
const load = React2.useCallback(
|
|
5130
5266
|
async (force = false) => {
|
|
5131
5267
|
if (!enabled || normalizedOrderId.length === 0) {
|
|
5132
5268
|
setOrder(null);
|
|
@@ -5179,10 +5315,10 @@ function useOrder(orderId, options = {}) {
|
|
|
5179
5315
|
},
|
|
5180
5316
|
[cacheKey, client, enabled, normalizedOrderId]
|
|
5181
5317
|
);
|
|
5182
|
-
|
|
5318
|
+
React2.useEffect(() => {
|
|
5183
5319
|
void load(false);
|
|
5184
5320
|
}, [load]);
|
|
5185
|
-
|
|
5321
|
+
React2.useEffect(() => {
|
|
5186
5322
|
if (!poll || !enabled || normalizedOrderId.length === 0) {
|
|
5187
5323
|
return;
|
|
5188
5324
|
}
|
|
@@ -5193,7 +5329,7 @@ function useOrder(orderId, options = {}) {
|
|
|
5193
5329
|
window.clearInterval(timer);
|
|
5194
5330
|
};
|
|
5195
5331
|
}, [enabled, load, normalizedOrderId.length, poll, pollInterval]);
|
|
5196
|
-
const refetch =
|
|
5332
|
+
const refetch = React2.useCallback(async () => {
|
|
5197
5333
|
orderCache.delete(cacheKey);
|
|
5198
5334
|
await load(true);
|
|
5199
5335
|
}, [cacheKey, load]);
|
|
@@ -5244,10 +5380,10 @@ function useLocations(options = {}) {
|
|
|
5244
5380
|
};
|
|
5245
5381
|
}
|
|
5246
5382
|
const client = options.client;
|
|
5247
|
-
const [locations, setLocations] =
|
|
5248
|
-
const [currentLocation, setCurrentLocationState] =
|
|
5249
|
-
const [isLoading, setIsLoading] =
|
|
5250
|
-
const setCurrentLocation =
|
|
5383
|
+
const [locations, setLocations] = React2.useState([]);
|
|
5384
|
+
const [currentLocation, setCurrentLocationState] = React2.useState(null);
|
|
5385
|
+
const [isLoading, setIsLoading] = React2.useState(true);
|
|
5386
|
+
const setCurrentLocation = React2.useCallback(
|
|
5251
5387
|
(location) => {
|
|
5252
5388
|
setCurrentLocationState(location);
|
|
5253
5389
|
if (client) {
|
|
@@ -5257,7 +5393,7 @@ function useLocations(options = {}) {
|
|
|
5257
5393
|
},
|
|
5258
5394
|
[client]
|
|
5259
5395
|
);
|
|
5260
|
-
|
|
5396
|
+
React2.useEffect(() => {
|
|
5261
5397
|
if (!client) {
|
|
5262
5398
|
setLocations([]);
|
|
5263
5399
|
setCurrentLocationState(null);
|
|
@@ -5315,24 +5451,24 @@ function useCollections(options = {}) {
|
|
|
5315
5451
|
}
|
|
5316
5452
|
const enabled = options.enabled ?? true;
|
|
5317
5453
|
const locationId = client.getLocationId();
|
|
5318
|
-
const previousLocationIdRef =
|
|
5319
|
-
const requestIdRef =
|
|
5320
|
-
const cacheKey =
|
|
5454
|
+
const previousLocationIdRef = React2.useRef(locationId);
|
|
5455
|
+
const requestIdRef = React2.useRef(0);
|
|
5456
|
+
const cacheKey = React2.useMemo(
|
|
5321
5457
|
() => buildCollectionsCacheKey(client, locationId),
|
|
5322
5458
|
[client, locationId]
|
|
5323
5459
|
);
|
|
5324
5460
|
const cached = collectionsCache.get(cacheKey);
|
|
5325
|
-
const [collections, setCollections] =
|
|
5326
|
-
const [isLoading, setIsLoading] =
|
|
5327
|
-
const [error, setError] =
|
|
5328
|
-
|
|
5461
|
+
const [collections, setCollections] = React2.useState(cached?.collections ?? []);
|
|
5462
|
+
const [isLoading, setIsLoading] = React2.useState(enabled && !cached);
|
|
5463
|
+
const [error, setError] = React2.useState(null);
|
|
5464
|
+
React2.useEffect(() => {
|
|
5329
5465
|
if (previousLocationIdRef.current !== locationId) {
|
|
5330
5466
|
collectionsCache.clear();
|
|
5331
5467
|
collectionsInflight.clear();
|
|
5332
5468
|
previousLocationIdRef.current = locationId;
|
|
5333
5469
|
}
|
|
5334
5470
|
}, [locationId]);
|
|
5335
|
-
const load =
|
|
5471
|
+
const load = React2.useCallback(
|
|
5336
5472
|
async (force = false) => {
|
|
5337
5473
|
if (!enabled) {
|
|
5338
5474
|
setIsLoading(false);
|
|
@@ -5382,10 +5518,10 @@ function useCollections(options = {}) {
|
|
|
5382
5518
|
},
|
|
5383
5519
|
[cacheKey, client, enabled]
|
|
5384
5520
|
);
|
|
5385
|
-
|
|
5521
|
+
React2.useEffect(() => {
|
|
5386
5522
|
void load(false);
|
|
5387
5523
|
}, [load]);
|
|
5388
|
-
const refetch =
|
|
5524
|
+
const refetch = React2.useCallback(async () => {
|
|
5389
5525
|
collectionsCache.delete(cacheKey);
|
|
5390
5526
|
await load(true);
|
|
5391
5527
|
}, [cacheKey, load]);
|
|
@@ -5411,28 +5547,28 @@ function useCollection(idOrSlug, options = {}) {
|
|
|
5411
5547
|
}
|
|
5412
5548
|
const enabled = options.enabled ?? true;
|
|
5413
5549
|
const locationId = client.getLocationId();
|
|
5414
|
-
const previousLocationIdRef =
|
|
5415
|
-
const requestIdRef =
|
|
5416
|
-
const normalizedIdOrSlug =
|
|
5417
|
-
const cacheKey =
|
|
5550
|
+
const previousLocationIdRef = React2.useRef(locationId);
|
|
5551
|
+
const requestIdRef = React2.useRef(0);
|
|
5552
|
+
const normalizedIdOrSlug = React2.useMemo(() => (idOrSlug || "").trim(), [idOrSlug]);
|
|
5553
|
+
const cacheKey = React2.useMemo(
|
|
5418
5554
|
() => buildCollectionCacheKey(client, locationId, normalizedIdOrSlug),
|
|
5419
5555
|
[client, locationId, normalizedIdOrSlug]
|
|
5420
5556
|
);
|
|
5421
5557
|
const cached = collectionCache.get(cacheKey);
|
|
5422
|
-
const [collection, setCollection] =
|
|
5423
|
-
const [products, setProducts] =
|
|
5424
|
-
const [isLoading, setIsLoading] =
|
|
5558
|
+
const [collection, setCollection] = React2.useState(cached?.collection ?? null);
|
|
5559
|
+
const [products, setProducts] = React2.useState(cached?.products ?? []);
|
|
5560
|
+
const [isLoading, setIsLoading] = React2.useState(
|
|
5425
5561
|
enabled && normalizedIdOrSlug.length > 0 && !cached
|
|
5426
5562
|
);
|
|
5427
|
-
const [error, setError] =
|
|
5428
|
-
|
|
5563
|
+
const [error, setError] = React2.useState(null);
|
|
5564
|
+
React2.useEffect(() => {
|
|
5429
5565
|
if (previousLocationIdRef.current !== locationId) {
|
|
5430
5566
|
collectionCache.clear();
|
|
5431
5567
|
collectionInflight.clear();
|
|
5432
5568
|
previousLocationIdRef.current = locationId;
|
|
5433
5569
|
}
|
|
5434
5570
|
}, [locationId]);
|
|
5435
|
-
const load =
|
|
5571
|
+
const load = React2.useCallback(
|
|
5436
5572
|
async (force = false) => {
|
|
5437
5573
|
if (!enabled || normalizedIdOrSlug.length === 0) {
|
|
5438
5574
|
setCollection(null);
|
|
@@ -5495,10 +5631,10 @@ function useCollection(idOrSlug, options = {}) {
|
|
|
5495
5631
|
},
|
|
5496
5632
|
[cacheKey, client, enabled, normalizedIdOrSlug]
|
|
5497
5633
|
);
|
|
5498
|
-
|
|
5634
|
+
React2.useEffect(() => {
|
|
5499
5635
|
void load(false);
|
|
5500
5636
|
}, [load]);
|
|
5501
|
-
const refetch =
|
|
5637
|
+
const refetch = React2.useCallback(async () => {
|
|
5502
5638
|
collectionCache.delete(cacheKey);
|
|
5503
5639
|
await load(true);
|
|
5504
5640
|
}, [cacheKey, load]);
|
|
@@ -5524,27 +5660,27 @@ function useBundle(idOrSlug, options = {}) {
|
|
|
5524
5660
|
}
|
|
5525
5661
|
const enabled = options.enabled ?? true;
|
|
5526
5662
|
const locationId = client.getLocationId();
|
|
5527
|
-
const previousLocationIdRef =
|
|
5528
|
-
const requestIdRef =
|
|
5529
|
-
const normalizedIdOrSlug =
|
|
5530
|
-
const cacheKey =
|
|
5663
|
+
const previousLocationIdRef = React2.useRef(locationId);
|
|
5664
|
+
const requestIdRef = React2.useRef(0);
|
|
5665
|
+
const normalizedIdOrSlug = React2.useMemo(() => (idOrSlug || "").trim(), [idOrSlug]);
|
|
5666
|
+
const cacheKey = React2.useMemo(
|
|
5531
5667
|
() => buildBundleCacheKey(client, locationId, normalizedIdOrSlug),
|
|
5532
5668
|
[client, locationId, normalizedIdOrSlug]
|
|
5533
5669
|
);
|
|
5534
5670
|
const cached = bundleCache.get(cacheKey);
|
|
5535
|
-
const [bundle, setBundle] =
|
|
5536
|
-
const [isLoading, setIsLoading] =
|
|
5671
|
+
const [bundle, setBundle] = React2.useState(cached?.bundle ?? null);
|
|
5672
|
+
const [isLoading, setIsLoading] = React2.useState(
|
|
5537
5673
|
enabled && normalizedIdOrSlug.length > 0 && !cached
|
|
5538
5674
|
);
|
|
5539
|
-
const [error, setError] =
|
|
5540
|
-
|
|
5675
|
+
const [error, setError] = React2.useState(null);
|
|
5676
|
+
React2.useEffect(() => {
|
|
5541
5677
|
if (previousLocationIdRef.current !== locationId) {
|
|
5542
5678
|
bundleCache.clear();
|
|
5543
5679
|
bundleInflight.clear();
|
|
5544
5680
|
previousLocationIdRef.current = locationId;
|
|
5545
5681
|
}
|
|
5546
5682
|
}, [locationId]);
|
|
5547
|
-
const load =
|
|
5683
|
+
const load = React2.useCallback(
|
|
5548
5684
|
async (force = false) => {
|
|
5549
5685
|
if (!enabled || normalizedIdOrSlug.length === 0) {
|
|
5550
5686
|
setBundle(null);
|
|
@@ -5595,10 +5731,10 @@ function useBundle(idOrSlug, options = {}) {
|
|
|
5595
5731
|
},
|
|
5596
5732
|
[cacheKey, client, enabled, normalizedIdOrSlug]
|
|
5597
5733
|
);
|
|
5598
|
-
|
|
5734
|
+
React2.useEffect(() => {
|
|
5599
5735
|
void load(false);
|
|
5600
5736
|
}, [load]);
|
|
5601
|
-
const refetch =
|
|
5737
|
+
const refetch = React2.useCallback(async () => {
|
|
5602
5738
|
bundleCache.delete(cacheKey);
|
|
5603
5739
|
await load(true);
|
|
5604
5740
|
}, [cacheKey, load]);
|
|
@@ -5628,37 +5764,37 @@ function useComposite(idOrProductId, options = {}) {
|
|
|
5628
5764
|
}
|
|
5629
5765
|
const enabled = options.enabled ?? true;
|
|
5630
5766
|
const locationId = client.getLocationId();
|
|
5631
|
-
const previousLocationIdRef =
|
|
5632
|
-
const requestIdRef =
|
|
5633
|
-
const priceRequestIdRef =
|
|
5634
|
-
const normalizedIdOrProductId =
|
|
5767
|
+
const previousLocationIdRef = React2.useRef(locationId);
|
|
5768
|
+
const requestIdRef = React2.useRef(0);
|
|
5769
|
+
const priceRequestIdRef = React2.useRef(0);
|
|
5770
|
+
const normalizedIdOrProductId = React2.useMemo(
|
|
5635
5771
|
() => (idOrProductId || "").trim(),
|
|
5636
5772
|
[idOrProductId]
|
|
5637
5773
|
);
|
|
5638
|
-
const byProductId =
|
|
5774
|
+
const byProductId = React2.useMemo(
|
|
5639
5775
|
() => shouldFetchByProductId(normalizedIdOrProductId, options.byProductId),
|
|
5640
5776
|
[normalizedIdOrProductId, options.byProductId]
|
|
5641
5777
|
);
|
|
5642
|
-
const cacheKey =
|
|
5778
|
+
const cacheKey = React2.useMemo(
|
|
5643
5779
|
() => buildCompositeCacheKey(client, locationId, normalizedIdOrProductId, byProductId),
|
|
5644
5780
|
[byProductId, client, locationId, normalizedIdOrProductId]
|
|
5645
5781
|
);
|
|
5646
5782
|
const cached = compositeCache.get(cacheKey);
|
|
5647
|
-
const [composite, setComposite] =
|
|
5648
|
-
const [isLoading, setIsLoading] =
|
|
5783
|
+
const [composite, setComposite] = React2.useState(cached?.composite ?? null);
|
|
5784
|
+
const [isLoading, setIsLoading] = React2.useState(
|
|
5649
5785
|
enabled && normalizedIdOrProductId.length > 0 && !cached
|
|
5650
5786
|
);
|
|
5651
|
-
const [error, setError] =
|
|
5652
|
-
const [priceResult, setPriceResult] =
|
|
5653
|
-
const [isPriceLoading, setIsPriceLoading] =
|
|
5654
|
-
|
|
5787
|
+
const [error, setError] = React2.useState(null);
|
|
5788
|
+
const [priceResult, setPriceResult] = React2.useState(null);
|
|
5789
|
+
const [isPriceLoading, setIsPriceLoading] = React2.useState(false);
|
|
5790
|
+
React2.useEffect(() => {
|
|
5655
5791
|
if (previousLocationIdRef.current !== locationId) {
|
|
5656
5792
|
compositeCache.clear();
|
|
5657
5793
|
compositeInflight.clear();
|
|
5658
5794
|
previousLocationIdRef.current = locationId;
|
|
5659
5795
|
}
|
|
5660
5796
|
}, [locationId]);
|
|
5661
|
-
const load =
|
|
5797
|
+
const load = React2.useCallback(
|
|
5662
5798
|
async (force = false) => {
|
|
5663
5799
|
if (!enabled || normalizedIdOrProductId.length === 0) {
|
|
5664
5800
|
setComposite(null);
|
|
@@ -5711,10 +5847,10 @@ function useComposite(idOrProductId, options = {}) {
|
|
|
5711
5847
|
},
|
|
5712
5848
|
[byProductId, cacheKey, client, enabled, normalizedIdOrProductId]
|
|
5713
5849
|
);
|
|
5714
|
-
|
|
5850
|
+
React2.useEffect(() => {
|
|
5715
5851
|
void load(false);
|
|
5716
5852
|
}, [load]);
|
|
5717
|
-
const calculatePrice =
|
|
5853
|
+
const calculatePrice = React2.useCallback(
|
|
5718
5854
|
async (selections, overrideLocationId) => {
|
|
5719
5855
|
if (!composite) {
|
|
5720
5856
|
return null;
|
|
@@ -5748,7 +5884,7 @@ function useComposite(idOrProductId, options = {}) {
|
|
|
5748
5884
|
},
|
|
5749
5885
|
[client, composite]
|
|
5750
5886
|
);
|
|
5751
|
-
const refetch =
|
|
5887
|
+
const refetch = React2.useCallback(async () => {
|
|
5752
5888
|
compositeCache.delete(cacheKey);
|
|
5753
5889
|
await load(true);
|
|
5754
5890
|
}, [cacheKey, load]);
|
|
@@ -5763,13 +5899,13 @@ function useSearch(options = {}) {
|
|
|
5763
5899
|
const minLength = Math.max(0, options.minLength ?? 2);
|
|
5764
5900
|
const debounceMs = Math.max(0, options.debounceMs ?? 300);
|
|
5765
5901
|
const limit = Math.max(1, options.limit ?? 20);
|
|
5766
|
-
const [query, setQueryState] =
|
|
5767
|
-
const [results, setResults] =
|
|
5768
|
-
const [isLoading, setIsLoading] =
|
|
5769
|
-
const [error, setError] =
|
|
5770
|
-
const requestIdRef =
|
|
5771
|
-
const timerRef =
|
|
5772
|
-
|
|
5902
|
+
const [query, setQueryState] = React2.useState("");
|
|
5903
|
+
const [results, setResults] = React2.useState([]);
|
|
5904
|
+
const [isLoading, setIsLoading] = React2.useState(false);
|
|
5905
|
+
const [error, setError] = React2.useState(null);
|
|
5906
|
+
const requestIdRef = React2.useRef(0);
|
|
5907
|
+
const timerRef = React2.useRef(null);
|
|
5908
|
+
React2.useEffect(() => {
|
|
5773
5909
|
if (timerRef.current) {
|
|
5774
5910
|
clearTimeout(timerRef.current);
|
|
5775
5911
|
timerRef.current = null;
|
|
@@ -5816,10 +5952,10 @@ function useSearch(options = {}) {
|
|
|
5816
5952
|
}
|
|
5817
5953
|
};
|
|
5818
5954
|
}, [client, debounceMs, limit, minLength, options.category, query]);
|
|
5819
|
-
const setQuery =
|
|
5955
|
+
const setQuery = React2.useCallback((nextQuery) => {
|
|
5820
5956
|
setQueryState(nextQuery);
|
|
5821
5957
|
}, []);
|
|
5822
|
-
const clear =
|
|
5958
|
+
const clear = React2.useCallback(() => {
|
|
5823
5959
|
requestIdRef.current += 1;
|
|
5824
5960
|
if (timerRef.current) {
|
|
5825
5961
|
clearTimeout(timerRef.current);
|
|
@@ -5875,28 +6011,28 @@ function useQuote(input, options = {}) {
|
|
|
5875
6011
|
const autoRefresh = options.autoRefresh ?? true;
|
|
5876
6012
|
const refreshBeforeExpiryMs = Math.max(0, options.refreshBeforeExpiryMs ?? 3e4);
|
|
5877
6013
|
const locationId = client.getLocationId();
|
|
5878
|
-
const requestIdRef =
|
|
5879
|
-
const refreshTimerRef =
|
|
5880
|
-
const expiryTimerRef =
|
|
5881
|
-
const inputSignature =
|
|
5882
|
-
const normalizedInput =
|
|
6014
|
+
const requestIdRef = React2.useRef(0);
|
|
6015
|
+
const refreshTimerRef = React2.useRef(null);
|
|
6016
|
+
const expiryTimerRef = React2.useRef(null);
|
|
6017
|
+
const inputSignature = React2.useMemo(() => JSON.stringify(input ?? null), [input]);
|
|
6018
|
+
const normalizedInput = React2.useMemo(() => {
|
|
5883
6019
|
if (!input) {
|
|
5884
6020
|
return null;
|
|
5885
6021
|
}
|
|
5886
6022
|
const normalized = normalizeInput(input, locationId);
|
|
5887
6023
|
return normalized.product_id.length > 0 ? normalized : null;
|
|
5888
6024
|
}, [inputSignature, locationId]);
|
|
5889
|
-
const cacheKey =
|
|
6025
|
+
const cacheKey = React2.useMemo(
|
|
5890
6026
|
() => buildQuoteCacheKey(client, locationId, inputSignature),
|
|
5891
6027
|
[client, inputSignature, locationId]
|
|
5892
6028
|
);
|
|
5893
6029
|
const cached = quoteCache.get(cacheKey);
|
|
5894
|
-
const [quote, setQuote] =
|
|
5895
|
-
const [isLoading, setIsLoading] =
|
|
5896
|
-
const [error, setError] =
|
|
5897
|
-
const [isExpired, setIsExpired] =
|
|
5898
|
-
const [messages, setMessages] =
|
|
5899
|
-
const load =
|
|
6030
|
+
const [quote, setQuote] = React2.useState(cached?.quote ?? null);
|
|
6031
|
+
const [isLoading, setIsLoading] = React2.useState(enabled && normalizedInput !== null && !cached);
|
|
6032
|
+
const [error, setError] = React2.useState(null);
|
|
6033
|
+
const [isExpired, setIsExpired] = React2.useState(isQuoteExpired(cached?.quote ?? null));
|
|
6034
|
+
const [messages, setMessages] = React2.useState(cached?.quote?.ui_messages ?? []);
|
|
6035
|
+
const load = React2.useCallback(
|
|
5900
6036
|
async (force = false) => {
|
|
5901
6037
|
if (!enabled || !normalizedInput) {
|
|
5902
6038
|
setQuote(null);
|
|
@@ -5954,10 +6090,10 @@ function useQuote(input, options = {}) {
|
|
|
5954
6090
|
},
|
|
5955
6091
|
[cacheKey, client, enabled, normalizedInput]
|
|
5956
6092
|
);
|
|
5957
|
-
|
|
6093
|
+
React2.useEffect(() => {
|
|
5958
6094
|
void load(false);
|
|
5959
6095
|
}, [load]);
|
|
5960
|
-
const refresh =
|
|
6096
|
+
const refresh = React2.useCallback(async () => {
|
|
5961
6097
|
if (!enabled || !normalizedInput) {
|
|
5962
6098
|
return;
|
|
5963
6099
|
}
|
|
@@ -5994,7 +6130,7 @@ function useQuote(input, options = {}) {
|
|
|
5994
6130
|
}
|
|
5995
6131
|
}
|
|
5996
6132
|
}, [cacheKey, client, enabled, load, normalizedInput, quote]);
|
|
5997
|
-
|
|
6133
|
+
React2.useEffect(() => {
|
|
5998
6134
|
if (expiryTimerRef.current) {
|
|
5999
6135
|
clearTimeout(expiryTimerRef.current);
|
|
6000
6136
|
expiryTimerRef.current = null;
|
|
@@ -6018,7 +6154,7 @@ function useQuote(input, options = {}) {
|
|
|
6018
6154
|
}
|
|
6019
6155
|
};
|
|
6020
6156
|
}, [quote?.expires_at, quote?.quote_id]);
|
|
6021
|
-
|
|
6157
|
+
React2.useEffect(() => {
|
|
6022
6158
|
if (refreshTimerRef.current) {
|
|
6023
6159
|
clearTimeout(refreshTimerRef.current);
|
|
6024
6160
|
refreshTimerRef.current = null;
|
|
@@ -6043,15 +6179,15 @@ function useQuote(input, options = {}) {
|
|
|
6043
6179
|
}, [autoRefresh, enabled, quote?.expires_at, quote?.quote_id, refresh, refreshBeforeExpiryMs]);
|
|
6044
6180
|
return { quote, isLoading, error, refresh, isExpired, messages };
|
|
6045
6181
|
}
|
|
6046
|
-
var ElementsContext =
|
|
6182
|
+
var ElementsContext = React2.createContext({
|
|
6047
6183
|
elements: null,
|
|
6048
6184
|
isReady: false
|
|
6049
6185
|
});
|
|
6050
6186
|
function useElements() {
|
|
6051
|
-
return
|
|
6187
|
+
return React2.useContext(ElementsContext).elements;
|
|
6052
6188
|
}
|
|
6053
6189
|
function useElementsReady() {
|
|
6054
|
-
return
|
|
6190
|
+
return React2.useContext(ElementsContext).isReady;
|
|
6055
6191
|
}
|
|
6056
6192
|
function ElementsProvider({
|
|
6057
6193
|
client,
|
|
@@ -6059,10 +6195,10 @@ function ElementsProvider({
|
|
|
6059
6195
|
options,
|
|
6060
6196
|
children
|
|
6061
6197
|
}) {
|
|
6062
|
-
const [elements, setElements] =
|
|
6063
|
-
const [isReady, setIsReady] =
|
|
6064
|
-
const initialOptionsRef =
|
|
6065
|
-
|
|
6198
|
+
const [elements, setElements] = React2.useState(null);
|
|
6199
|
+
const [isReady, setIsReady] = React2.useState(false);
|
|
6200
|
+
const initialOptionsRef = React2.useRef(options);
|
|
6201
|
+
React2.useEffect(() => {
|
|
6066
6202
|
let cancelled = false;
|
|
6067
6203
|
let instance = null;
|
|
6068
6204
|
setIsReady(false);
|
|
@@ -6103,20 +6239,20 @@ function AuthElement({
|
|
|
6103
6239
|
onRequiresOtp,
|
|
6104
6240
|
onError
|
|
6105
6241
|
}) {
|
|
6106
|
-
const containerRef =
|
|
6107
|
-
const elementRef =
|
|
6242
|
+
const containerRef = React2.useRef(null);
|
|
6243
|
+
const elementRef = React2.useRef(null);
|
|
6108
6244
|
const elements = useElements();
|
|
6109
|
-
const onReadyRef =
|
|
6110
|
-
const onAuthenticatedRef =
|
|
6111
|
-
const onRequiresOtpRef =
|
|
6112
|
-
const onErrorRef =
|
|
6113
|
-
|
|
6245
|
+
const onReadyRef = React2.useRef(onReady);
|
|
6246
|
+
const onAuthenticatedRef = React2.useRef(onAuthenticated);
|
|
6247
|
+
const onRequiresOtpRef = React2.useRef(onRequiresOtp);
|
|
6248
|
+
const onErrorRef = React2.useRef(onError);
|
|
6249
|
+
React2.useEffect(() => {
|
|
6114
6250
|
onReadyRef.current = onReady;
|
|
6115
6251
|
onAuthenticatedRef.current = onAuthenticated;
|
|
6116
6252
|
onRequiresOtpRef.current = onRequiresOtp;
|
|
6117
6253
|
onErrorRef.current = onError;
|
|
6118
6254
|
}, [onReady, onAuthenticated, onRequiresOtp, onError]);
|
|
6119
|
-
|
|
6255
|
+
React2.useEffect(() => {
|
|
6120
6256
|
if (!elements || !containerRef.current) return;
|
|
6121
6257
|
const element = elements.create(ELEMENT_TYPES.AUTH, { prefillEmail });
|
|
6122
6258
|
elementRef.current = element;
|
|
@@ -6146,18 +6282,18 @@ function AddressElement({
|
|
|
6146
6282
|
onChange,
|
|
6147
6283
|
onError
|
|
6148
6284
|
}) {
|
|
6149
|
-
const containerRef =
|
|
6150
|
-
const elementRef =
|
|
6285
|
+
const containerRef = React2.useRef(null);
|
|
6286
|
+
const elementRef = React2.useRef(null);
|
|
6151
6287
|
const elements = useElements();
|
|
6152
|
-
const onReadyRef =
|
|
6153
|
-
const onChangeRef =
|
|
6154
|
-
const onErrorRef =
|
|
6155
|
-
|
|
6288
|
+
const onReadyRef = React2.useRef(onReady);
|
|
6289
|
+
const onChangeRef = React2.useRef(onChange);
|
|
6290
|
+
const onErrorRef = React2.useRef(onError);
|
|
6291
|
+
React2.useEffect(() => {
|
|
6156
6292
|
onReadyRef.current = onReady;
|
|
6157
6293
|
onChangeRef.current = onChange;
|
|
6158
6294
|
onErrorRef.current = onError;
|
|
6159
6295
|
}, [onReady, onChange, onError]);
|
|
6160
|
-
|
|
6296
|
+
React2.useEffect(() => {
|
|
6161
6297
|
if (!elements || !containerRef.current) return;
|
|
6162
6298
|
const element = elements.create(ELEMENT_TYPES.ADDRESS, { mode });
|
|
6163
6299
|
elementRef.current = element;
|
|
@@ -6184,18 +6320,18 @@ function PaymentElement({
|
|
|
6184
6320
|
onChange,
|
|
6185
6321
|
onError
|
|
6186
6322
|
}) {
|
|
6187
|
-
const containerRef =
|
|
6188
|
-
const elementRef =
|
|
6323
|
+
const containerRef = React2.useRef(null);
|
|
6324
|
+
const elementRef = React2.useRef(null);
|
|
6189
6325
|
const elements = useElements();
|
|
6190
|
-
const onReadyRef =
|
|
6191
|
-
const onChangeRef =
|
|
6192
|
-
const onErrorRef =
|
|
6193
|
-
|
|
6326
|
+
const onReadyRef = React2.useRef(onReady);
|
|
6327
|
+
const onChangeRef = React2.useRef(onChange);
|
|
6328
|
+
const onErrorRef = React2.useRef(onError);
|
|
6329
|
+
React2.useEffect(() => {
|
|
6194
6330
|
onReadyRef.current = onReady;
|
|
6195
6331
|
onChangeRef.current = onChange;
|
|
6196
6332
|
onErrorRef.current = onError;
|
|
6197
6333
|
}, [onReady, onChange, onError]);
|
|
6198
|
-
|
|
6334
|
+
React2.useEffect(() => {
|
|
6199
6335
|
if (!elements || !containerRef.current) return;
|
|
6200
6336
|
const element = elements.create(ELEMENT_TYPES.PAYMENT, { amount, currency });
|
|
6201
6337
|
elementRef.current = element;
|
|
@@ -6215,8 +6351,8 @@ function PaymentElement({
|
|
|
6215
6351
|
}
|
|
6216
6352
|
function useCheckout() {
|
|
6217
6353
|
const elements = useElements();
|
|
6218
|
-
const [isLoading, setIsLoading] =
|
|
6219
|
-
const submit =
|
|
6354
|
+
const [isLoading, setIsLoading] = React2.useState(false);
|
|
6355
|
+
const submit = React2.useCallback(
|
|
6220
6356
|
async (data) => {
|
|
6221
6357
|
if (!elements) {
|
|
6222
6358
|
return { success: false, error: { code: "NO_ELEMENTS", message: "Elements not initialized" } };
|
|
@@ -6230,7 +6366,7 @@ function useCheckout() {
|
|
|
6230
6366
|
},
|
|
6231
6367
|
[elements]
|
|
6232
6368
|
);
|
|
6233
|
-
const process =
|
|
6369
|
+
const process = React2.useCallback(
|
|
6234
6370
|
async (options) => {
|
|
6235
6371
|
if (!elements) {
|
|
6236
6372
|
return {
|