@cimplify/sdk 0.22.0 → 0.22.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 -24
- package/dist/advanced.d.ts +1 -24
- package/dist/advanced.js +0 -9
- package/dist/advanced.mjs +0 -1
- package/dist/index.d.mts +1 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.js +0 -9
- package/dist/index.mjs +0 -1
- package/dist/react.d.mts +32 -91
- package/dist/react.d.ts +32 -91
- package/dist/react.js +687 -2296
- package/dist/react.mjs +688 -2297
- package/package.json +1 -1
- package/dist/chunk-FLPI2VVJ.js +0 -72
- package/dist/chunk-LM3CJ4L7.mjs +0 -69
- /package/dist/{client-uvCOGdBp.d.ts → index-uvCOGdBp.d.ts} +0 -0
- /package/dist/{client-v1NFqZFG.d.mts → index-v1NFqZFG.d.mts} +0 -0
package/dist/react.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { getVariantDisplayName, createCimplifyClient } from './chunk-W3DMONZR.mj
|
|
|
3
3
|
export { getVariantDisplayName } from './chunk-W3DMONZR.mjs';
|
|
4
4
|
import { ELEMENT_TYPES, EVENT_TYPES } from './chunk-R4EYMPSN.mjs';
|
|
5
5
|
import { isSupportedCurrency, formatPrice, parsePrice, isOnSale, getDiscountPercentage, getBasePrice } from './chunk-JFT63H34.mjs';
|
|
6
|
-
import React3, { createContext,
|
|
6
|
+
import React3, { createContext, useRef, useState, useCallback, useEffect, useContext, useMemo, useSyncExternalStore, useId } from 'react';
|
|
7
7
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
8
8
|
import { NumberField } from '@base-ui/react/number-field';
|
|
9
9
|
import { clsx } from 'clsx';
|
|
@@ -1679,41 +1679,130 @@ function Price({ amount, className, prefix }) {
|
|
|
1679
1679
|
formatPrice(convertPrice(amount), displayCurrency)
|
|
1680
1680
|
] });
|
|
1681
1681
|
}
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
options.tags?.join(",") ?? "",
|
|
1696
|
-
options.in_stock ?? "",
|
|
1697
|
-
options.min_price ?? "",
|
|
1698
|
-
options.max_price ?? "",
|
|
1699
|
-
options.page ?? "",
|
|
1700
|
-
options.properties ? JSON.stringify(options.properties) : ""
|
|
1701
|
-
].join("|");
|
|
1702
|
-
}
|
|
1703
|
-
function useProducts(options = {}) {
|
|
1704
|
-
const context = useOptionalCimplifyClient();
|
|
1705
|
-
const client = options.client ?? context?.client;
|
|
1706
|
-
if (!client) {
|
|
1707
|
-
throw new Error("useProducts must be used within CimplifyProvider or passed { client }.");
|
|
1682
|
+
function createCachedQuery(config) {
|
|
1683
|
+
const cache = /* @__PURE__ */ new Map();
|
|
1684
|
+
const inflight = /* @__PURE__ */ new Map();
|
|
1685
|
+
const gcMaxAge = config.gcMaxAge ?? 3e5;
|
|
1686
|
+
let lastSweep = 0;
|
|
1687
|
+
function sweep() {
|
|
1688
|
+
const now = Date.now();
|
|
1689
|
+
if (now - lastSweep < 6e4) return;
|
|
1690
|
+
lastSweep = now;
|
|
1691
|
+
const cutoff = now - gcMaxAge;
|
|
1692
|
+
for (const [key, entry] of cache) {
|
|
1693
|
+
if (entry.ts < cutoff) cache.delete(key);
|
|
1694
|
+
}
|
|
1708
1695
|
}
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1696
|
+
function useCachedQuery(options = {}) {
|
|
1697
|
+
const context = useOptionalCimplifyClient();
|
|
1698
|
+
const client = options.client ?? context?.client;
|
|
1699
|
+
if (!client) {
|
|
1700
|
+
throw new Error(
|
|
1701
|
+
`${config.name} must be used within CimplifyProvider or passed { client }.`
|
|
1702
|
+
);
|
|
1703
|
+
}
|
|
1704
|
+
const enabled = options.enabled ?? true;
|
|
1705
|
+
const locationId = client.getLocationId();
|
|
1706
|
+
const previousLocationRef = useRef(locationId);
|
|
1707
|
+
const requestIdRef = useRef(0);
|
|
1708
|
+
const optionsRef = useRef(options);
|
|
1709
|
+
optionsRef.current = options;
|
|
1710
|
+
if (config.locationSensitive && previousLocationRef.current !== locationId) {
|
|
1711
|
+
cache.clear();
|
|
1712
|
+
inflight.clear();
|
|
1713
|
+
previousLocationRef.current = locationId;
|
|
1714
|
+
}
|
|
1715
|
+
sweep();
|
|
1716
|
+
const cacheKey2 = config.key(client, options);
|
|
1717
|
+
const cached = cache.get(cacheKey2);
|
|
1718
|
+
const [data, setData] = useState(cached?.data ?? null);
|
|
1719
|
+
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
1720
|
+
const [error, setError] = useState(null);
|
|
1721
|
+
const load = useCallback(
|
|
1722
|
+
async (force = false) => {
|
|
1723
|
+
if (!enabled) {
|
|
1724
|
+
setIsLoading(false);
|
|
1725
|
+
return;
|
|
1726
|
+
}
|
|
1727
|
+
const nextRequestId = ++requestIdRef.current;
|
|
1728
|
+
setError(null);
|
|
1729
|
+
if (!force) {
|
|
1730
|
+
const hit = cache.get(cacheKey2);
|
|
1731
|
+
if (hit) {
|
|
1732
|
+
setData(hit.data);
|
|
1733
|
+
setIsLoading(false);
|
|
1734
|
+
return;
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
setIsLoading(true);
|
|
1738
|
+
try {
|
|
1739
|
+
const existing = inflight.get(cacheKey2);
|
|
1740
|
+
const promise = existing ?? (async () => config.fetch(client, optionsRef.current))();
|
|
1741
|
+
if (!existing) {
|
|
1742
|
+
inflight.set(cacheKey2, promise);
|
|
1743
|
+
promise.finally(() => inflight.delete(cacheKey2)).catch(() => {
|
|
1744
|
+
});
|
|
1745
|
+
}
|
|
1746
|
+
const value = await promise;
|
|
1747
|
+
cache.set(cacheKey2, { data: value, ts: Date.now() });
|
|
1748
|
+
if (nextRequestId === requestIdRef.current) {
|
|
1749
|
+
setData(value);
|
|
1750
|
+
setError(null);
|
|
1751
|
+
}
|
|
1752
|
+
} catch (loadError) {
|
|
1753
|
+
if (nextRequestId === requestIdRef.current) {
|
|
1754
|
+
setError(loadError);
|
|
1755
|
+
}
|
|
1756
|
+
} finally {
|
|
1757
|
+
if (nextRequestId === requestIdRef.current) {
|
|
1758
|
+
setIsLoading(false);
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
},
|
|
1762
|
+
[cacheKey2, client, enabled]
|
|
1763
|
+
);
|
|
1764
|
+
useEffect(() => {
|
|
1765
|
+
void load(false);
|
|
1766
|
+
}, [load]);
|
|
1767
|
+
const refetch = useCallback(async () => {
|
|
1768
|
+
cache.delete(cacheKey2);
|
|
1769
|
+
await load(true);
|
|
1770
|
+
}, [cacheKey2, load]);
|
|
1771
|
+
return { data, isLoading, error, refetch };
|
|
1772
|
+
}
|
|
1773
|
+
useCachedQuery.clear = () => {
|
|
1774
|
+
cache.clear();
|
|
1775
|
+
inflight.clear();
|
|
1776
|
+
};
|
|
1777
|
+
return useCachedQuery;
|
|
1778
|
+
}
|
|
1779
|
+
function cacheKey(...parts) {
|
|
1780
|
+
return parts.map((p) => String(p ?? "")).join("|");
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
// src/react/hooks/use-products.ts
|
|
1784
|
+
var productsQuery = createCachedQuery({
|
|
1785
|
+
name: "useProducts",
|
|
1786
|
+
locationSensitive: true,
|
|
1787
|
+
key: (client, options) => cacheKey(
|
|
1788
|
+
client.getPublicKey(),
|
|
1789
|
+
client.getLocationId(),
|
|
1790
|
+
options.category,
|
|
1791
|
+
options.taxonomy,
|
|
1792
|
+
options.search,
|
|
1793
|
+
options.featured,
|
|
1794
|
+
options.limit,
|
|
1795
|
+
options.sort_by,
|
|
1796
|
+
options.sort_order,
|
|
1797
|
+
options.tags?.join(","),
|
|
1798
|
+
options.in_stock,
|
|
1799
|
+
options.min_price,
|
|
1800
|
+
options.max_price,
|
|
1801
|
+
options.page,
|
|
1802
|
+
options.properties ? JSON.stringify(options.properties) : void 0
|
|
1803
|
+
),
|
|
1804
|
+
fetch: async (client, options) => {
|
|
1805
|
+
const result = await client.catalogue.getProducts({
|
|
1717
1806
|
category: options.category,
|
|
1718
1807
|
taxonomy: options.taxonomy,
|
|
1719
1808
|
search: options.search,
|
|
@@ -1727,301 +1816,71 @@ function useProducts(options = {}) {
|
|
|
1727
1816
|
max_price: options.max_price,
|
|
1728
1817
|
page: options.page,
|
|
1729
1818
|
properties: options.properties
|
|
1730
|
-
})
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
options.max_price,
|
|
1743
|
-
options.page,
|
|
1744
|
-
propertiesSignature
|
|
1745
|
-
]
|
|
1746
|
-
);
|
|
1747
|
-
const cacheKey = useMemo(
|
|
1748
|
-
() => buildProductsCacheKey(client, locationId, queryOptions),
|
|
1749
|
-
[client, locationId, queryOptions]
|
|
1750
|
-
);
|
|
1751
|
-
const cached = productsCache.get(cacheKey);
|
|
1752
|
-
const [products, setProducts] = useState(cached?.products ?? []);
|
|
1753
|
-
const [isComplete, setIsComplete] = useState(cached?.is_complete ?? true);
|
|
1754
|
-
const [totalAvailable, setTotalAvailable] = useState(cached?.total_available);
|
|
1755
|
-
const [pagination, setPagination] = useState(cached?.pagination);
|
|
1756
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
1757
|
-
const [error, setError] = useState(null);
|
|
1758
|
-
useEffect(() => {
|
|
1759
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
1760
|
-
productsCache.clear();
|
|
1761
|
-
productsInflight.clear();
|
|
1762
|
-
previousLocationIdRef.current = locationId;
|
|
1763
|
-
}
|
|
1764
|
-
}, [locationId]);
|
|
1765
|
-
const load = useCallback(
|
|
1766
|
-
async (force = false) => {
|
|
1767
|
-
if (!enabled) {
|
|
1768
|
-
setIsLoading(false);
|
|
1769
|
-
return;
|
|
1770
|
-
}
|
|
1771
|
-
const nextRequestId = ++requestIdRef.current;
|
|
1772
|
-
setError(null);
|
|
1773
|
-
if (!force) {
|
|
1774
|
-
const cacheEntry = productsCache.get(cacheKey);
|
|
1775
|
-
if (cacheEntry) {
|
|
1776
|
-
setProducts(cacheEntry.products);
|
|
1777
|
-
setIsComplete(cacheEntry.is_complete);
|
|
1778
|
-
setTotalAvailable(cacheEntry.total_available);
|
|
1779
|
-
setPagination(cacheEntry.pagination);
|
|
1780
|
-
setIsLoading(false);
|
|
1781
|
-
return;
|
|
1782
|
-
}
|
|
1783
|
-
}
|
|
1784
|
-
setIsLoading(true);
|
|
1785
|
-
try {
|
|
1786
|
-
const existing = productsInflight.get(cacheKey);
|
|
1787
|
-
const promise = existing ?? (async () => {
|
|
1788
|
-
const result = await client.catalogue.getProducts(queryOptions);
|
|
1789
|
-
if (!result.ok) {
|
|
1790
|
-
throw result.error;
|
|
1791
|
-
}
|
|
1792
|
-
return result.value;
|
|
1793
|
-
})();
|
|
1794
|
-
if (!existing) {
|
|
1795
|
-
productsInflight.set(
|
|
1796
|
-
cacheKey,
|
|
1797
|
-
promise.finally(() => {
|
|
1798
|
-
productsInflight.delete(cacheKey);
|
|
1799
|
-
})
|
|
1800
|
-
);
|
|
1801
|
-
}
|
|
1802
|
-
const value = await promise;
|
|
1803
|
-
productsCache.set(cacheKey, {
|
|
1804
|
-
products: value.items,
|
|
1805
|
-
is_complete: value.is_complete,
|
|
1806
|
-
total_available: value.total_available,
|
|
1807
|
-
pagination: value.pagination
|
|
1808
|
-
});
|
|
1809
|
-
if (nextRequestId === requestIdRef.current) {
|
|
1810
|
-
setProducts(value.items);
|
|
1811
|
-
setIsComplete(value.is_complete);
|
|
1812
|
-
setTotalAvailable(value.total_available);
|
|
1813
|
-
setPagination(value.pagination);
|
|
1814
|
-
setError(null);
|
|
1815
|
-
}
|
|
1816
|
-
} catch (loadError) {
|
|
1817
|
-
if (nextRequestId === requestIdRef.current) {
|
|
1818
|
-
setError(loadError);
|
|
1819
|
-
}
|
|
1820
|
-
} finally {
|
|
1821
|
-
if (nextRequestId === requestIdRef.current) {
|
|
1822
|
-
setIsLoading(false);
|
|
1823
|
-
}
|
|
1824
|
-
}
|
|
1825
|
-
},
|
|
1826
|
-
[cacheKey, client, enabled, queryOptions]
|
|
1827
|
-
);
|
|
1828
|
-
useEffect(() => {
|
|
1829
|
-
void load(false);
|
|
1830
|
-
}, [load]);
|
|
1831
|
-
const refetch = useCallback(async () => {
|
|
1832
|
-
productsCache.delete(cacheKey);
|
|
1833
|
-
await load(true);
|
|
1834
|
-
}, [cacheKey, load]);
|
|
1819
|
+
});
|
|
1820
|
+
if (!result.ok) throw result.error;
|
|
1821
|
+
return {
|
|
1822
|
+
products: result.value.items,
|
|
1823
|
+
is_complete: result.value.is_complete,
|
|
1824
|
+
total_available: result.value.total_available,
|
|
1825
|
+
pagination: result.value.pagination
|
|
1826
|
+
};
|
|
1827
|
+
}
|
|
1828
|
+
});
|
|
1829
|
+
function useProducts(options = {}) {
|
|
1830
|
+
const { data, isLoading, error, refetch } = productsQuery(options);
|
|
1835
1831
|
return {
|
|
1836
|
-
products,
|
|
1837
|
-
is_complete:
|
|
1838
|
-
total_available:
|
|
1839
|
-
pagination,
|
|
1832
|
+
products: data?.products ?? [],
|
|
1833
|
+
is_complete: data?.is_complete ?? true,
|
|
1834
|
+
total_available: data?.total_available,
|
|
1835
|
+
pagination: data?.pagination,
|
|
1840
1836
|
isLoading,
|
|
1841
1837
|
error,
|
|
1842
1838
|
refetch
|
|
1843
1839
|
};
|
|
1844
1840
|
}
|
|
1845
|
-
|
|
1846
|
-
|
|
1841
|
+
|
|
1842
|
+
// src/react/hooks/use-product.ts
|
|
1847
1843
|
function isLikelySlug(value) {
|
|
1848
1844
|
return /^[a-z0-9-]+$/.test(value);
|
|
1849
1845
|
}
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1846
|
+
var productQuery = createCachedQuery({
|
|
1847
|
+
name: "useProduct",
|
|
1848
|
+
locationSensitive: true,
|
|
1849
|
+
key: (client, options) => cacheKey(client.getPublicKey(), client.getLocationId(), options.slugOrId),
|
|
1850
|
+
fetch: async (client, options) => {
|
|
1851
|
+
const result = isLikelySlug(options.slugOrId) ? await client.catalogue.getProductBySlug(options.slugOrId) : await client.catalogue.getProduct(options.slugOrId);
|
|
1852
|
+
if (!result.ok) throw result.error;
|
|
1853
|
+
client.activity.trackProductView(result.value.id, {
|
|
1854
|
+
productName: result.value.name,
|
|
1855
|
+
categoryId: result.value.category_id,
|
|
1856
|
+
price: String(result.value.default_price)
|
|
1857
|
+
});
|
|
1858
|
+
return result.value;
|
|
1859
|
+
}
|
|
1860
|
+
});
|
|
1861
|
+
function useProduct(slugOrId, options = {}) {
|
|
1862
|
+
const normalized = (slugOrId || "").trim();
|
|
1863
|
+
const { data, isLoading, error, refetch } = productQuery({
|
|
1864
|
+
...options,
|
|
1865
|
+
slugOrId: normalized,
|
|
1866
|
+
enabled: (options.enabled ?? true) && normalized.length > 0
|
|
1855
1867
|
});
|
|
1868
|
+
return { product: data, isLoading, error, refetch };
|
|
1856
1869
|
}
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1870
|
+
|
|
1871
|
+
// src/react/hooks/use-categories.ts
|
|
1872
|
+
var categoriesQuery = createCachedQuery({
|
|
1873
|
+
name: "useCategories",
|
|
1874
|
+
key: (client) => client.getPublicKey() || "__demo__",
|
|
1875
|
+
fetch: async (client) => {
|
|
1876
|
+
const result = await client.catalogue.getCategories();
|
|
1877
|
+
if (!result.ok) throw result.error;
|
|
1878
|
+
return result.value;
|
|
1862
1879
|
}
|
|
1863
|
-
|
|
1864
|
-
const locationId = client.getLocationId();
|
|
1865
|
-
const previousLocationIdRef = useRef(locationId);
|
|
1866
|
-
const requestIdRef = useRef(0);
|
|
1867
|
-
const trackedProductRef = useRef(null);
|
|
1868
|
-
const normalizedSlugOrId = useMemo(() => (slugOrId || "").trim(), [slugOrId]);
|
|
1869
|
-
const cacheKey = useMemo(
|
|
1870
|
-
() => buildProductCacheKey(client, locationId, normalizedSlugOrId),
|
|
1871
|
-
[client, locationId, normalizedSlugOrId]
|
|
1872
|
-
);
|
|
1873
|
-
const cached = productCache.get(cacheKey);
|
|
1874
|
-
const [product, setProduct] = useState(cached?.product ?? null);
|
|
1875
|
-
const [isLoading, setIsLoading] = useState(
|
|
1876
|
-
enabled && normalizedSlugOrId.length > 0 && !cached
|
|
1877
|
-
);
|
|
1878
|
-
const [error, setError] = useState(null);
|
|
1879
|
-
useEffect(() => {
|
|
1880
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
1881
|
-
productCache.clear();
|
|
1882
|
-
productInflight.clear();
|
|
1883
|
-
previousLocationIdRef.current = locationId;
|
|
1884
|
-
}
|
|
1885
|
-
}, [locationId]);
|
|
1886
|
-
const load = useCallback(
|
|
1887
|
-
async (force = false) => {
|
|
1888
|
-
if (!enabled || normalizedSlugOrId.length === 0) {
|
|
1889
|
-
setProduct(null);
|
|
1890
|
-
setIsLoading(false);
|
|
1891
|
-
return;
|
|
1892
|
-
}
|
|
1893
|
-
const nextRequestId = ++requestIdRef.current;
|
|
1894
|
-
setError(null);
|
|
1895
|
-
if (!force) {
|
|
1896
|
-
const cacheEntry = productCache.get(cacheKey);
|
|
1897
|
-
if (cacheEntry) {
|
|
1898
|
-
setProduct(cacheEntry.product);
|
|
1899
|
-
setIsLoading(false);
|
|
1900
|
-
return;
|
|
1901
|
-
}
|
|
1902
|
-
}
|
|
1903
|
-
setIsLoading(true);
|
|
1904
|
-
try {
|
|
1905
|
-
const existing = productInflight.get(cacheKey);
|
|
1906
|
-
const promise = existing ?? (async () => {
|
|
1907
|
-
const result = isLikelySlug(normalizedSlugOrId) ? await client.catalogue.getProductBySlug(normalizedSlugOrId) : await client.catalogue.getProduct(normalizedSlugOrId);
|
|
1908
|
-
if (!result.ok) {
|
|
1909
|
-
throw result.error;
|
|
1910
|
-
}
|
|
1911
|
-
return result.value;
|
|
1912
|
-
})();
|
|
1913
|
-
if (!existing) {
|
|
1914
|
-
productInflight.set(
|
|
1915
|
-
cacheKey,
|
|
1916
|
-
promise.finally(() => {
|
|
1917
|
-
productInflight.delete(cacheKey);
|
|
1918
|
-
})
|
|
1919
|
-
);
|
|
1920
|
-
}
|
|
1921
|
-
const value = await promise;
|
|
1922
|
-
productCache.set(cacheKey, { product: value });
|
|
1923
|
-
if (nextRequestId === requestIdRef.current) {
|
|
1924
|
-
setProduct(value);
|
|
1925
|
-
setError(null);
|
|
1926
|
-
if (value && trackedProductRef.current !== value.id) {
|
|
1927
|
-
trackedProductRef.current = value.id;
|
|
1928
|
-
client.activity.trackProductView(value.id, {
|
|
1929
|
-
productName: value.name,
|
|
1930
|
-
categoryId: value.category_id,
|
|
1931
|
-
price: String(value.default_price)
|
|
1932
|
-
});
|
|
1933
|
-
}
|
|
1934
|
-
}
|
|
1935
|
-
} catch (loadError) {
|
|
1936
|
-
if (nextRequestId === requestIdRef.current) {
|
|
1937
|
-
setError(loadError);
|
|
1938
|
-
}
|
|
1939
|
-
} finally {
|
|
1940
|
-
if (nextRequestId === requestIdRef.current) {
|
|
1941
|
-
setIsLoading(false);
|
|
1942
|
-
}
|
|
1943
|
-
}
|
|
1944
|
-
},
|
|
1945
|
-
[cacheKey, client, enabled, normalizedSlugOrId]
|
|
1946
|
-
);
|
|
1947
|
-
useEffect(() => {
|
|
1948
|
-
void load(false);
|
|
1949
|
-
}, [load]);
|
|
1950
|
-
const refetch = useCallback(async () => {
|
|
1951
|
-
productCache.delete(cacheKey);
|
|
1952
|
-
await load(true);
|
|
1953
|
-
}, [cacheKey, load]);
|
|
1954
|
-
return { product, isLoading, error, refetch };
|
|
1955
|
-
}
|
|
1956
|
-
var categoriesCache = /* @__PURE__ */ new Map();
|
|
1957
|
-
var categoriesInflight = /* @__PURE__ */ new Map();
|
|
1958
|
-
function buildCategoriesCacheKey(client) {
|
|
1959
|
-
return client.getPublicKey() || "__demo__";
|
|
1960
|
-
}
|
|
1880
|
+
});
|
|
1961
1881
|
function useCategories(options = {}) {
|
|
1962
|
-
const
|
|
1963
|
-
|
|
1964
|
-
if (!client) {
|
|
1965
|
-
throw new Error("useCategories must be used within CimplifyProvider or passed { client }.");
|
|
1966
|
-
}
|
|
1967
|
-
const enabled = options.enabled ?? true;
|
|
1968
|
-
const cacheKey = useMemo(() => buildCategoriesCacheKey(client), [client]);
|
|
1969
|
-
const cached = categoriesCache.get(cacheKey);
|
|
1970
|
-
const [categories, setCategories] = useState(cached ?? []);
|
|
1971
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
1972
|
-
const [error, setError] = useState(null);
|
|
1973
|
-
const load = useCallback(
|
|
1974
|
-
async (force = false) => {
|
|
1975
|
-
if (!enabled) {
|
|
1976
|
-
setIsLoading(false);
|
|
1977
|
-
return;
|
|
1978
|
-
}
|
|
1979
|
-
setError(null);
|
|
1980
|
-
if (!force) {
|
|
1981
|
-
const cachedCategories = categoriesCache.get(cacheKey);
|
|
1982
|
-
if (cachedCategories) {
|
|
1983
|
-
setCategories(cachedCategories);
|
|
1984
|
-
setIsLoading(false);
|
|
1985
|
-
return;
|
|
1986
|
-
}
|
|
1987
|
-
}
|
|
1988
|
-
setIsLoading(true);
|
|
1989
|
-
try {
|
|
1990
|
-
const existing = categoriesInflight.get(cacheKey);
|
|
1991
|
-
const promise = existing ?? (async () => {
|
|
1992
|
-
const result = await client.catalogue.getCategories();
|
|
1993
|
-
if (!result.ok) {
|
|
1994
|
-
throw result.error;
|
|
1995
|
-
}
|
|
1996
|
-
return result.value;
|
|
1997
|
-
})();
|
|
1998
|
-
if (!existing) {
|
|
1999
|
-
categoriesInflight.set(
|
|
2000
|
-
cacheKey,
|
|
2001
|
-
promise.finally(() => {
|
|
2002
|
-
categoriesInflight.delete(cacheKey);
|
|
2003
|
-
})
|
|
2004
|
-
);
|
|
2005
|
-
}
|
|
2006
|
-
const value = await promise;
|
|
2007
|
-
categoriesCache.set(cacheKey, value);
|
|
2008
|
-
setCategories(value);
|
|
2009
|
-
} catch (loadError) {
|
|
2010
|
-
setError(loadError);
|
|
2011
|
-
} finally {
|
|
2012
|
-
setIsLoading(false);
|
|
2013
|
-
}
|
|
2014
|
-
},
|
|
2015
|
-
[cacheKey, client, enabled]
|
|
2016
|
-
);
|
|
2017
|
-
useEffect(() => {
|
|
2018
|
-
void load(false);
|
|
2019
|
-
}, [load]);
|
|
2020
|
-
const refetch = useCallback(async () => {
|
|
2021
|
-
categoriesCache.delete(cacheKey);
|
|
2022
|
-
await load(true);
|
|
2023
|
-
}, [cacheKey, load]);
|
|
2024
|
-
return { categories, isLoading, error, refetch };
|
|
1882
|
+
const { data, isLoading, error, refetch } = categoriesQuery(options);
|
|
1883
|
+
return { categories: data ?? [], isLoading, error, refetch };
|
|
2025
1884
|
}
|
|
2026
1885
|
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "cancelled", "refunded"]);
|
|
2027
1886
|
var orderCache = /* @__PURE__ */ new Map();
|
|
@@ -2043,11 +1902,11 @@ function useOrder(orderId, options = {}) {
|
|
|
2043
1902
|
const previousStatusRef = useRef(null);
|
|
2044
1903
|
const onStatusChangeRef = useRef(options.onStatusChange);
|
|
2045
1904
|
onStatusChangeRef.current = options.onStatusChange;
|
|
2046
|
-
const
|
|
1905
|
+
const cacheKey2 = useMemo(
|
|
2047
1906
|
() => buildOrderCacheKey(client, normalizedOrderId),
|
|
2048
1907
|
[client, normalizedOrderId]
|
|
2049
1908
|
);
|
|
2050
|
-
const cached = orderCache.get(
|
|
1909
|
+
const cached = orderCache.get(cacheKey2);
|
|
2051
1910
|
const [order, setOrder] = useState(cached?.order ?? null);
|
|
2052
1911
|
const [isLoading, setIsLoading] = useState(
|
|
2053
1912
|
enabled && normalizedOrderId.length > 0 && !cached
|
|
@@ -2063,7 +1922,7 @@ function useOrder(orderId, options = {}) {
|
|
|
2063
1922
|
const nextRequestId = ++requestIdRef.current;
|
|
2064
1923
|
setError(null);
|
|
2065
1924
|
if (!force) {
|
|
2066
|
-
const cacheEntry = orderCache.get(
|
|
1925
|
+
const cacheEntry = orderCache.get(cacheKey2);
|
|
2067
1926
|
if (cacheEntry) {
|
|
2068
1927
|
setOrder(cacheEntry.order);
|
|
2069
1928
|
setIsLoading(false);
|
|
@@ -2072,7 +1931,7 @@ function useOrder(orderId, options = {}) {
|
|
|
2072
1931
|
}
|
|
2073
1932
|
setIsLoading(true);
|
|
2074
1933
|
try {
|
|
2075
|
-
const existing = orderInflight.get(
|
|
1934
|
+
const existing = orderInflight.get(cacheKey2);
|
|
2076
1935
|
const promise = existing ?? (async () => {
|
|
2077
1936
|
const result = await client.orders.get(normalizedOrderId);
|
|
2078
1937
|
if (!result.ok) {
|
|
@@ -2082,14 +1941,14 @@ function useOrder(orderId, options = {}) {
|
|
|
2082
1941
|
})();
|
|
2083
1942
|
if (!existing) {
|
|
2084
1943
|
orderInflight.set(
|
|
2085
|
-
|
|
1944
|
+
cacheKey2,
|
|
2086
1945
|
promise.finally(() => {
|
|
2087
|
-
orderInflight.delete(
|
|
1946
|
+
orderInflight.delete(cacheKey2);
|
|
2088
1947
|
})
|
|
2089
1948
|
);
|
|
2090
1949
|
}
|
|
2091
1950
|
const value = await promise;
|
|
2092
|
-
orderCache.set(
|
|
1951
|
+
orderCache.set(cacheKey2, { order: value });
|
|
2093
1952
|
if (nextRequestId === requestIdRef.current) {
|
|
2094
1953
|
setOrder(value);
|
|
2095
1954
|
setError(null);
|
|
@@ -2110,7 +1969,7 @@ function useOrder(orderId, options = {}) {
|
|
|
2110
1969
|
}
|
|
2111
1970
|
}
|
|
2112
1971
|
},
|
|
2113
|
-
[
|
|
1972
|
+
[cacheKey2, client, enabled, normalizedOrderId]
|
|
2114
1973
|
);
|
|
2115
1974
|
useEffect(() => {
|
|
2116
1975
|
void load(false);
|
|
@@ -2128,9 +1987,9 @@ function useOrder(orderId, options = {}) {
|
|
|
2128
1987
|
};
|
|
2129
1988
|
}, [enabled, isTerminal, load, normalizedOrderId, poll, pollInterval]);
|
|
2130
1989
|
const refetch = useCallback(async () => {
|
|
2131
|
-
orderCache.delete(
|
|
1990
|
+
orderCache.delete(cacheKey2);
|
|
2132
1991
|
await load(true);
|
|
2133
|
-
}, [
|
|
1992
|
+
}, [cacheKey2, load]);
|
|
2134
1993
|
return { order, isLoading, error, refetch, isTerminal };
|
|
2135
1994
|
}
|
|
2136
1995
|
var LOCATION_STORAGE_KEY2 = "cimplify_location_id";
|
|
@@ -2233,216 +2092,64 @@ function useLocations(options = {}) {
|
|
|
2233
2092
|
isLoading
|
|
2234
2093
|
};
|
|
2235
2094
|
}
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2095
|
+
|
|
2096
|
+
// src/react/hooks/use-collections.ts
|
|
2097
|
+
var collectionsQuery = createCachedQuery({
|
|
2098
|
+
name: "useCollections",
|
|
2099
|
+
locationSensitive: true,
|
|
2100
|
+
key: (client) => cacheKey(client.getPublicKey(), client.getLocationId()),
|
|
2101
|
+
fetch: async (client) => {
|
|
2102
|
+
const result = await client.catalogue.getCollections();
|
|
2103
|
+
if (!result.ok) throw result.error;
|
|
2104
|
+
return result.value;
|
|
2105
|
+
}
|
|
2106
|
+
});
|
|
2107
|
+
function useCollections(options = {}) {
|
|
2108
|
+
const { data, isLoading, error, refetch } = collectionsQuery(options);
|
|
2109
|
+
return { collections: data ?? [], isLoading, error, refetch };
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
// src/react/hooks/use-collection.ts
|
|
2113
|
+
function isLikelySlug2(value) {
|
|
2114
|
+
return /^[a-z0-9-]+$/.test(value);
|
|
2115
|
+
}
|
|
2116
|
+
var collectionQuery = createCachedQuery({
|
|
2117
|
+
name: "useCollection",
|
|
2118
|
+
locationSensitive: true,
|
|
2119
|
+
key: (client, options) => cacheKey(client.getPublicKey(), client.getLocationId(), options.idOrSlug),
|
|
2120
|
+
fetch: async (client, options) => {
|
|
2121
|
+
const collectionResult = isLikelySlug2(options.idOrSlug) ? await client.catalogue.getCollectionBySlug(options.idOrSlug) : await client.catalogue.getCollection(options.idOrSlug);
|
|
2122
|
+
if (!collectionResult.ok) throw collectionResult.error;
|
|
2123
|
+
const productsResult = await client.catalogue.getCollectionProducts(
|
|
2124
|
+
collectionResult.value.id
|
|
2125
|
+
);
|
|
2126
|
+
if (!productsResult.ok) throw productsResult.error;
|
|
2127
|
+
return {
|
|
2128
|
+
collection: collectionResult.value,
|
|
2129
|
+
products: productsResult.value
|
|
2130
|
+
};
|
|
2131
|
+
}
|
|
2132
|
+
});
|
|
2133
|
+
function useCollection(idOrSlug, options = {}) {
|
|
2134
|
+
const normalized = (idOrSlug || "").trim();
|
|
2135
|
+
const { data, isLoading, error, refetch } = collectionQuery({
|
|
2136
|
+
...options,
|
|
2137
|
+
idOrSlug: normalized,
|
|
2138
|
+
enabled: (options.enabled ?? true) && normalized.length > 0
|
|
2242
2139
|
});
|
|
2140
|
+
return {
|
|
2141
|
+
collection: data?.collection ?? null,
|
|
2142
|
+
products: data?.products ?? [],
|
|
2143
|
+
isLoading,
|
|
2144
|
+
error,
|
|
2145
|
+
refetch
|
|
2146
|
+
};
|
|
2243
2147
|
}
|
|
2244
|
-
function
|
|
2148
|
+
function useSearch(options = {}) {
|
|
2245
2149
|
const context = useOptionalCimplifyClient();
|
|
2246
2150
|
const client = options.client ?? context?.client;
|
|
2247
2151
|
if (!client) {
|
|
2248
|
-
throw new Error("
|
|
2249
|
-
}
|
|
2250
|
-
const enabled = options.enabled ?? true;
|
|
2251
|
-
const locationId = client.getLocationId();
|
|
2252
|
-
const previousLocationIdRef = useRef(locationId);
|
|
2253
|
-
const requestIdRef = useRef(0);
|
|
2254
|
-
const cacheKey = useMemo(
|
|
2255
|
-
() => buildCollectionsCacheKey(client, locationId),
|
|
2256
|
-
[client, locationId]
|
|
2257
|
-
);
|
|
2258
|
-
const cached = collectionsCache.get(cacheKey);
|
|
2259
|
-
const [collections, setCollections] = useState(cached?.collections ?? []);
|
|
2260
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
2261
|
-
const [error, setError] = useState(null);
|
|
2262
|
-
useEffect(() => {
|
|
2263
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
2264
|
-
collectionsCache.clear();
|
|
2265
|
-
collectionsInflight.clear();
|
|
2266
|
-
previousLocationIdRef.current = locationId;
|
|
2267
|
-
}
|
|
2268
|
-
}, [locationId]);
|
|
2269
|
-
const load = useCallback(
|
|
2270
|
-
async (force = false) => {
|
|
2271
|
-
if (!enabled) {
|
|
2272
|
-
setIsLoading(false);
|
|
2273
|
-
return;
|
|
2274
|
-
}
|
|
2275
|
-
const nextRequestId = ++requestIdRef.current;
|
|
2276
|
-
setError(null);
|
|
2277
|
-
if (!force) {
|
|
2278
|
-
const cacheEntry = collectionsCache.get(cacheKey);
|
|
2279
|
-
if (cacheEntry) {
|
|
2280
|
-
setCollections(cacheEntry.collections);
|
|
2281
|
-
setIsLoading(false);
|
|
2282
|
-
return;
|
|
2283
|
-
}
|
|
2284
|
-
}
|
|
2285
|
-
setIsLoading(true);
|
|
2286
|
-
try {
|
|
2287
|
-
const existing = collectionsInflight.get(cacheKey);
|
|
2288
|
-
const promise = existing ?? (async () => {
|
|
2289
|
-
const result = await client.catalogue.getCollections();
|
|
2290
|
-
if (!result.ok) {
|
|
2291
|
-
throw result.error;
|
|
2292
|
-
}
|
|
2293
|
-
return result.value;
|
|
2294
|
-
})();
|
|
2295
|
-
if (!existing) {
|
|
2296
|
-
collectionsInflight.set(cacheKey, promise);
|
|
2297
|
-
promise.finally(() => {
|
|
2298
|
-
collectionsInflight.delete(cacheKey);
|
|
2299
|
-
}).catch(() => void 0);
|
|
2300
|
-
}
|
|
2301
|
-
const value = await promise;
|
|
2302
|
-
collectionsCache.set(cacheKey, { collections: value });
|
|
2303
|
-
if (nextRequestId === requestIdRef.current) {
|
|
2304
|
-
setCollections(value);
|
|
2305
|
-
setError(null);
|
|
2306
|
-
}
|
|
2307
|
-
} catch (loadError) {
|
|
2308
|
-
if (nextRequestId === requestIdRef.current) {
|
|
2309
|
-
setError(loadError);
|
|
2310
|
-
}
|
|
2311
|
-
} finally {
|
|
2312
|
-
if (nextRequestId === requestIdRef.current) {
|
|
2313
|
-
setIsLoading(false);
|
|
2314
|
-
}
|
|
2315
|
-
}
|
|
2316
|
-
},
|
|
2317
|
-
[cacheKey, client, enabled]
|
|
2318
|
-
);
|
|
2319
|
-
useEffect(() => {
|
|
2320
|
-
void load(false);
|
|
2321
|
-
}, [load]);
|
|
2322
|
-
const refetch = useCallback(async () => {
|
|
2323
|
-
collectionsCache.delete(cacheKey);
|
|
2324
|
-
await load(true);
|
|
2325
|
-
}, [cacheKey, load]);
|
|
2326
|
-
return { collections, isLoading, error, refetch };
|
|
2327
|
-
}
|
|
2328
|
-
var collectionCache = /* @__PURE__ */ new Map();
|
|
2329
|
-
var collectionInflight = /* @__PURE__ */ new Map();
|
|
2330
|
-
function isLikelySlug2(value) {
|
|
2331
|
-
return /^[a-z0-9-]+$/.test(value);
|
|
2332
|
-
}
|
|
2333
|
-
function buildCollectionCacheKey(client, locationId, idOrSlug) {
|
|
2334
|
-
return JSON.stringify({
|
|
2335
|
-
key: client.getPublicKey(),
|
|
2336
|
-
location_id: locationId || "__none__",
|
|
2337
|
-
collection: idOrSlug
|
|
2338
|
-
});
|
|
2339
|
-
}
|
|
2340
|
-
function useCollection(idOrSlug, options = {}) {
|
|
2341
|
-
const context = useOptionalCimplifyClient();
|
|
2342
|
-
const client = options.client ?? context?.client;
|
|
2343
|
-
if (!client) {
|
|
2344
|
-
throw new Error("useCollection must be used within CimplifyProvider or passed { client }.");
|
|
2345
|
-
}
|
|
2346
|
-
const enabled = options.enabled ?? true;
|
|
2347
|
-
const locationId = client.getLocationId();
|
|
2348
|
-
const previousLocationIdRef = useRef(locationId);
|
|
2349
|
-
const requestIdRef = useRef(0);
|
|
2350
|
-
const normalizedIdOrSlug = useMemo(() => (idOrSlug || "").trim(), [idOrSlug]);
|
|
2351
|
-
const cacheKey = useMemo(
|
|
2352
|
-
() => buildCollectionCacheKey(client, locationId, normalizedIdOrSlug),
|
|
2353
|
-
[client, locationId, normalizedIdOrSlug]
|
|
2354
|
-
);
|
|
2355
|
-
const cached = collectionCache.get(cacheKey);
|
|
2356
|
-
const [collection, setCollection] = useState(cached?.collection ?? null);
|
|
2357
|
-
const [products, setProducts] = useState(cached?.products ?? []);
|
|
2358
|
-
const [isLoading, setIsLoading] = useState(
|
|
2359
|
-
enabled && normalizedIdOrSlug.length > 0 && !cached
|
|
2360
|
-
);
|
|
2361
|
-
const [error, setError] = useState(null);
|
|
2362
|
-
useEffect(() => {
|
|
2363
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
2364
|
-
collectionCache.clear();
|
|
2365
|
-
collectionInflight.clear();
|
|
2366
|
-
previousLocationIdRef.current = locationId;
|
|
2367
|
-
}
|
|
2368
|
-
}, [locationId]);
|
|
2369
|
-
const load = useCallback(
|
|
2370
|
-
async (force = false) => {
|
|
2371
|
-
if (!enabled || normalizedIdOrSlug.length === 0) {
|
|
2372
|
-
setCollection(null);
|
|
2373
|
-
setProducts([]);
|
|
2374
|
-
setIsLoading(false);
|
|
2375
|
-
return;
|
|
2376
|
-
}
|
|
2377
|
-
const nextRequestId = ++requestIdRef.current;
|
|
2378
|
-
setError(null);
|
|
2379
|
-
if (!force) {
|
|
2380
|
-
const cacheEntry = collectionCache.get(cacheKey);
|
|
2381
|
-
if (cacheEntry) {
|
|
2382
|
-
setCollection(cacheEntry.collection);
|
|
2383
|
-
setProducts(cacheEntry.products);
|
|
2384
|
-
setIsLoading(false);
|
|
2385
|
-
return;
|
|
2386
|
-
}
|
|
2387
|
-
}
|
|
2388
|
-
setIsLoading(true);
|
|
2389
|
-
try {
|
|
2390
|
-
const existing = collectionInflight.get(cacheKey);
|
|
2391
|
-
const promise = existing ?? (async () => {
|
|
2392
|
-
const collectionResult = isLikelySlug2(normalizedIdOrSlug) ? await client.catalogue.getCollectionBySlug(normalizedIdOrSlug) : await client.catalogue.getCollection(normalizedIdOrSlug);
|
|
2393
|
-
if (!collectionResult.ok) {
|
|
2394
|
-
throw collectionResult.error;
|
|
2395
|
-
}
|
|
2396
|
-
const productsResult = await client.catalogue.getCollectionProducts(
|
|
2397
|
-
collectionResult.value.id
|
|
2398
|
-
);
|
|
2399
|
-
if (!productsResult.ok) {
|
|
2400
|
-
throw productsResult.error;
|
|
2401
|
-
}
|
|
2402
|
-
return {
|
|
2403
|
-
collection: collectionResult.value,
|
|
2404
|
-
products: productsResult.value
|
|
2405
|
-
};
|
|
2406
|
-
})();
|
|
2407
|
-
if (!existing) {
|
|
2408
|
-
collectionInflight.set(cacheKey, promise);
|
|
2409
|
-
promise.finally(() => {
|
|
2410
|
-
collectionInflight.delete(cacheKey);
|
|
2411
|
-
}).catch(() => void 0);
|
|
2412
|
-
}
|
|
2413
|
-
const value = await promise;
|
|
2414
|
-
collectionCache.set(cacheKey, value);
|
|
2415
|
-
if (nextRequestId === requestIdRef.current) {
|
|
2416
|
-
setCollection(value.collection);
|
|
2417
|
-
setProducts(value.products);
|
|
2418
|
-
setError(null);
|
|
2419
|
-
}
|
|
2420
|
-
} catch (loadError) {
|
|
2421
|
-
if (nextRequestId === requestIdRef.current) {
|
|
2422
|
-
setError(loadError);
|
|
2423
|
-
}
|
|
2424
|
-
} finally {
|
|
2425
|
-
if (nextRequestId === requestIdRef.current) {
|
|
2426
|
-
setIsLoading(false);
|
|
2427
|
-
}
|
|
2428
|
-
}
|
|
2429
|
-
},
|
|
2430
|
-
[cacheKey, client, enabled, normalizedIdOrSlug]
|
|
2431
|
-
);
|
|
2432
|
-
useEffect(() => {
|
|
2433
|
-
void load(false);
|
|
2434
|
-
}, [load]);
|
|
2435
|
-
const refetch = useCallback(async () => {
|
|
2436
|
-
collectionCache.delete(cacheKey);
|
|
2437
|
-
await load(true);
|
|
2438
|
-
}, [cacheKey, load]);
|
|
2439
|
-
return { collection, products, isLoading, error, refetch };
|
|
2440
|
-
}
|
|
2441
|
-
function useSearch(options = {}) {
|
|
2442
|
-
const context = useOptionalCimplifyClient();
|
|
2443
|
-
const client = options.client ?? context?.client;
|
|
2444
|
-
if (!client) {
|
|
2445
|
-
throw new Error("useSearch must be used within CimplifyProvider or passed { client }.");
|
|
2152
|
+
throw new Error("useSearch must be used within CimplifyProvider or passed { client }.");
|
|
2446
2153
|
}
|
|
2447
2154
|
const minLength = Math.max(0, options.minLength ?? 2);
|
|
2448
2155
|
const debounceMs = Math.max(0, options.debounceMs ?? 300);
|
|
@@ -2613,11 +2320,11 @@ function useQuote(input, options = {}) {
|
|
|
2613
2320
|
const normalized = normalizeInput(input, locationId);
|
|
2614
2321
|
return normalized.product_id.length > 0 ? normalized : null;
|
|
2615
2322
|
}, [inputSignature, locationId]);
|
|
2616
|
-
const
|
|
2323
|
+
const cacheKey2 = useMemo(
|
|
2617
2324
|
() => buildQuoteCacheKey(client, locationId, inputSignature),
|
|
2618
2325
|
[client, inputSignature, locationId]
|
|
2619
2326
|
);
|
|
2620
|
-
const cached = quoteCache.get(
|
|
2327
|
+
const cached = quoteCache.get(cacheKey2);
|
|
2621
2328
|
const [quote, setQuote] = useState(cached?.quote ?? null);
|
|
2622
2329
|
const [isLoading, setIsLoading] = useState(enabled && normalizedInput !== null && !cached);
|
|
2623
2330
|
const [error, setError] = useState(null);
|
|
@@ -2643,7 +2350,7 @@ function useQuote(input, options = {}) {
|
|
|
2643
2350
|
const nextRequestId = ++requestIdRef.current;
|
|
2644
2351
|
setError(null);
|
|
2645
2352
|
if (!force) {
|
|
2646
|
-
const cacheEntry = quoteCache.get(
|
|
2353
|
+
const cacheEntry = quoteCache.get(cacheKey2);
|
|
2647
2354
|
if (cacheEntry) {
|
|
2648
2355
|
setQuote(cacheEntry.quote);
|
|
2649
2356
|
setMessages(cacheEntry.quote?.ui_messages ?? []);
|
|
@@ -2656,7 +2363,7 @@ function useQuote(input, options = {}) {
|
|
|
2656
2363
|
setQuote(null);
|
|
2657
2364
|
setMessages([]);
|
|
2658
2365
|
try {
|
|
2659
|
-
const existing = quoteInflight.get(
|
|
2366
|
+
const existing = quoteInflight.get(cacheKey2);
|
|
2660
2367
|
const promise = existing ?? (async () => {
|
|
2661
2368
|
const result = await client.catalogue.fetchQuote(normalizedInput);
|
|
2662
2369
|
if (!result.ok) {
|
|
@@ -2665,13 +2372,13 @@ function useQuote(input, options = {}) {
|
|
|
2665
2372
|
return result.value;
|
|
2666
2373
|
})();
|
|
2667
2374
|
if (!existing) {
|
|
2668
|
-
quoteInflight.set(
|
|
2375
|
+
quoteInflight.set(cacheKey2, promise);
|
|
2669
2376
|
promise.finally(() => {
|
|
2670
|
-
quoteInflight.delete(
|
|
2377
|
+
quoteInflight.delete(cacheKey2);
|
|
2671
2378
|
}).catch(() => void 0);
|
|
2672
2379
|
}
|
|
2673
2380
|
const value = await promise;
|
|
2674
|
-
quoteCache.set(
|
|
2381
|
+
quoteCache.set(cacheKey2, { quote: value });
|
|
2675
2382
|
if (nextRequestId === requestIdRef.current) {
|
|
2676
2383
|
setQuote(value);
|
|
2677
2384
|
setMessages(value.ui_messages ?? []);
|
|
@@ -2688,13 +2395,13 @@ function useQuote(input, options = {}) {
|
|
|
2688
2395
|
}
|
|
2689
2396
|
}
|
|
2690
2397
|
},
|
|
2691
|
-
[
|
|
2398
|
+
[cacheKey2, client, enabled, normalizedInput]
|
|
2692
2399
|
);
|
|
2693
2400
|
useEffect(() => {
|
|
2694
2401
|
if (debounceTimerRef.current) {
|
|
2695
2402
|
clearTimeout(debounceTimerRef.current);
|
|
2696
2403
|
}
|
|
2697
|
-
const hasCached = quoteCache.has(
|
|
2404
|
+
const hasCached = quoteCache.has(cacheKey2);
|
|
2698
2405
|
if (hasCached || !enabled || !normalizedInput) {
|
|
2699
2406
|
void load(false);
|
|
2700
2407
|
} else {
|
|
@@ -2708,7 +2415,7 @@ function useQuote(input, options = {}) {
|
|
|
2708
2415
|
debounceTimerRef.current = null;
|
|
2709
2416
|
}
|
|
2710
2417
|
};
|
|
2711
|
-
}, [load,
|
|
2418
|
+
}, [load, cacheKey2, enabled, normalizedInput]);
|
|
2712
2419
|
const refresh = useCallback(async () => {
|
|
2713
2420
|
if (!enabled || !normalizedInput) {
|
|
2714
2421
|
return;
|
|
@@ -2729,7 +2436,7 @@ function useQuote(input, options = {}) {
|
|
|
2729
2436
|
throw result.error;
|
|
2730
2437
|
}
|
|
2731
2438
|
const refreshed = result.value.quote;
|
|
2732
|
-
quoteCache.set(
|
|
2439
|
+
quoteCache.set(cacheKey2, { quote: refreshed });
|
|
2733
2440
|
if (nextRequestId === requestIdRef.current) {
|
|
2734
2441
|
setQuote(refreshed);
|
|
2735
2442
|
setMessages(refreshed.ui_messages ?? []);
|
|
@@ -2745,7 +2452,7 @@ function useQuote(input, options = {}) {
|
|
|
2745
2452
|
setIsLoading(false);
|
|
2746
2453
|
}
|
|
2747
2454
|
}
|
|
2748
|
-
}, [
|
|
2455
|
+
}, [cacheKey2, client, enabled, load, normalizedInput, quote]);
|
|
2749
2456
|
useEffect(() => {
|
|
2750
2457
|
if (!Number.isFinite(quoteExpiryTimestamp)) {
|
|
2751
2458
|
setIsExpired(false);
|
|
@@ -2777,1402 +2484,391 @@ function useQuote(input, options = {}) {
|
|
|
2777
2484
|
}, [autoRefresh, enabled, quoteExpiryTimestamp, refresh, refreshBeforeExpiryMs]);
|
|
2778
2485
|
return { quote, isLoading, error, refresh, isExpired, messages };
|
|
2779
2486
|
}
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2487
|
+
|
|
2488
|
+
// src/react/hooks/use-taxonomies.ts
|
|
2489
|
+
var taxonomiesQuery = createCachedQuery({
|
|
2490
|
+
name: "useTaxonomies",
|
|
2491
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.parentId ?? "__root__"),
|
|
2492
|
+
fetch: async (client, options) => {
|
|
2493
|
+
const result = await client.catalogue.getTaxonomies(options.parentId);
|
|
2494
|
+
if (!result.ok) throw result.error;
|
|
2495
|
+
return result.value;
|
|
2496
|
+
}
|
|
2497
|
+
});
|
|
2788
2498
|
function useTaxonomies(options = {}) {
|
|
2499
|
+
const { data, isLoading, error, refetch } = taxonomiesQuery(options);
|
|
2500
|
+
return { taxonomies: data ?? [], isLoading, error, refetch };
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
// src/react/hooks/use-taxonomy.ts
|
|
2504
|
+
var taxonomyQuery = createCachedQuery({
|
|
2505
|
+
name: "useTaxonomy",
|
|
2506
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.id),
|
|
2507
|
+
fetch: async (client, options) => {
|
|
2508
|
+
const result = await client.catalogue.getTaxonomy(options.id);
|
|
2509
|
+
if (!result.ok) throw result.error;
|
|
2510
|
+
client.activity.trackCategoryView(result.value.id, {
|
|
2511
|
+
categoryName: result.value.name
|
|
2512
|
+
});
|
|
2513
|
+
return result.value;
|
|
2514
|
+
}
|
|
2515
|
+
});
|
|
2516
|
+
function useTaxonomy(id, options = {}) {
|
|
2517
|
+
const { data, isLoading, error, refetch } = taxonomyQuery({ ...options, id });
|
|
2518
|
+
return { taxonomy: data, isLoading, error, refetch };
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
// src/react/hooks/use-taxonomy-path.ts
|
|
2522
|
+
var taxonomyPathQuery = createCachedQuery({
|
|
2523
|
+
name: "useTaxonomyPath",
|
|
2524
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.id),
|
|
2525
|
+
fetch: async (client, options) => {
|
|
2526
|
+
const result = await client.catalogue.getTaxonomyPath(options.id);
|
|
2527
|
+
if (!result.ok) throw result.error;
|
|
2528
|
+
return result.value;
|
|
2529
|
+
}
|
|
2530
|
+
});
|
|
2531
|
+
function useTaxonomyPath(id, options = {}) {
|
|
2532
|
+
const { data, isLoading, error, refetch } = taxonomyPathQuery({ ...options, id });
|
|
2533
|
+
return { path: data ?? [], isLoading, error, refetch };
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
// src/react/hooks/use-product-schedules.ts
|
|
2537
|
+
var productSchedulesQuery = createCachedQuery({
|
|
2538
|
+
name: "useProductSchedules",
|
|
2539
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.productId),
|
|
2540
|
+
fetch: async (client, options) => {
|
|
2541
|
+
const result = await client.catalogue.getProductSchedules(options.productId);
|
|
2542
|
+
if (!result.ok) throw result.error;
|
|
2543
|
+
return result.value;
|
|
2544
|
+
}
|
|
2545
|
+
});
|
|
2546
|
+
function useProductSchedules(productId, options = {}) {
|
|
2547
|
+
const { data, isLoading, error, refetch } = productSchedulesQuery({ ...options, productId });
|
|
2548
|
+
return { schedules: data ?? [], isLoading, error, refetch };
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
// src/react/hooks/use-product-availability.ts
|
|
2552
|
+
var productAvailabilityQuery = createCachedQuery({
|
|
2553
|
+
name: "useProductAvailability",
|
|
2554
|
+
locationSensitive: true,
|
|
2555
|
+
key: (client, options) => {
|
|
2556
|
+
const locationId = options.locationId ?? client.getLocationId();
|
|
2557
|
+
return cacheKey(client.getPublicKey(), options.productId, locationId);
|
|
2558
|
+
},
|
|
2559
|
+
fetch: async (client, options) => {
|
|
2560
|
+
const locationId = options.locationId ?? client.getLocationId();
|
|
2561
|
+
if (!locationId) return null;
|
|
2562
|
+
const result = await client.catalogue.checkProductAvailableNow(options.productId, locationId);
|
|
2563
|
+
if (!result.ok) throw result.error;
|
|
2564
|
+
return result.value;
|
|
2565
|
+
}
|
|
2566
|
+
});
|
|
2567
|
+
function useProductAvailability(productId, options = {}) {
|
|
2568
|
+
const { data, isLoading, error, refetch } = productAvailabilityQuery({ ...options, productId });
|
|
2569
|
+
return {
|
|
2570
|
+
isAvailable: data?.is_available ?? null,
|
|
2571
|
+
schedulesToday: data?.schedules_today ?? [],
|
|
2572
|
+
isLoading,
|
|
2573
|
+
error,
|
|
2574
|
+
refetch
|
|
2575
|
+
};
|
|
2576
|
+
}
|
|
2577
|
+
|
|
2578
|
+
// src/react/hooks/use-deals.ts
|
|
2579
|
+
function resolveLocationId(client, options) {
|
|
2580
|
+
return options.locationId ?? client.getLocationId() ?? void 0;
|
|
2581
|
+
}
|
|
2582
|
+
var dealsQuery = createCachedQuery({
|
|
2583
|
+
name: "useDeals",
|
|
2584
|
+
locationSensitive: true,
|
|
2585
|
+
key: (client, options) => cacheKey(client.getPublicKey(), resolveLocationId(client, options)),
|
|
2586
|
+
fetch: async (client, options) => {
|
|
2587
|
+
const result = await client.catalogue.getDeals(resolveLocationId(client, options));
|
|
2588
|
+
if (!result.ok) throw result.error;
|
|
2589
|
+
return result.value;
|
|
2590
|
+
}
|
|
2591
|
+
});
|
|
2592
|
+
function useDeals(options = {}) {
|
|
2593
|
+
const { data, isLoading, error, refetch } = dealsQuery(options);
|
|
2594
|
+
return { deals: data ?? [], isLoading, error, refetch };
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2597
|
+
// src/react/hooks/use-products-on-sale.ts
|
|
2598
|
+
var productsOnSaleQuery = createCachedQuery({
|
|
2599
|
+
name: "useProductsOnSale",
|
|
2600
|
+
key: (client) => client.getPublicKey() || "__demo__",
|
|
2601
|
+
fetch: async (client) => {
|
|
2602
|
+
const result = await client.catalogue.getProductsOnSale();
|
|
2603
|
+
if (!result.ok) throw result.error;
|
|
2604
|
+
return result.value;
|
|
2605
|
+
}
|
|
2606
|
+
});
|
|
2607
|
+
function useProductsOnSale(options = {}) {
|
|
2608
|
+
const { data, isLoading, error, refetch } = productsOnSaleQuery(options);
|
|
2609
|
+
return { products: data ?? [], isLoading, error, refetch };
|
|
2610
|
+
}
|
|
2611
|
+
|
|
2612
|
+
// src/react/hooks/use-product-deals.ts
|
|
2613
|
+
var productDealsQuery = createCachedQuery({
|
|
2614
|
+
name: "useProductDeals",
|
|
2615
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.productId),
|
|
2616
|
+
fetch: async (client, options) => {
|
|
2617
|
+
const result = await client.catalogue.getProductDeals(options.productId);
|
|
2618
|
+
if (!result.ok) throw result.error;
|
|
2619
|
+
return result.value;
|
|
2620
|
+
}
|
|
2621
|
+
});
|
|
2622
|
+
function useProductDeals(productId, options = {}) {
|
|
2623
|
+
const { data, isLoading, error, refetch } = productDealsQuery({ ...options, productId });
|
|
2624
|
+
return { deals: data ?? [], isLoading, error, refetch };
|
|
2625
|
+
}
|
|
2626
|
+
function useValidateDiscount(options = {}) {
|
|
2789
2627
|
const context = useOptionalCimplifyClient();
|
|
2790
2628
|
const client = options.client ?? context?.client;
|
|
2791
2629
|
if (!client) {
|
|
2792
|
-
throw new Error("
|
|
2630
|
+
throw new Error("useValidateDiscount must be used within CimplifyProvider or passed { client }.");
|
|
2793
2631
|
}
|
|
2794
|
-
const
|
|
2795
|
-
const cacheKey = useMemo(
|
|
2796
|
-
() => buildTaxonomiesCacheKey(client, options.parentId),
|
|
2797
|
-
[client, options.parentId]
|
|
2798
|
-
);
|
|
2799
|
-
const cached = taxonomiesCache.get(cacheKey);
|
|
2800
|
-
const [taxonomies, setTaxonomies] = useState(cached ?? []);
|
|
2801
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
2632
|
+
const [isValidating, setIsValidating] = useState(false);
|
|
2802
2633
|
const [error, setError] = useState(null);
|
|
2803
|
-
const
|
|
2804
|
-
|
|
2805
|
-
async (force = false) => {
|
|
2806
|
-
if (!enabled) {
|
|
2807
|
-
setIsLoading(false);
|
|
2808
|
-
return;
|
|
2809
|
-
}
|
|
2634
|
+
const validate = useCallback(
|
|
2635
|
+
async (code, orderSubtotal, locationId) => {
|
|
2810
2636
|
setError(null);
|
|
2811
|
-
|
|
2812
|
-
const cachedTaxonomies = taxonomiesCache.get(cacheKey);
|
|
2813
|
-
if (cachedTaxonomies) {
|
|
2814
|
-
setTaxonomies(cachedTaxonomies);
|
|
2815
|
-
setIsLoading(false);
|
|
2816
|
-
return;
|
|
2817
|
-
}
|
|
2818
|
-
}
|
|
2819
|
-
setIsLoading(true);
|
|
2637
|
+
setIsValidating(true);
|
|
2820
2638
|
try {
|
|
2821
|
-
const
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
throw result.error;
|
|
2826
|
-
}
|
|
2827
|
-
return result.value;
|
|
2828
|
-
})();
|
|
2829
|
-
if (!existing) {
|
|
2830
|
-
taxonomiesInflight.set(
|
|
2831
|
-
cacheKey,
|
|
2832
|
-
promise.finally(() => {
|
|
2833
|
-
taxonomiesInflight.delete(cacheKey);
|
|
2834
|
-
})
|
|
2835
|
-
);
|
|
2639
|
+
const result = await client.catalogue.validateDiscountCode(code, orderSubtotal, locationId);
|
|
2640
|
+
if (!result.ok) {
|
|
2641
|
+
setError(result.error);
|
|
2642
|
+
return null;
|
|
2836
2643
|
}
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
setError(loadError);
|
|
2644
|
+
return result.value;
|
|
2645
|
+
} catch (validateError) {
|
|
2646
|
+
setError(validateError);
|
|
2647
|
+
return null;
|
|
2842
2648
|
} finally {
|
|
2843
|
-
|
|
2649
|
+
setIsValidating(false);
|
|
2844
2650
|
}
|
|
2845
2651
|
},
|
|
2846
|
-
[
|
|
2652
|
+
[client]
|
|
2847
2653
|
);
|
|
2848
|
-
|
|
2849
|
-
void load(false);
|
|
2850
|
-
}, [load]);
|
|
2851
|
-
const refetch = useCallback(async () => {
|
|
2852
|
-
taxonomiesCache.delete(cacheKey);
|
|
2853
|
-
await load(true);
|
|
2854
|
-
}, [cacheKey, load]);
|
|
2855
|
-
return { taxonomies, isLoading, error, refetch };
|
|
2856
|
-
}
|
|
2857
|
-
var taxonomyCache = /* @__PURE__ */ new Map();
|
|
2858
|
-
var taxonomyInflight = /* @__PURE__ */ new Map();
|
|
2859
|
-
function buildTaxonomyCacheKey(client, id) {
|
|
2860
|
-
return JSON.stringify({
|
|
2861
|
-
key: client.getPublicKey(),
|
|
2862
|
-
id
|
|
2863
|
-
});
|
|
2654
|
+
return { validate, isValidating, error };
|
|
2864
2655
|
}
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2656
|
+
|
|
2657
|
+
// src/react/hooks/use-bundles.ts
|
|
2658
|
+
var bundlesQuery = createCachedQuery({
|
|
2659
|
+
name: "useBundles",
|
|
2660
|
+
locationSensitive: true,
|
|
2661
|
+
key: (client) => cacheKey(client.getPublicKey(), client.getLocationId()),
|
|
2662
|
+
fetch: async (client) => {
|
|
2663
|
+
const result = await client.catalogue.getBundles();
|
|
2664
|
+
if (!result.ok) throw result.error;
|
|
2665
|
+
return result.value;
|
|
2870
2666
|
}
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
const
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
const
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
const existing = taxonomyInflight.get(cacheKey);
|
|
2896
|
-
const promise = existing ?? (async () => {
|
|
2897
|
-
const result = await client.catalogue.getTaxonomy(id);
|
|
2898
|
-
if (!result.ok) {
|
|
2899
|
-
throw result.error;
|
|
2900
|
-
}
|
|
2901
|
-
return result.value;
|
|
2902
|
-
})();
|
|
2903
|
-
if (!existing) {
|
|
2904
|
-
taxonomyInflight.set(
|
|
2905
|
-
cacheKey,
|
|
2906
|
-
promise.finally(() => {
|
|
2907
|
-
taxonomyInflight.delete(cacheKey);
|
|
2908
|
-
})
|
|
2909
|
-
);
|
|
2910
|
-
}
|
|
2911
|
-
const value = await promise;
|
|
2912
|
-
taxonomyCache.set(cacheKey, value);
|
|
2913
|
-
setTaxonomy(value);
|
|
2914
|
-
if (value && trackedTaxonomyRef.current !== value.id) {
|
|
2915
|
-
trackedTaxonomyRef.current = value.id;
|
|
2916
|
-
client.activity.trackCategoryView(value.id, {
|
|
2917
|
-
categoryName: value.name
|
|
2918
|
-
});
|
|
2919
|
-
}
|
|
2920
|
-
} catch (loadError) {
|
|
2921
|
-
setError(loadError);
|
|
2922
|
-
} finally {
|
|
2923
|
-
setIsLoading(false);
|
|
2924
|
-
}
|
|
2925
|
-
},
|
|
2926
|
-
[cacheKey, client, enabled, id]
|
|
2927
|
-
);
|
|
2928
|
-
useEffect(() => {
|
|
2929
|
-
void load(false);
|
|
2930
|
-
}, [load]);
|
|
2931
|
-
const refetch = useCallback(async () => {
|
|
2932
|
-
taxonomyCache.delete(cacheKey);
|
|
2933
|
-
await load(true);
|
|
2934
|
-
}, [cacheKey, load]);
|
|
2935
|
-
return { taxonomy, isLoading, error, refetch };
|
|
2936
|
-
}
|
|
2937
|
-
var taxonomyPathCache = /* @__PURE__ */ new Map();
|
|
2938
|
-
var taxonomyPathInflight = /* @__PURE__ */ new Map();
|
|
2939
|
-
function buildTaxonomyPathCacheKey(client, id) {
|
|
2940
|
-
return JSON.stringify({
|
|
2941
|
-
key: client.getPublicKey(),
|
|
2942
|
-
id
|
|
2943
|
-
});
|
|
2944
|
-
}
|
|
2945
|
-
function useTaxonomyPath(id, options = {}) {
|
|
2946
|
-
const context = useOptionalCimplifyClient();
|
|
2947
|
-
const client = options.client ?? context?.client;
|
|
2948
|
-
if (!client) {
|
|
2949
|
-
throw new Error("useTaxonomyPath must be used within CimplifyProvider or passed { client }.");
|
|
2950
|
-
}
|
|
2951
|
-
const enabled = options.enabled ?? true;
|
|
2952
|
-
const cacheKey = useMemo(() => buildTaxonomyPathCacheKey(client, id), [client, id]);
|
|
2953
|
-
const cached = taxonomyPathCache.get(cacheKey);
|
|
2954
|
-
const [path, setPath] = useState(cached ?? []);
|
|
2955
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
2956
|
-
const [error, setError] = useState(null);
|
|
2957
|
-
const load = useCallback(
|
|
2958
|
-
async (force = false) => {
|
|
2959
|
-
if (!enabled) {
|
|
2960
|
-
setIsLoading(false);
|
|
2961
|
-
return;
|
|
2962
|
-
}
|
|
2963
|
-
setError(null);
|
|
2964
|
-
if (!force) {
|
|
2965
|
-
const cachedPath = taxonomyPathCache.get(cacheKey);
|
|
2966
|
-
if (cachedPath) {
|
|
2967
|
-
setPath(cachedPath);
|
|
2968
|
-
setIsLoading(false);
|
|
2969
|
-
return;
|
|
2970
|
-
}
|
|
2971
|
-
}
|
|
2972
|
-
setIsLoading(true);
|
|
2973
|
-
try {
|
|
2974
|
-
const existing = taxonomyPathInflight.get(cacheKey);
|
|
2975
|
-
const promise = existing ?? (async () => {
|
|
2976
|
-
const result = await client.catalogue.getTaxonomyPath(id);
|
|
2977
|
-
if (!result.ok) {
|
|
2978
|
-
throw result.error;
|
|
2979
|
-
}
|
|
2980
|
-
return result.value;
|
|
2981
|
-
})();
|
|
2982
|
-
if (!existing) {
|
|
2983
|
-
taxonomyPathInflight.set(
|
|
2984
|
-
cacheKey,
|
|
2985
|
-
promise.finally(() => {
|
|
2986
|
-
taxonomyPathInflight.delete(cacheKey);
|
|
2987
|
-
})
|
|
2988
|
-
);
|
|
2989
|
-
}
|
|
2990
|
-
const value = await promise;
|
|
2991
|
-
taxonomyPathCache.set(cacheKey, value);
|
|
2992
|
-
setPath(value);
|
|
2993
|
-
} catch (loadError) {
|
|
2994
|
-
setError(loadError);
|
|
2995
|
-
} finally {
|
|
2996
|
-
setIsLoading(false);
|
|
2997
|
-
}
|
|
2998
|
-
},
|
|
2999
|
-
[cacheKey, client, enabled, id]
|
|
3000
|
-
);
|
|
3001
|
-
useEffect(() => {
|
|
3002
|
-
void load(false);
|
|
3003
|
-
}, [load]);
|
|
3004
|
-
const refetch = useCallback(async () => {
|
|
3005
|
-
taxonomyPathCache.delete(cacheKey);
|
|
3006
|
-
await load(true);
|
|
3007
|
-
}, [cacheKey, load]);
|
|
3008
|
-
return { path, isLoading, error, refetch };
|
|
3009
|
-
}
|
|
3010
|
-
var schedulesCache = /* @__PURE__ */ new Map();
|
|
3011
|
-
var schedulesInflight = /* @__PURE__ */ new Map();
|
|
3012
|
-
function buildSchedulesCacheKey(client, productId) {
|
|
3013
|
-
return JSON.stringify({
|
|
3014
|
-
key: client.getPublicKey(),
|
|
3015
|
-
product_id: productId
|
|
3016
|
-
});
|
|
3017
|
-
}
|
|
3018
|
-
function useProductSchedules(productId, options = {}) {
|
|
3019
|
-
const context = useOptionalCimplifyClient();
|
|
3020
|
-
const client = options.client ?? context?.client;
|
|
3021
|
-
if (!client) {
|
|
3022
|
-
throw new Error("useProductSchedules must be used within CimplifyProvider or passed { client }.");
|
|
3023
|
-
}
|
|
3024
|
-
const enabled = options.enabled ?? true;
|
|
3025
|
-
const cacheKey = useMemo(() => buildSchedulesCacheKey(client, productId), [client, productId]);
|
|
3026
|
-
const cached = schedulesCache.get(cacheKey);
|
|
3027
|
-
const [schedules, setSchedules] = useState(cached ?? []);
|
|
3028
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3029
|
-
const [error, setError] = useState(null);
|
|
3030
|
-
const load = useCallback(
|
|
3031
|
-
async (force = false) => {
|
|
3032
|
-
if (!enabled) {
|
|
3033
|
-
setIsLoading(false);
|
|
3034
|
-
return;
|
|
3035
|
-
}
|
|
3036
|
-
setError(null);
|
|
3037
|
-
if (!force) {
|
|
3038
|
-
const cachedSchedules = schedulesCache.get(cacheKey);
|
|
3039
|
-
if (cachedSchedules) {
|
|
3040
|
-
setSchedules(cachedSchedules);
|
|
3041
|
-
setIsLoading(false);
|
|
3042
|
-
return;
|
|
3043
|
-
}
|
|
3044
|
-
}
|
|
3045
|
-
setIsLoading(true);
|
|
3046
|
-
try {
|
|
3047
|
-
const existing = schedulesInflight.get(cacheKey);
|
|
3048
|
-
const promise = existing ?? (async () => {
|
|
3049
|
-
const result = await client.catalogue.getProductSchedules(productId);
|
|
3050
|
-
if (!result.ok) {
|
|
3051
|
-
throw result.error;
|
|
3052
|
-
}
|
|
3053
|
-
return result.value;
|
|
3054
|
-
})();
|
|
3055
|
-
if (!existing) {
|
|
3056
|
-
schedulesInflight.set(
|
|
3057
|
-
cacheKey,
|
|
3058
|
-
promise.finally(() => {
|
|
3059
|
-
schedulesInflight.delete(cacheKey);
|
|
3060
|
-
})
|
|
3061
|
-
);
|
|
3062
|
-
}
|
|
3063
|
-
const value = await promise;
|
|
3064
|
-
schedulesCache.set(cacheKey, value);
|
|
3065
|
-
setSchedules(value);
|
|
3066
|
-
} catch (loadError) {
|
|
3067
|
-
setError(loadError);
|
|
3068
|
-
} finally {
|
|
3069
|
-
setIsLoading(false);
|
|
3070
|
-
}
|
|
3071
|
-
},
|
|
3072
|
-
[cacheKey, client, enabled, productId]
|
|
3073
|
-
);
|
|
3074
|
-
useEffect(() => {
|
|
3075
|
-
void load(false);
|
|
3076
|
-
}, [load]);
|
|
3077
|
-
const refetch = useCallback(async () => {
|
|
3078
|
-
schedulesCache.delete(cacheKey);
|
|
3079
|
-
await load(true);
|
|
3080
|
-
}, [cacheKey, load]);
|
|
3081
|
-
return { schedules, isLoading, error, refetch };
|
|
3082
|
-
}
|
|
3083
|
-
var availabilityCache = /* @__PURE__ */ new Map();
|
|
3084
|
-
var availabilityInflight = /* @__PURE__ */ new Map();
|
|
3085
|
-
function buildAvailabilityCacheKey(client, productId, locationId) {
|
|
3086
|
-
return JSON.stringify({
|
|
3087
|
-
key: client.getPublicKey(),
|
|
3088
|
-
product_id: productId,
|
|
3089
|
-
location_id: locationId
|
|
3090
|
-
});
|
|
3091
|
-
}
|
|
3092
|
-
function useProductAvailability(productId, options = {}) {
|
|
3093
|
-
const context = useOptionalCimplifyClient();
|
|
3094
|
-
const client = options.client ?? context?.client;
|
|
3095
|
-
if (!client) {
|
|
3096
|
-
throw new Error("useProductAvailability must be used within CimplifyProvider or passed { client }.");
|
|
3097
|
-
}
|
|
3098
|
-
const enabled = options.enabled ?? true;
|
|
3099
|
-
const locationId = options.locationId ?? client.getLocationId();
|
|
3100
|
-
const previousLocationIdRef = useRef(locationId);
|
|
3101
|
-
const cacheKey = useMemo(
|
|
3102
|
-
() => locationId ? buildAvailabilityCacheKey(client, productId, locationId) : null,
|
|
3103
|
-
[client, productId, locationId]
|
|
3104
|
-
);
|
|
3105
|
-
const cached = cacheKey ? availabilityCache.get(cacheKey) : void 0;
|
|
3106
|
-
const [isAvailable, setIsAvailable] = useState(cached?.is_available ?? null);
|
|
3107
|
-
const [schedulesToday, setSchedulesToday] = useState(
|
|
3108
|
-
cached?.schedules_today ?? []
|
|
3109
|
-
);
|
|
3110
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached && !!locationId);
|
|
3111
|
-
const [error, setError] = useState(null);
|
|
3112
|
-
useEffect(() => {
|
|
3113
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
3114
|
-
availabilityCache.clear();
|
|
3115
|
-
availabilityInflight.clear();
|
|
3116
|
-
previousLocationIdRef.current = locationId;
|
|
3117
|
-
}
|
|
3118
|
-
}, [locationId]);
|
|
3119
|
-
const load = useCallback(
|
|
3120
|
-
async (force = false) => {
|
|
3121
|
-
if (!enabled || !locationId || !cacheKey) {
|
|
3122
|
-
setIsLoading(false);
|
|
3123
|
-
return;
|
|
3124
|
-
}
|
|
3125
|
-
setError(null);
|
|
3126
|
-
if (!force) {
|
|
3127
|
-
const cachedAvailability = availabilityCache.get(cacheKey);
|
|
3128
|
-
if (cachedAvailability) {
|
|
3129
|
-
setIsAvailable(cachedAvailability.is_available);
|
|
3130
|
-
setSchedulesToday(cachedAvailability.schedules_today);
|
|
3131
|
-
setIsLoading(false);
|
|
3132
|
-
return;
|
|
3133
|
-
}
|
|
3134
|
-
}
|
|
3135
|
-
setIsLoading(true);
|
|
3136
|
-
try {
|
|
3137
|
-
const existing = availabilityInflight.get(cacheKey);
|
|
3138
|
-
const promise = existing ?? (async () => {
|
|
3139
|
-
const result = await client.catalogue.checkProductAvailableNow(productId, locationId);
|
|
3140
|
-
if (!result.ok) {
|
|
3141
|
-
throw result.error;
|
|
3142
|
-
}
|
|
3143
|
-
return result.value;
|
|
3144
|
-
})();
|
|
3145
|
-
if (!existing) {
|
|
3146
|
-
availabilityInflight.set(
|
|
3147
|
-
cacheKey,
|
|
3148
|
-
promise.finally(() => {
|
|
3149
|
-
availabilityInflight.delete(cacheKey);
|
|
3150
|
-
})
|
|
3151
|
-
);
|
|
3152
|
-
}
|
|
3153
|
-
const value = await promise;
|
|
3154
|
-
availabilityCache.set(cacheKey, value);
|
|
3155
|
-
setIsAvailable(value.is_available);
|
|
3156
|
-
setSchedulesToday(value.schedules_today);
|
|
3157
|
-
} catch (loadError) {
|
|
3158
|
-
setError(loadError);
|
|
3159
|
-
} finally {
|
|
3160
|
-
setIsLoading(false);
|
|
3161
|
-
}
|
|
3162
|
-
},
|
|
3163
|
-
[cacheKey, client, enabled, locationId, productId]
|
|
3164
|
-
);
|
|
3165
|
-
useEffect(() => {
|
|
3166
|
-
void load(false);
|
|
3167
|
-
}, [load]);
|
|
3168
|
-
const refetch = useCallback(async () => {
|
|
3169
|
-
if (cacheKey) {
|
|
3170
|
-
availabilityCache.delete(cacheKey);
|
|
3171
|
-
}
|
|
3172
|
-
await load(true);
|
|
3173
|
-
}, [cacheKey, load]);
|
|
3174
|
-
return { isAvailable, schedulesToday, isLoading, error, refetch };
|
|
3175
|
-
}
|
|
3176
|
-
var dealsCache = /* @__PURE__ */ new Map();
|
|
3177
|
-
var dealsInflight = /* @__PURE__ */ new Map();
|
|
3178
|
-
function buildDealsCacheKey(client, locationId) {
|
|
3179
|
-
return JSON.stringify({ key: client.getPublicKey(), location_id: locationId });
|
|
3180
|
-
}
|
|
3181
|
-
function useDeals(options = {}) {
|
|
3182
|
-
const context = useOptionalCimplifyClient();
|
|
3183
|
-
const client = options.client ?? context?.client;
|
|
3184
|
-
if (!client) {
|
|
3185
|
-
throw new Error("useDeals must be used within CimplifyProvider or passed { client }.");
|
|
3186
|
-
}
|
|
3187
|
-
const enabled = options.enabled ?? true;
|
|
3188
|
-
const locationId = options.locationId ?? client.getLocationId() ?? void 0;
|
|
3189
|
-
const previousLocationIdRef = useRef(locationId);
|
|
3190
|
-
const cacheKey = useMemo(() => buildDealsCacheKey(client, locationId), [client, locationId]);
|
|
3191
|
-
const cached = dealsCache.get(cacheKey);
|
|
3192
|
-
const [deals, setDeals] = useState(cached ?? []);
|
|
3193
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3194
|
-
const [error, setError] = useState(null);
|
|
3195
|
-
useEffect(() => {
|
|
3196
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
3197
|
-
dealsCache.clear();
|
|
3198
|
-
dealsInflight.clear();
|
|
3199
|
-
previousLocationIdRef.current = locationId;
|
|
3200
|
-
}
|
|
3201
|
-
}, [locationId]);
|
|
3202
|
-
const load = useCallback(
|
|
3203
|
-
async (force = false) => {
|
|
3204
|
-
if (!enabled) {
|
|
3205
|
-
setIsLoading(false);
|
|
3206
|
-
return;
|
|
3207
|
-
}
|
|
3208
|
-
setError(null);
|
|
3209
|
-
if (!force) {
|
|
3210
|
-
const cachedDeals = dealsCache.get(cacheKey);
|
|
3211
|
-
if (cachedDeals) {
|
|
3212
|
-
setDeals(cachedDeals);
|
|
3213
|
-
setIsLoading(false);
|
|
3214
|
-
return;
|
|
3215
|
-
}
|
|
3216
|
-
}
|
|
3217
|
-
setIsLoading(true);
|
|
3218
|
-
try {
|
|
3219
|
-
const existing = dealsInflight.get(cacheKey);
|
|
3220
|
-
const promise = existing ?? (async () => {
|
|
3221
|
-
const result = await client.catalogue.getDeals(locationId);
|
|
3222
|
-
if (!result.ok) {
|
|
3223
|
-
throw result.error;
|
|
3224
|
-
}
|
|
3225
|
-
return result.value;
|
|
3226
|
-
})();
|
|
3227
|
-
if (!existing) {
|
|
3228
|
-
dealsInflight.set(
|
|
3229
|
-
cacheKey,
|
|
3230
|
-
promise.finally(() => {
|
|
3231
|
-
dealsInflight.delete(cacheKey);
|
|
3232
|
-
})
|
|
3233
|
-
);
|
|
3234
|
-
}
|
|
3235
|
-
const value = await promise;
|
|
3236
|
-
dealsCache.set(cacheKey, value);
|
|
3237
|
-
setDeals(value);
|
|
3238
|
-
} catch (loadError) {
|
|
3239
|
-
setError(loadError);
|
|
3240
|
-
} finally {
|
|
3241
|
-
setIsLoading(false);
|
|
3242
|
-
}
|
|
3243
|
-
},
|
|
3244
|
-
[cacheKey, client, enabled, locationId]
|
|
3245
|
-
);
|
|
3246
|
-
useEffect(() => {
|
|
3247
|
-
void load(false);
|
|
3248
|
-
}, [load]);
|
|
3249
|
-
const refetch = useCallback(async () => {
|
|
3250
|
-
dealsCache.delete(cacheKey);
|
|
3251
|
-
await load(true);
|
|
3252
|
-
}, [cacheKey, load]);
|
|
3253
|
-
return { deals, isLoading, error, refetch };
|
|
3254
|
-
}
|
|
3255
|
-
var onSaleCache = /* @__PURE__ */ new Map();
|
|
3256
|
-
var onSaleInflight = /* @__PURE__ */ new Map();
|
|
3257
|
-
function buildOnSaleCacheKey(client) {
|
|
3258
|
-
return client.getPublicKey() || "__demo__";
|
|
3259
|
-
}
|
|
3260
|
-
function useProductsOnSale(options = {}) {
|
|
3261
|
-
const context = useOptionalCimplifyClient();
|
|
3262
|
-
const client = options.client ?? context?.client;
|
|
3263
|
-
if (!client) {
|
|
3264
|
-
throw new Error("useProductsOnSale must be used within CimplifyProvider or passed { client }.");
|
|
3265
|
-
}
|
|
3266
|
-
const enabled = options.enabled ?? true;
|
|
3267
|
-
const cacheKey = useMemo(() => buildOnSaleCacheKey(client), [client]);
|
|
3268
|
-
const cached = onSaleCache.get(cacheKey);
|
|
3269
|
-
const [products, setProducts] = useState(cached ?? []);
|
|
3270
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3271
|
-
const [error, setError] = useState(null);
|
|
3272
|
-
const load = useCallback(
|
|
3273
|
-
async (force = false) => {
|
|
3274
|
-
if (!enabled) {
|
|
3275
|
-
setIsLoading(false);
|
|
3276
|
-
return;
|
|
3277
|
-
}
|
|
3278
|
-
setError(null);
|
|
3279
|
-
if (!force) {
|
|
3280
|
-
const cachedProducts = onSaleCache.get(cacheKey);
|
|
3281
|
-
if (cachedProducts) {
|
|
3282
|
-
setProducts(cachedProducts);
|
|
3283
|
-
setIsLoading(false);
|
|
3284
|
-
return;
|
|
3285
|
-
}
|
|
3286
|
-
}
|
|
3287
|
-
setIsLoading(true);
|
|
3288
|
-
try {
|
|
3289
|
-
const existing = onSaleInflight.get(cacheKey);
|
|
3290
|
-
const promise = existing ?? (async () => {
|
|
3291
|
-
const result = await client.catalogue.getProductsOnSale();
|
|
3292
|
-
if (!result.ok) {
|
|
3293
|
-
throw result.error;
|
|
3294
|
-
}
|
|
3295
|
-
return result.value;
|
|
3296
|
-
})();
|
|
3297
|
-
if (!existing) {
|
|
3298
|
-
onSaleInflight.set(
|
|
3299
|
-
cacheKey,
|
|
3300
|
-
promise.finally(() => {
|
|
3301
|
-
onSaleInflight.delete(cacheKey);
|
|
3302
|
-
})
|
|
3303
|
-
);
|
|
3304
|
-
}
|
|
3305
|
-
const value = await promise;
|
|
3306
|
-
onSaleCache.set(cacheKey, value);
|
|
3307
|
-
setProducts(value);
|
|
3308
|
-
} catch (loadError) {
|
|
3309
|
-
setError(loadError);
|
|
3310
|
-
} finally {
|
|
3311
|
-
setIsLoading(false);
|
|
3312
|
-
}
|
|
3313
|
-
},
|
|
3314
|
-
[cacheKey, client, enabled]
|
|
3315
|
-
);
|
|
3316
|
-
useEffect(() => {
|
|
3317
|
-
void load(false);
|
|
3318
|
-
}, [load]);
|
|
3319
|
-
const refetch = useCallback(async () => {
|
|
3320
|
-
onSaleCache.delete(cacheKey);
|
|
3321
|
-
await load(true);
|
|
3322
|
-
}, [cacheKey, load]);
|
|
3323
|
-
return { products, isLoading, error, refetch };
|
|
3324
|
-
}
|
|
3325
|
-
var productDealsCache = /* @__PURE__ */ new Map();
|
|
3326
|
-
var productDealsInflight = /* @__PURE__ */ new Map();
|
|
3327
|
-
function buildProductDealsCacheKey(client, productId) {
|
|
3328
|
-
return JSON.stringify({ key: client.getPublicKey(), product_id: productId });
|
|
3329
|
-
}
|
|
3330
|
-
function useProductDeals(productId, options = {}) {
|
|
3331
|
-
const context = useOptionalCimplifyClient();
|
|
3332
|
-
const client = options.client ?? context?.client;
|
|
3333
|
-
if (!client) {
|
|
3334
|
-
throw new Error("useProductDeals must be used within CimplifyProvider or passed { client }.");
|
|
3335
|
-
}
|
|
3336
|
-
const enabled = options.enabled ?? true;
|
|
3337
|
-
const cacheKey = useMemo(
|
|
3338
|
-
() => buildProductDealsCacheKey(client, productId),
|
|
3339
|
-
[client, productId]
|
|
3340
|
-
);
|
|
3341
|
-
const cached = productDealsCache.get(cacheKey);
|
|
3342
|
-
const [deals, setDeals] = useState(cached ?? []);
|
|
3343
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3344
|
-
const [error, setError] = useState(null);
|
|
3345
|
-
const load = useCallback(
|
|
3346
|
-
async (force = false) => {
|
|
3347
|
-
if (!enabled) {
|
|
3348
|
-
setIsLoading(false);
|
|
3349
|
-
return;
|
|
3350
|
-
}
|
|
3351
|
-
setError(null);
|
|
3352
|
-
if (!force) {
|
|
3353
|
-
const cachedDeals = productDealsCache.get(cacheKey);
|
|
3354
|
-
if (cachedDeals) {
|
|
3355
|
-
setDeals(cachedDeals);
|
|
3356
|
-
setIsLoading(false);
|
|
3357
|
-
return;
|
|
3358
|
-
}
|
|
3359
|
-
}
|
|
3360
|
-
setIsLoading(true);
|
|
3361
|
-
try {
|
|
3362
|
-
const existing = productDealsInflight.get(cacheKey);
|
|
3363
|
-
const promise = existing ?? (async () => {
|
|
3364
|
-
const result = await client.catalogue.getProductDeals(productId);
|
|
3365
|
-
if (!result.ok) {
|
|
3366
|
-
throw result.error;
|
|
3367
|
-
}
|
|
3368
|
-
return result.value;
|
|
3369
|
-
})();
|
|
3370
|
-
if (!existing) {
|
|
3371
|
-
productDealsInflight.set(
|
|
3372
|
-
cacheKey,
|
|
3373
|
-
promise.finally(() => {
|
|
3374
|
-
productDealsInflight.delete(cacheKey);
|
|
3375
|
-
})
|
|
3376
|
-
);
|
|
3377
|
-
}
|
|
3378
|
-
const value = await promise;
|
|
3379
|
-
productDealsCache.set(cacheKey, value);
|
|
3380
|
-
setDeals(value);
|
|
3381
|
-
} catch (loadError) {
|
|
3382
|
-
setError(loadError);
|
|
3383
|
-
} finally {
|
|
3384
|
-
setIsLoading(false);
|
|
3385
|
-
}
|
|
3386
|
-
},
|
|
3387
|
-
[cacheKey, client, enabled, productId]
|
|
3388
|
-
);
|
|
3389
|
-
useEffect(() => {
|
|
3390
|
-
void load(false);
|
|
3391
|
-
}, [load]);
|
|
3392
|
-
const refetch = useCallback(async () => {
|
|
3393
|
-
productDealsCache.delete(cacheKey);
|
|
3394
|
-
await load(true);
|
|
3395
|
-
}, [cacheKey, load]);
|
|
3396
|
-
return { deals, isLoading, error, refetch };
|
|
3397
|
-
}
|
|
3398
|
-
function useValidateDiscount(options = {}) {
|
|
3399
|
-
const context = useOptionalCimplifyClient();
|
|
3400
|
-
const client = options.client ?? context?.client;
|
|
3401
|
-
if (!client) {
|
|
3402
|
-
throw new Error("useValidateDiscount must be used within CimplifyProvider or passed { client }.");
|
|
3403
|
-
}
|
|
3404
|
-
const [isValidating, setIsValidating] = useState(false);
|
|
3405
|
-
const [error, setError] = useState(null);
|
|
3406
|
-
const validate = useCallback(
|
|
3407
|
-
async (code, orderSubtotal, locationId) => {
|
|
3408
|
-
setError(null);
|
|
3409
|
-
setIsValidating(true);
|
|
3410
|
-
try {
|
|
3411
|
-
const result = await client.catalogue.validateDiscountCode(code, orderSubtotal, locationId);
|
|
3412
|
-
if (!result.ok) {
|
|
3413
|
-
setError(result.error);
|
|
3414
|
-
return null;
|
|
3415
|
-
}
|
|
3416
|
-
return result.value;
|
|
3417
|
-
} catch (validateError) {
|
|
3418
|
-
setError(validateError);
|
|
3419
|
-
return null;
|
|
3420
|
-
} finally {
|
|
3421
|
-
setIsValidating(false);
|
|
3422
|
-
}
|
|
3423
|
-
},
|
|
3424
|
-
[client]
|
|
3425
|
-
);
|
|
3426
|
-
return { validate, isValidating, error };
|
|
3427
|
-
}
|
|
3428
|
-
var bundlesCache = /* @__PURE__ */ new Map();
|
|
3429
|
-
var bundlesInflight = /* @__PURE__ */ new Map();
|
|
3430
|
-
function buildBundlesCacheKey(client, locationId) {
|
|
3431
|
-
return JSON.stringify({
|
|
3432
|
-
key: client.getPublicKey(),
|
|
3433
|
-
location_id: locationId || "__none__"
|
|
3434
|
-
});
|
|
3435
|
-
}
|
|
3436
|
-
function useBundles(options = {}) {
|
|
3437
|
-
const context = useOptionalCimplifyClient();
|
|
3438
|
-
const client = options.client ?? context?.client;
|
|
3439
|
-
if (!client) {
|
|
3440
|
-
throw new Error("useBundles must be used within CimplifyProvider or passed { client }.");
|
|
3441
|
-
}
|
|
3442
|
-
const enabled = options.enabled ?? true;
|
|
3443
|
-
const locationId = client.getLocationId();
|
|
3444
|
-
const previousLocationIdRef = useRef(locationId);
|
|
3445
|
-
const requestIdRef = useRef(0);
|
|
3446
|
-
const cacheKey = useMemo(
|
|
3447
|
-
() => buildBundlesCacheKey(client, locationId),
|
|
3448
|
-
[client, locationId]
|
|
3449
|
-
);
|
|
3450
|
-
const cached = bundlesCache.get(cacheKey);
|
|
3451
|
-
const [bundles, setBundles] = useState(cached?.bundles ?? []);
|
|
3452
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3453
|
-
const [error, setError] = useState(null);
|
|
3454
|
-
useEffect(() => {
|
|
3455
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
3456
|
-
bundlesCache.clear();
|
|
3457
|
-
bundlesInflight.clear();
|
|
3458
|
-
previousLocationIdRef.current = locationId;
|
|
3459
|
-
}
|
|
3460
|
-
}, [locationId]);
|
|
3461
|
-
const load = useCallback(
|
|
3462
|
-
async (force = false) => {
|
|
3463
|
-
if (!enabled) {
|
|
3464
|
-
setIsLoading(false);
|
|
3465
|
-
return;
|
|
3466
|
-
}
|
|
3467
|
-
const nextRequestId = ++requestIdRef.current;
|
|
3468
|
-
setError(null);
|
|
3469
|
-
if (!force) {
|
|
3470
|
-
const cacheEntry = bundlesCache.get(cacheKey);
|
|
3471
|
-
if (cacheEntry) {
|
|
3472
|
-
setBundles(cacheEntry.bundles);
|
|
3473
|
-
setIsLoading(false);
|
|
3474
|
-
return;
|
|
3475
|
-
}
|
|
3476
|
-
}
|
|
3477
|
-
setIsLoading(true);
|
|
3478
|
-
try {
|
|
3479
|
-
const existing = bundlesInflight.get(cacheKey);
|
|
3480
|
-
const promise = existing ?? (async () => {
|
|
3481
|
-
const result = await client.catalogue.getBundles();
|
|
3482
|
-
if (!result.ok) {
|
|
3483
|
-
throw result.error;
|
|
3484
|
-
}
|
|
3485
|
-
return result.value;
|
|
3486
|
-
})();
|
|
3487
|
-
if (!existing) {
|
|
3488
|
-
bundlesInflight.set(cacheKey, promise);
|
|
3489
|
-
promise.finally(() => {
|
|
3490
|
-
bundlesInflight.delete(cacheKey);
|
|
3491
|
-
}).catch(() => void 0);
|
|
3492
|
-
}
|
|
3493
|
-
const value = await promise;
|
|
3494
|
-
bundlesCache.set(cacheKey, { bundles: value });
|
|
3495
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3496
|
-
setBundles(value);
|
|
3497
|
-
setError(null);
|
|
3498
|
-
}
|
|
3499
|
-
} catch (loadError) {
|
|
3500
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3501
|
-
setError(loadError);
|
|
3502
|
-
}
|
|
3503
|
-
} finally {
|
|
3504
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3505
|
-
setIsLoading(false);
|
|
3506
|
-
}
|
|
3507
|
-
}
|
|
3508
|
-
},
|
|
3509
|
-
[cacheKey, client, enabled]
|
|
3510
|
-
);
|
|
3511
|
-
useEffect(() => {
|
|
3512
|
-
void load(false);
|
|
3513
|
-
}, [load]);
|
|
3514
|
-
const refetch = useCallback(async () => {
|
|
3515
|
-
bundlesCache.delete(cacheKey);
|
|
3516
|
-
await load(true);
|
|
3517
|
-
}, [cacheKey, load]);
|
|
3518
|
-
return { bundles, isLoading, error, refetch };
|
|
3519
|
-
}
|
|
3520
|
-
function useProductPrice(input) {
|
|
3521
|
-
const {
|
|
3522
|
-
product,
|
|
3523
|
-
quantity = 1,
|
|
3524
|
-
variant,
|
|
3525
|
-
addOnOptions,
|
|
3526
|
-
compositePrice,
|
|
3527
|
-
bundleTotalPrice
|
|
3528
|
-
} = input;
|
|
3529
|
-
return useMemo(() => {
|
|
3530
|
-
let unitPrice;
|
|
3531
|
-
if (bundleTotalPrice != null) {
|
|
3532
|
-
unitPrice = bundleTotalPrice;
|
|
3533
|
-
} else if (compositePrice) {
|
|
3534
|
-
unitPrice = parsePrice(compositePrice.final_price);
|
|
3535
|
-
} else {
|
|
3536
|
-
unitPrice = parsePrice(product.default_price);
|
|
3537
|
-
if (variant?.price_adjustment) {
|
|
3538
|
-
unitPrice += parsePrice(variant.price_adjustment);
|
|
3539
|
-
}
|
|
3540
|
-
if (addOnOptions) {
|
|
3541
|
-
for (const option of addOnOptions) {
|
|
3542
|
-
if (option.default_price) {
|
|
3543
|
-
unitPrice += parsePrice(option.default_price);
|
|
3544
|
-
}
|
|
3545
|
-
}
|
|
3546
|
-
}
|
|
3547
|
-
}
|
|
3548
|
-
unitPrice = Math.round(unitPrice * 100) / 100;
|
|
3549
|
-
const totalPrice = Math.round(unitPrice * quantity * 100) / 100;
|
|
3550
|
-
return {
|
|
3551
|
-
unitPrice,
|
|
3552
|
-
totalPrice,
|
|
3553
|
-
displayTotalPrice: totalPrice
|
|
3554
|
-
};
|
|
3555
|
-
}, [product.default_price, quantity, variant?.price_adjustment, addOnOptions, compositePrice, bundleTotalPrice]);
|
|
3556
|
-
}
|
|
3557
|
-
var ordersCache = /* @__PURE__ */ new Map();
|
|
3558
|
-
var ordersInflight = /* @__PURE__ */ new Map();
|
|
3559
|
-
function buildOrdersCacheKey(client, status, limit) {
|
|
3560
|
-
return JSON.stringify({ key: client.getPublicKey(), status, limit });
|
|
3561
|
-
}
|
|
3562
|
-
function useOrders(options = {}) {
|
|
3563
|
-
const context = useOptionalCimplifyClient();
|
|
3564
|
-
const client = options.client ?? context?.client;
|
|
3565
|
-
if (!client) {
|
|
3566
|
-
throw new Error("useOrders must be used within CimplifyProvider or passed { client }.");
|
|
3567
|
-
}
|
|
3568
|
-
const enabled = options.enabled ?? true;
|
|
3569
|
-
const requestIdRef = useRef(0);
|
|
3570
|
-
const cacheKey = useMemo(
|
|
3571
|
-
() => buildOrdersCacheKey(client, options.status, options.limit),
|
|
3572
|
-
[client, options.status, options.limit]
|
|
3573
|
-
);
|
|
3574
|
-
const cached = ordersCache.get(cacheKey);
|
|
3575
|
-
const [orders, setOrders] = useState(cached ?? []);
|
|
3576
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3577
|
-
const [error, setError] = useState(null);
|
|
3578
|
-
const load = useCallback(
|
|
3579
|
-
async (force = false) => {
|
|
3580
|
-
if (!enabled) {
|
|
3581
|
-
setIsLoading(false);
|
|
3582
|
-
return;
|
|
3583
|
-
}
|
|
3584
|
-
const nextRequestId = ++requestIdRef.current;
|
|
3585
|
-
setError(null);
|
|
3586
|
-
if (!force) {
|
|
3587
|
-
const cachedOrders = ordersCache.get(cacheKey);
|
|
3588
|
-
if (cachedOrders) {
|
|
3589
|
-
setOrders(cachedOrders);
|
|
3590
|
-
setIsLoading(false);
|
|
3591
|
-
return;
|
|
3592
|
-
}
|
|
3593
|
-
}
|
|
3594
|
-
setIsLoading(true);
|
|
3595
|
-
try {
|
|
3596
|
-
const existing = ordersInflight.get(cacheKey);
|
|
3597
|
-
const promise = existing ?? (async () => {
|
|
3598
|
-
const result = await client.orders.list({
|
|
3599
|
-
status: options.status,
|
|
3600
|
-
limit: options.limit
|
|
3601
|
-
});
|
|
3602
|
-
if (!result.ok) {
|
|
3603
|
-
throw result.error;
|
|
3604
|
-
}
|
|
3605
|
-
return result.value;
|
|
3606
|
-
})();
|
|
3607
|
-
if (!existing) {
|
|
3608
|
-
ordersInflight.set(
|
|
3609
|
-
cacheKey,
|
|
3610
|
-
promise.finally(() => {
|
|
3611
|
-
ordersInflight.delete(cacheKey);
|
|
3612
|
-
})
|
|
3613
|
-
);
|
|
3614
|
-
}
|
|
3615
|
-
const value = await promise;
|
|
3616
|
-
ordersCache.set(cacheKey, value);
|
|
3617
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3618
|
-
setOrders(value);
|
|
3619
|
-
setError(null);
|
|
3620
|
-
}
|
|
3621
|
-
} catch (loadError) {
|
|
3622
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3623
|
-
setError(loadError);
|
|
3624
|
-
}
|
|
3625
|
-
} finally {
|
|
3626
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3627
|
-
setIsLoading(false);
|
|
3628
|
-
}
|
|
3629
|
-
}
|
|
3630
|
-
},
|
|
3631
|
-
[cacheKey, client, enabled, options.status, options.limit]
|
|
3632
|
-
);
|
|
3633
|
-
useEffect(() => {
|
|
3634
|
-
void load(false);
|
|
3635
|
-
}, [load]);
|
|
3636
|
-
const refetch = useCallback(async () => {
|
|
3637
|
-
ordersCache.delete(cacheKey);
|
|
3638
|
-
await load(true);
|
|
3639
|
-
}, [cacheKey, load]);
|
|
3640
|
-
return { orders, isLoading, error, refetch };
|
|
3641
|
-
}
|
|
3642
|
-
var servicesCache = /* @__PURE__ */ new Map();
|
|
3643
|
-
var servicesInflight = /* @__PURE__ */ new Map();
|
|
3644
|
-
function buildServicesCacheKey(client) {
|
|
3645
|
-
return JSON.stringify({ key: client.getPublicKey() });
|
|
3646
|
-
}
|
|
3647
|
-
function useServices(options = {}) {
|
|
3648
|
-
const context = useOptionalCimplifyClient();
|
|
3649
|
-
const client = options.client ?? context?.client;
|
|
3650
|
-
if (!client) {
|
|
3651
|
-
throw new Error("useServices must be used within CimplifyProvider or passed { client }.");
|
|
3652
|
-
}
|
|
3653
|
-
const enabled = options.enabled ?? true;
|
|
3654
|
-
const requestIdRef = useRef(0);
|
|
3655
|
-
const cacheKey = useMemo(() => buildServicesCacheKey(client), [client]);
|
|
3656
|
-
const cached = servicesCache.get(cacheKey);
|
|
3657
|
-
const [services, setServices] = useState(cached ?? []);
|
|
3658
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3659
|
-
const [error, setError] = useState(null);
|
|
3660
|
-
const load = useCallback(
|
|
3661
|
-
async (force = false) => {
|
|
3662
|
-
if (!enabled) {
|
|
3663
|
-
setIsLoading(false);
|
|
3664
|
-
return;
|
|
3665
|
-
}
|
|
3666
|
-
const nextRequestId = ++requestIdRef.current;
|
|
3667
|
-
setError(null);
|
|
3668
|
-
if (!force) {
|
|
3669
|
-
const cachedServices = servicesCache.get(cacheKey);
|
|
3670
|
-
if (cachedServices) {
|
|
3671
|
-
setServices(cachedServices);
|
|
3672
|
-
setIsLoading(false);
|
|
3673
|
-
return;
|
|
3674
|
-
}
|
|
3675
|
-
}
|
|
3676
|
-
setIsLoading(true);
|
|
3677
|
-
try {
|
|
3678
|
-
const existing = servicesInflight.get(cacheKey);
|
|
3679
|
-
const promise = existing ?? (async () => {
|
|
3680
|
-
const result = await client.scheduling.getServices();
|
|
3681
|
-
if (!result.ok) {
|
|
3682
|
-
throw result.error;
|
|
3683
|
-
}
|
|
3684
|
-
return result.value;
|
|
3685
|
-
})();
|
|
3686
|
-
if (!existing) {
|
|
3687
|
-
servicesInflight.set(
|
|
3688
|
-
cacheKey,
|
|
3689
|
-
promise.finally(() => {
|
|
3690
|
-
servicesInflight.delete(cacheKey);
|
|
3691
|
-
})
|
|
3692
|
-
);
|
|
3693
|
-
}
|
|
3694
|
-
const value = await promise;
|
|
3695
|
-
servicesCache.set(cacheKey, value);
|
|
3696
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3697
|
-
setServices(value);
|
|
3698
|
-
setError(null);
|
|
3699
|
-
}
|
|
3700
|
-
} catch (loadError) {
|
|
3701
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3702
|
-
setError(loadError);
|
|
3703
|
-
}
|
|
3704
|
-
} finally {
|
|
3705
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3706
|
-
setIsLoading(false);
|
|
3707
|
-
}
|
|
3708
|
-
}
|
|
3709
|
-
},
|
|
3710
|
-
[cacheKey, client, enabled]
|
|
3711
|
-
);
|
|
3712
|
-
useEffect(() => {
|
|
3713
|
-
void load(false);
|
|
3714
|
-
}, [load]);
|
|
3715
|
-
const refetch = useCallback(async () => {
|
|
3716
|
-
servicesCache.delete(cacheKey);
|
|
3717
|
-
await load(true);
|
|
3718
|
-
}, [cacheKey, load]);
|
|
3719
|
-
return { services, isLoading, error, refetch };
|
|
3720
|
-
}
|
|
3721
|
-
var slotsCache = /* @__PURE__ */ new Map();
|
|
3722
|
-
var slotsInflight = /* @__PURE__ */ new Map();
|
|
3723
|
-
function buildSlotsCacheKey(client, serviceId, date, participantCount) {
|
|
3724
|
-
return JSON.stringify({
|
|
3725
|
-
key: client.getPublicKey(),
|
|
3726
|
-
serviceId,
|
|
3727
|
-
date,
|
|
3728
|
-
participantCount
|
|
3729
|
-
});
|
|
3730
|
-
}
|
|
3731
|
-
function useAvailableSlots(serviceId, date, options = {}) {
|
|
3732
|
-
const context = useOptionalCimplifyClient();
|
|
3733
|
-
const client = options.client ?? context?.client;
|
|
3734
|
-
if (!client) {
|
|
3735
|
-
throw new Error("useAvailableSlots must be used within CimplifyProvider or passed { client }.");
|
|
3736
|
-
}
|
|
3737
|
-
const enabled = (options.enabled ?? true) && !!serviceId && !!date;
|
|
3738
|
-
const requestIdRef = useRef(0);
|
|
3739
|
-
const cacheKey = useMemo(
|
|
3740
|
-
() => serviceId && date ? buildSlotsCacheKey(client, serviceId, date, options.participantCount) : null,
|
|
3741
|
-
[client, serviceId, date, options.participantCount]
|
|
3742
|
-
);
|
|
3743
|
-
const cached = cacheKey ? slotsCache.get(cacheKey) : void 0;
|
|
3744
|
-
const [slots, setSlots] = useState(cached ?? []);
|
|
3745
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3746
|
-
const [error, setError] = useState(null);
|
|
3747
|
-
const load = useCallback(
|
|
3748
|
-
async (force = false) => {
|
|
3749
|
-
if (!enabled || !cacheKey || !serviceId || !date) {
|
|
3750
|
-
setIsLoading(false);
|
|
3751
|
-
return;
|
|
3752
|
-
}
|
|
3753
|
-
const nextRequestId = ++requestIdRef.current;
|
|
3754
|
-
setError(null);
|
|
3755
|
-
if (!force) {
|
|
3756
|
-
const cachedSlots = slotsCache.get(cacheKey);
|
|
3757
|
-
if (cachedSlots) {
|
|
3758
|
-
setSlots(cachedSlots);
|
|
3759
|
-
setIsLoading(false);
|
|
3760
|
-
return;
|
|
3761
|
-
}
|
|
3762
|
-
}
|
|
3763
|
-
setIsLoading(true);
|
|
3764
|
-
try {
|
|
3765
|
-
const existing = slotsInflight.get(cacheKey);
|
|
3766
|
-
const promise = existing ?? (async () => {
|
|
3767
|
-
const result = await client.scheduling.getAvailableSlots({
|
|
3768
|
-
service_id: serviceId,
|
|
3769
|
-
date,
|
|
3770
|
-
participant_count: options.participantCount
|
|
3771
|
-
});
|
|
3772
|
-
if (!result.ok) {
|
|
3773
|
-
throw result.error;
|
|
3774
|
-
}
|
|
3775
|
-
return result.value;
|
|
3776
|
-
})();
|
|
3777
|
-
if (!existing) {
|
|
3778
|
-
slotsInflight.set(
|
|
3779
|
-
cacheKey,
|
|
3780
|
-
promise.finally(() => {
|
|
3781
|
-
slotsInflight.delete(cacheKey);
|
|
3782
|
-
})
|
|
3783
|
-
);
|
|
3784
|
-
}
|
|
3785
|
-
const value = await promise;
|
|
3786
|
-
slotsCache.set(cacheKey, value);
|
|
3787
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3788
|
-
setSlots(value);
|
|
3789
|
-
setError(null);
|
|
3790
|
-
}
|
|
3791
|
-
} catch (loadError) {
|
|
3792
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3793
|
-
setError(loadError);
|
|
3794
|
-
}
|
|
3795
|
-
} finally {
|
|
3796
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3797
|
-
setIsLoading(false);
|
|
3798
|
-
}
|
|
3799
|
-
}
|
|
3800
|
-
},
|
|
3801
|
-
[cacheKey, client, enabled, serviceId, date, options.participantCount]
|
|
3802
|
-
);
|
|
3803
|
-
useEffect(() => {
|
|
3804
|
-
void load(false);
|
|
3805
|
-
}, [load]);
|
|
3806
|
-
const refetch = useCallback(async () => {
|
|
3807
|
-
if (cacheKey) {
|
|
3808
|
-
slotsCache.delete(cacheKey);
|
|
3809
|
-
}
|
|
3810
|
-
await load(true);
|
|
3811
|
-
}, [cacheKey, load]);
|
|
3812
|
-
return { slots, isLoading, error, refetch };
|
|
3813
|
-
}
|
|
3814
|
-
var availabilityCache2 = /* @__PURE__ */ new Map();
|
|
3815
|
-
var availabilityInflight2 = /* @__PURE__ */ new Map();
|
|
3816
|
-
function buildAvailabilityCacheKey2(client, serviceId, startDate, endDate, participantCount) {
|
|
3817
|
-
return JSON.stringify({
|
|
3818
|
-
key: client.getPublicKey(),
|
|
3819
|
-
serviceId,
|
|
3820
|
-
startDate,
|
|
3821
|
-
endDate,
|
|
3822
|
-
participantCount
|
|
3823
|
-
});
|
|
3824
|
-
}
|
|
3825
|
-
function useServiceAvailability(serviceId, startDate, endDate, options = {}) {
|
|
3826
|
-
const context = useOptionalCimplifyClient();
|
|
3827
|
-
const client = options.client ?? context?.client;
|
|
3828
|
-
if (!client) {
|
|
3829
|
-
throw new Error(
|
|
3830
|
-
"useServiceAvailability must be used within CimplifyProvider or passed { client }."
|
|
3831
|
-
);
|
|
3832
|
-
}
|
|
3833
|
-
const enabled = (options.enabled ?? true) && !!serviceId && !!startDate && !!endDate;
|
|
3834
|
-
const requestIdRef = useRef(0);
|
|
3835
|
-
const cacheKey = useMemo(
|
|
3836
|
-
() => serviceId && startDate && endDate ? buildAvailabilityCacheKey2(
|
|
3837
|
-
client,
|
|
3838
|
-
serviceId,
|
|
3839
|
-
startDate,
|
|
3840
|
-
endDate,
|
|
3841
|
-
options.participantCount
|
|
3842
|
-
) : null,
|
|
3843
|
-
[client, serviceId, startDate, endDate, options.participantCount]
|
|
3844
|
-
);
|
|
3845
|
-
const cached = cacheKey ? availabilityCache2.get(cacheKey) : void 0;
|
|
3846
|
-
const [days, setDays] = useState(cached ?? []);
|
|
3847
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3848
|
-
const [error, setError] = useState(null);
|
|
3849
|
-
const load = useCallback(
|
|
3850
|
-
async (force = false) => {
|
|
3851
|
-
if (!enabled || !cacheKey || !serviceId || !startDate || !endDate) {
|
|
3852
|
-
setIsLoading(false);
|
|
3853
|
-
return;
|
|
3854
|
-
}
|
|
3855
|
-
const nextRequestId = ++requestIdRef.current;
|
|
3856
|
-
setError(null);
|
|
3857
|
-
if (!force) {
|
|
3858
|
-
const cachedDays = availabilityCache2.get(cacheKey);
|
|
3859
|
-
if (cachedDays) {
|
|
3860
|
-
setDays(cachedDays);
|
|
3861
|
-
setIsLoading(false);
|
|
3862
|
-
return;
|
|
3863
|
-
}
|
|
2667
|
+
});
|
|
2668
|
+
function useBundles(options = {}) {
|
|
2669
|
+
const { data, isLoading, error, refetch } = bundlesQuery(options);
|
|
2670
|
+
return { bundles: data ?? [], isLoading, error, refetch };
|
|
2671
|
+
}
|
|
2672
|
+
function useProductPrice(input) {
|
|
2673
|
+
const {
|
|
2674
|
+
product,
|
|
2675
|
+
quantity = 1,
|
|
2676
|
+
variant,
|
|
2677
|
+
addOnOptions,
|
|
2678
|
+
compositePrice,
|
|
2679
|
+
bundleTotalPrice
|
|
2680
|
+
} = input;
|
|
2681
|
+
return useMemo(() => {
|
|
2682
|
+
let unitPrice;
|
|
2683
|
+
if (bundleTotalPrice != null) {
|
|
2684
|
+
unitPrice = bundleTotalPrice;
|
|
2685
|
+
} else if (compositePrice) {
|
|
2686
|
+
unitPrice = parsePrice(compositePrice.final_price);
|
|
2687
|
+
} else {
|
|
2688
|
+
unitPrice = parsePrice(product.default_price);
|
|
2689
|
+
if (variant?.price_adjustment) {
|
|
2690
|
+
unitPrice += parsePrice(variant.price_adjustment);
|
|
3864
2691
|
}
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
const result = await client.scheduling.getServiceAvailability({
|
|
3870
|
-
service_id: serviceId,
|
|
3871
|
-
start_date: startDate,
|
|
3872
|
-
end_date: endDate,
|
|
3873
|
-
location_id: options.locationId,
|
|
3874
|
-
participant_count: options.participantCount
|
|
3875
|
-
});
|
|
3876
|
-
if (!result.ok) {
|
|
3877
|
-
throw result.error;
|
|
2692
|
+
if (addOnOptions) {
|
|
2693
|
+
for (const option of addOnOptions) {
|
|
2694
|
+
if (option.default_price) {
|
|
2695
|
+
unitPrice += parsePrice(option.default_price);
|
|
3878
2696
|
}
|
|
3879
|
-
return result.value.availability;
|
|
3880
|
-
})();
|
|
3881
|
-
if (!existing) {
|
|
3882
|
-
availabilityInflight2.set(
|
|
3883
|
-
cacheKey,
|
|
3884
|
-
promise.finally(() => {
|
|
3885
|
-
availabilityInflight2.delete(cacheKey);
|
|
3886
|
-
})
|
|
3887
|
-
);
|
|
3888
|
-
}
|
|
3889
|
-
const value = await promise;
|
|
3890
|
-
availabilityCache2.set(cacheKey, value);
|
|
3891
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3892
|
-
setDays(value);
|
|
3893
|
-
setError(null);
|
|
3894
|
-
}
|
|
3895
|
-
} catch (loadError) {
|
|
3896
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3897
|
-
setError(loadError);
|
|
3898
|
-
}
|
|
3899
|
-
} finally {
|
|
3900
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3901
|
-
setIsLoading(false);
|
|
3902
2697
|
}
|
|
3903
2698
|
}
|
|
3904
|
-
},
|
|
3905
|
-
[cacheKey, client, enabled, serviceId, startDate, endDate, options.locationId, options.participantCount]
|
|
3906
|
-
);
|
|
3907
|
-
useEffect(() => {
|
|
3908
|
-
void load(false);
|
|
3909
|
-
}, [load]);
|
|
3910
|
-
const refetch = useCallback(async () => {
|
|
3911
|
-
if (cacheKey) {
|
|
3912
|
-
availabilityCache2.delete(cacheKey);
|
|
3913
2699
|
}
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
2700
|
+
unitPrice = Math.round(unitPrice * 100) / 100;
|
|
2701
|
+
const totalPrice = Math.round(unitPrice * quantity * 100) / 100;
|
|
2702
|
+
return {
|
|
2703
|
+
unitPrice,
|
|
2704
|
+
totalPrice,
|
|
2705
|
+
displayTotalPrice: totalPrice
|
|
2706
|
+
};
|
|
2707
|
+
}, [product.default_price, quantity, variant?.price_adjustment, addOnOptions, compositePrice, bundleTotalPrice]);
|
|
2708
|
+
}
|
|
2709
|
+
|
|
2710
|
+
// src/react/hooks/use-orders.ts
|
|
2711
|
+
var ordersQuery = createCachedQuery({
|
|
2712
|
+
name: "useOrders",
|
|
2713
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.status, options.limit),
|
|
2714
|
+
fetch: async (client, options) => {
|
|
2715
|
+
const result = await client.orders.list({
|
|
2716
|
+
status: options.status,
|
|
2717
|
+
limit: options.limit
|
|
2718
|
+
});
|
|
2719
|
+
if (!result.ok) throw result.error;
|
|
2720
|
+
return result.value;
|
|
2721
|
+
}
|
|
2722
|
+
});
|
|
2723
|
+
function useOrders(options = {}) {
|
|
2724
|
+
const { data, isLoading, error, refetch } = ordersQuery(options);
|
|
2725
|
+
return { orders: data ?? [], isLoading, error, refetch };
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
// src/react/hooks/use-services.ts
|
|
2729
|
+
var servicesQuery = createCachedQuery({
|
|
2730
|
+
name: "useServices",
|
|
2731
|
+
key: (client) => cacheKey(client.getPublicKey()),
|
|
2732
|
+
fetch: async (client) => {
|
|
2733
|
+
const result = await client.scheduling.getServices();
|
|
2734
|
+
if (!result.ok) throw result.error;
|
|
2735
|
+
return result.value;
|
|
2736
|
+
}
|
|
2737
|
+
});
|
|
2738
|
+
function useServices(options = {}) {
|
|
2739
|
+
const { data, isLoading, error, refetch } = servicesQuery(options);
|
|
2740
|
+
return { services: data ?? [], isLoading, error, refetch };
|
|
3917
2741
|
}
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
2742
|
+
|
|
2743
|
+
// src/react/hooks/use-available-slots.ts
|
|
2744
|
+
var slotsQuery = createCachedQuery({
|
|
2745
|
+
name: "useAvailableSlots",
|
|
2746
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.serviceId, options.date, options.participantCount),
|
|
2747
|
+
fetch: async (client, options) => {
|
|
2748
|
+
const result = await client.scheduling.getAvailableSlots({
|
|
2749
|
+
service_id: options.serviceId,
|
|
2750
|
+
date: options.date,
|
|
2751
|
+
participant_count: options.participantCount
|
|
2752
|
+
});
|
|
2753
|
+
if (!result.ok) throw result.error;
|
|
2754
|
+
return result.value;
|
|
2755
|
+
}
|
|
2756
|
+
});
|
|
2757
|
+
function useAvailableSlots(serviceId, date, options = {}) {
|
|
2758
|
+
const { data, isLoading, error, refetch } = slotsQuery({
|
|
2759
|
+
...options,
|
|
2760
|
+
serviceId: serviceId || "",
|
|
2761
|
+
date: date || "",
|
|
2762
|
+
enabled: (options.enabled ?? true) && !!serviceId && !!date
|
|
2763
|
+
});
|
|
2764
|
+
return { slots: data ?? [], isLoading, error, refetch };
|
|
3922
2765
|
}
|
|
2766
|
+
|
|
2767
|
+
// src/react/hooks/use-service-availability.ts
|
|
2768
|
+
var serviceAvailabilityQuery = createCachedQuery({
|
|
2769
|
+
name: "useServiceAvailability",
|
|
2770
|
+
key: (client, options) => cacheKey(
|
|
2771
|
+
client.getPublicKey(),
|
|
2772
|
+
options.serviceId,
|
|
2773
|
+
options.startDate,
|
|
2774
|
+
options.endDate,
|
|
2775
|
+
options.participantCount
|
|
2776
|
+
),
|
|
2777
|
+
fetch: async (client, options) => {
|
|
2778
|
+
const result = await client.scheduling.getServiceAvailability({
|
|
2779
|
+
service_id: options.serviceId,
|
|
2780
|
+
start_date: options.startDate,
|
|
2781
|
+
end_date: options.endDate,
|
|
2782
|
+
location_id: options.locationId,
|
|
2783
|
+
participant_count: options.participantCount
|
|
2784
|
+
});
|
|
2785
|
+
if (!result.ok) throw result.error;
|
|
2786
|
+
return result.value.availability;
|
|
2787
|
+
}
|
|
2788
|
+
});
|
|
2789
|
+
function useServiceAvailability(serviceId, startDate, endDate, options = {}) {
|
|
2790
|
+
const { data, isLoading, error, refetch } = serviceAvailabilityQuery({
|
|
2791
|
+
...options,
|
|
2792
|
+
serviceId: serviceId || "",
|
|
2793
|
+
startDate: startDate || "",
|
|
2794
|
+
endDate: endDate || "",
|
|
2795
|
+
enabled: (options.enabled ?? true) && !!serviceId && !!startDate && !!endDate
|
|
2796
|
+
});
|
|
2797
|
+
return { days: data ?? [], isLoading, error, refetch };
|
|
2798
|
+
}
|
|
2799
|
+
var bookingsQuery = createCachedQuery({
|
|
2800
|
+
name: "useBookings",
|
|
2801
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.filter ?? "all"),
|
|
2802
|
+
fetch: async (client, options) => {
|
|
2803
|
+
const filter = options.filter ?? "all";
|
|
2804
|
+
let result;
|
|
2805
|
+
switch (filter) {
|
|
2806
|
+
case "upcoming":
|
|
2807
|
+
result = await client.scheduling.getUpcomingBookings();
|
|
2808
|
+
break;
|
|
2809
|
+
case "past":
|
|
2810
|
+
result = await client.scheduling.getPastBookings();
|
|
2811
|
+
break;
|
|
2812
|
+
default:
|
|
2813
|
+
result = await client.scheduling.getCustomerBookings();
|
|
2814
|
+
break;
|
|
2815
|
+
}
|
|
2816
|
+
if (!result.ok) throw result.error;
|
|
2817
|
+
return result.value;
|
|
2818
|
+
}
|
|
2819
|
+
});
|
|
3923
2820
|
function useBookings(options = {}) {
|
|
3924
2821
|
const context = useOptionalCimplifyClient();
|
|
3925
2822
|
const client = options.client ?? context?.client;
|
|
3926
|
-
|
|
3927
|
-
throw new Error("useBookings must be used within CimplifyProvider or passed { client }.");
|
|
3928
|
-
}
|
|
3929
|
-
const filter = options.filter ?? "all";
|
|
3930
|
-
const enabled = options.enabled ?? true;
|
|
3931
|
-
const requestIdRef = useRef(0);
|
|
3932
|
-
const cacheKey = useMemo(
|
|
3933
|
-
() => buildBookingsCacheKey(client, filter),
|
|
3934
|
-
[client, filter]
|
|
3935
|
-
);
|
|
3936
|
-
const cached = bookingsCache.get(cacheKey);
|
|
3937
|
-
const [bookings, setBookings] = useState(cached ?? []);
|
|
3938
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
3939
|
-
const [error, setError] = useState(null);
|
|
3940
|
-
const load = useCallback(
|
|
3941
|
-
async (force = false) => {
|
|
3942
|
-
if (!enabled) {
|
|
3943
|
-
setIsLoading(false);
|
|
3944
|
-
return;
|
|
3945
|
-
}
|
|
3946
|
-
const nextRequestId = ++requestIdRef.current;
|
|
3947
|
-
setError(null);
|
|
3948
|
-
if (!force) {
|
|
3949
|
-
const cachedBookings = bookingsCache.get(cacheKey);
|
|
3950
|
-
if (cachedBookings) {
|
|
3951
|
-
setBookings(cachedBookings);
|
|
3952
|
-
setIsLoading(false);
|
|
3953
|
-
return;
|
|
3954
|
-
}
|
|
3955
|
-
}
|
|
3956
|
-
setIsLoading(true);
|
|
3957
|
-
try {
|
|
3958
|
-
const existing = bookingsInflight.get(cacheKey);
|
|
3959
|
-
const promise = existing ?? (async () => {
|
|
3960
|
-
let result;
|
|
3961
|
-
switch (filter) {
|
|
3962
|
-
case "upcoming":
|
|
3963
|
-
result = await client.scheduling.getUpcomingBookings();
|
|
3964
|
-
break;
|
|
3965
|
-
case "past":
|
|
3966
|
-
result = await client.scheduling.getPastBookings();
|
|
3967
|
-
break;
|
|
3968
|
-
default:
|
|
3969
|
-
result = await client.scheduling.getCustomerBookings();
|
|
3970
|
-
break;
|
|
3971
|
-
}
|
|
3972
|
-
if (!result.ok) {
|
|
3973
|
-
throw result.error;
|
|
3974
|
-
}
|
|
3975
|
-
return result.value;
|
|
3976
|
-
})();
|
|
3977
|
-
if (!existing) {
|
|
3978
|
-
bookingsInflight.set(
|
|
3979
|
-
cacheKey,
|
|
3980
|
-
promise.finally(() => {
|
|
3981
|
-
bookingsInflight.delete(cacheKey);
|
|
3982
|
-
})
|
|
3983
|
-
);
|
|
3984
|
-
}
|
|
3985
|
-
const value = await promise;
|
|
3986
|
-
bookingsCache.set(cacheKey, value);
|
|
3987
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3988
|
-
setBookings(value);
|
|
3989
|
-
setError(null);
|
|
3990
|
-
}
|
|
3991
|
-
} catch (loadError) {
|
|
3992
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3993
|
-
setError(loadError);
|
|
3994
|
-
}
|
|
3995
|
-
} finally {
|
|
3996
|
-
if (nextRequestId === requestIdRef.current) {
|
|
3997
|
-
setIsLoading(false);
|
|
3998
|
-
}
|
|
3999
|
-
}
|
|
4000
|
-
},
|
|
4001
|
-
[cacheKey, client, enabled, filter]
|
|
4002
|
-
);
|
|
4003
|
-
useEffect(() => {
|
|
4004
|
-
void load(false);
|
|
4005
|
-
}, [load]);
|
|
4006
|
-
const refetch = useCallback(async () => {
|
|
4007
|
-
bookingsCache.delete(cacheKey);
|
|
4008
|
-
await load(true);
|
|
4009
|
-
}, [cacheKey, load]);
|
|
2823
|
+
const { data, isLoading, error, refetch } = bookingsQuery(options);
|
|
4010
2824
|
const cancelBooking = useCallback(
|
|
4011
2825
|
async (bookingId, reason) => {
|
|
2826
|
+
if (!client) throw new Error("useBookings must be used within CimplifyProvider or passed { client }.");
|
|
4012
2827
|
const result = await client.scheduling.cancelBooking({
|
|
4013
2828
|
booking_id: bookingId,
|
|
4014
2829
|
reason
|
|
4015
2830
|
});
|
|
4016
|
-
if (!result.ok)
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
for (const key of bookingsCache.keys()) {
|
|
4020
|
-
bookingsCache.delete(key);
|
|
4021
|
-
}
|
|
4022
|
-
await load(true);
|
|
2831
|
+
if (!result.ok) throw result.error;
|
|
2832
|
+
bookingsQuery.clear();
|
|
2833
|
+
await refetch();
|
|
4023
2834
|
return result.value;
|
|
4024
2835
|
},
|
|
4025
|
-
[client,
|
|
2836
|
+
[client, refetch]
|
|
4026
2837
|
);
|
|
4027
|
-
return { bookings, isLoading, error, refetch, cancelBooking };
|
|
2838
|
+
return { bookings: data ?? [], isLoading, error, refetch, cancelBooking };
|
|
4028
2839
|
}
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
throw new Error(
|
|
4039
|
-
"useAttributeDefinitions must be used within CimplifyProvider or passed { client }."
|
|
4040
|
-
);
|
|
2840
|
+
|
|
2841
|
+
// src/react/hooks/use-attribute-definitions.ts
|
|
2842
|
+
var attributeDefinitionsQuery = createCachedQuery({
|
|
2843
|
+
name: "useAttributeDefinitions",
|
|
2844
|
+
key: (client, options) => cacheKey(client.getPublicKey() || "__demo__", options.namespace),
|
|
2845
|
+
fetch: async (client, options) => {
|
|
2846
|
+
const result = await client.catalogue.getAttributeDefinitions(options.namespace);
|
|
2847
|
+
if (!result.ok) throw result.error;
|
|
2848
|
+
return result.value;
|
|
4041
2849
|
}
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
const
|
|
4045
|
-
|
|
4046
|
-
const [definitions, setDefinitions] = useState(cached ?? []);
|
|
4047
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
4048
|
-
const [error, setError] = useState(null);
|
|
4049
|
-
const load = useCallback(
|
|
4050
|
-
async (force = false) => {
|
|
4051
|
-
if (!enabled) {
|
|
4052
|
-
setIsLoading(false);
|
|
4053
|
-
return;
|
|
4054
|
-
}
|
|
4055
|
-
setError(null);
|
|
4056
|
-
if (!force) {
|
|
4057
|
-
const cachedDefs = definitionsCache.get(cacheKey);
|
|
4058
|
-
if (cachedDefs) {
|
|
4059
|
-
setDefinitions(cachedDefs);
|
|
4060
|
-
setIsLoading(false);
|
|
4061
|
-
return;
|
|
4062
|
-
}
|
|
4063
|
-
}
|
|
4064
|
-
setIsLoading(true);
|
|
4065
|
-
try {
|
|
4066
|
-
const existing = definitionsInflight.get(cacheKey);
|
|
4067
|
-
const promise = existing ?? (async () => {
|
|
4068
|
-
const result = await client.catalogue.getAttributeDefinitions(namespace);
|
|
4069
|
-
if (!result.ok) {
|
|
4070
|
-
throw result.error;
|
|
4071
|
-
}
|
|
4072
|
-
return result.value;
|
|
4073
|
-
})();
|
|
4074
|
-
if (!existing) {
|
|
4075
|
-
definitionsInflight.set(
|
|
4076
|
-
cacheKey,
|
|
4077
|
-
promise.finally(() => {
|
|
4078
|
-
definitionsInflight.delete(cacheKey);
|
|
4079
|
-
})
|
|
4080
|
-
);
|
|
4081
|
-
}
|
|
4082
|
-
const value = await promise;
|
|
4083
|
-
definitionsCache.set(cacheKey, value);
|
|
4084
|
-
setDefinitions(value);
|
|
4085
|
-
} catch (loadError) {
|
|
4086
|
-
setError(loadError);
|
|
4087
|
-
} finally {
|
|
4088
|
-
setIsLoading(false);
|
|
4089
|
-
}
|
|
4090
|
-
},
|
|
4091
|
-
[cacheKey, client, enabled]
|
|
4092
|
-
);
|
|
4093
|
-
useEffect(() => {
|
|
4094
|
-
void load(false);
|
|
4095
|
-
}, [load]);
|
|
4096
|
-
const refetch = useCallback(async () => {
|
|
4097
|
-
definitionsCache.delete(cacheKey);
|
|
4098
|
-
await load(true);
|
|
4099
|
-
}, [cacheKey, load]);
|
|
4100
|
-
return { definitions, isLoading, error, refetch };
|
|
2850
|
+
});
|
|
2851
|
+
function useAttributeDefinitions(options = {}) {
|
|
2852
|
+
const { data, isLoading, error, refetch } = attributeDefinitionsQuery(options);
|
|
2853
|
+
return { definitions: data ?? [], isLoading, error, refetch };
|
|
4101
2854
|
}
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
2855
|
+
|
|
2856
|
+
// src/react/hooks/use-property-facets.ts
|
|
2857
|
+
var propertyFacetsQuery = createCachedQuery({
|
|
2858
|
+
name: "usePropertyFacets",
|
|
2859
|
+
key: (client, options) => cacheKey(client.getPublicKey() || "__demo__", options.category_id, options.product_type),
|
|
2860
|
+
fetch: async (client, options) => {
|
|
2861
|
+
const result = await client.catalogue.getPropertyFacets({
|
|
2862
|
+
category_id: options.category_id,
|
|
2863
|
+
product_type: options.product_type
|
|
2864
|
+
});
|
|
2865
|
+
if (!result.ok) throw result.error;
|
|
2866
|
+
return result.value;
|
|
4111
2867
|
}
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
);
|
|
4117
|
-
const cached = facetsCache.get(cacheKey);
|
|
4118
|
-
const [facets, setFacets] = useState(cached ?? []);
|
|
4119
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
4120
|
-
const [error, setError] = useState(null);
|
|
4121
|
-
const load = useCallback(
|
|
4122
|
-
async (force = false) => {
|
|
4123
|
-
if (!enabled) {
|
|
4124
|
-
setIsLoading(false);
|
|
4125
|
-
return;
|
|
4126
|
-
}
|
|
4127
|
-
setError(null);
|
|
4128
|
-
if (!force) {
|
|
4129
|
-
const cachedFacets = facetsCache.get(cacheKey);
|
|
4130
|
-
if (cachedFacets) {
|
|
4131
|
-
setFacets(cachedFacets);
|
|
4132
|
-
setIsLoading(false);
|
|
4133
|
-
return;
|
|
4134
|
-
}
|
|
4135
|
-
}
|
|
4136
|
-
setIsLoading(true);
|
|
4137
|
-
try {
|
|
4138
|
-
const existing = facetsInflight.get(cacheKey);
|
|
4139
|
-
const promise = existing ?? (async () => {
|
|
4140
|
-
const result = await client.catalogue.getPropertyFacets({
|
|
4141
|
-
category_id: options.category_id,
|
|
4142
|
-
product_type: options.product_type
|
|
4143
|
-
});
|
|
4144
|
-
if (!result.ok) {
|
|
4145
|
-
throw result.error;
|
|
4146
|
-
}
|
|
4147
|
-
return result.value;
|
|
4148
|
-
})();
|
|
4149
|
-
if (!existing) {
|
|
4150
|
-
facetsInflight.set(
|
|
4151
|
-
cacheKey,
|
|
4152
|
-
promise.finally(() => {
|
|
4153
|
-
facetsInflight.delete(cacheKey);
|
|
4154
|
-
})
|
|
4155
|
-
);
|
|
4156
|
-
}
|
|
4157
|
-
const value = await promise;
|
|
4158
|
-
facetsCache.set(cacheKey, value);
|
|
4159
|
-
setFacets(value);
|
|
4160
|
-
} catch (loadError) {
|
|
4161
|
-
setError(loadError);
|
|
4162
|
-
} finally {
|
|
4163
|
-
setIsLoading(false);
|
|
4164
|
-
}
|
|
4165
|
-
},
|
|
4166
|
-
[cacheKey, client, enabled, options.category_id, options.product_type]
|
|
4167
|
-
);
|
|
4168
|
-
useEffect(() => {
|
|
4169
|
-
void load(false);
|
|
4170
|
-
}, [load]);
|
|
4171
|
-
const refetch = useCallback(async () => {
|
|
4172
|
-
facetsCache.delete(cacheKey);
|
|
4173
|
-
await load(true);
|
|
4174
|
-
}, [cacheKey, load]);
|
|
4175
|
-
return { facets, isLoading, error, refetch };
|
|
2868
|
+
});
|
|
2869
|
+
function usePropertyFacets(options = {}) {
|
|
2870
|
+
const { data, isLoading, error, refetch } = propertyFacetsQuery(options);
|
|
2871
|
+
return { facets: data ?? [], isLoading, error, refetch };
|
|
4176
2872
|
}
|
|
4177
2873
|
function useBillingPlans(productId, options = {}) {
|
|
4178
2874
|
const context = useOptionalCimplifyClient();
|
|
@@ -4304,417 +3000,112 @@ function useVariantSelector(options) {
|
|
|
4304
3000
|
reset
|
|
4305
3001
|
};
|
|
4306
3002
|
}
|
|
4307
|
-
var
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
3003
|
+
var activityStateQuery = createCachedQuery({
|
|
3004
|
+
name: "useActivityState",
|
|
3005
|
+
key: (client) => cacheKey(client.getPublicKey()),
|
|
3006
|
+
fetch: async (client) => {
|
|
3007
|
+
const result = await client.activity.getState();
|
|
3008
|
+
if (!result.ok) throw result.error;
|
|
3009
|
+
return result.value;
|
|
3010
|
+
}
|
|
3011
|
+
});
|
|
4312
3012
|
function useActivityState(options = {}) {
|
|
4313
3013
|
const context = useOptionalCimplifyClient();
|
|
4314
3014
|
const client = options.client ?? context?.client;
|
|
4315
|
-
|
|
4316
|
-
throw new Error("useActivityState must be used within CimplifyProvider or passed { client }.");
|
|
4317
|
-
}
|
|
4318
|
-
const enabled = options.enabled ?? true;
|
|
4319
|
-
const cacheKey = useMemo(() => buildActivityStateCacheKey(client), [client]);
|
|
4320
|
-
const cached = activityStateCache.get(cacheKey);
|
|
4321
|
-
const [state, setState] = useState(cached ?? null);
|
|
4322
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
4323
|
-
const [error, setError] = useState(null);
|
|
4324
|
-
const load = useCallback(
|
|
4325
|
-
async (force = false) => {
|
|
4326
|
-
if (!enabled) {
|
|
4327
|
-
setIsLoading(false);
|
|
4328
|
-
return;
|
|
4329
|
-
}
|
|
4330
|
-
setError(null);
|
|
4331
|
-
if (!force) {
|
|
4332
|
-
const cachedState = activityStateCache.get(cacheKey);
|
|
4333
|
-
if (cachedState) {
|
|
4334
|
-
setState(cachedState);
|
|
4335
|
-
setIsLoading(false);
|
|
4336
|
-
return;
|
|
4337
|
-
}
|
|
4338
|
-
}
|
|
4339
|
-
setIsLoading(true);
|
|
4340
|
-
try {
|
|
4341
|
-
const existing = activityStateInflight.get(cacheKey);
|
|
4342
|
-
const promise = existing ?? (async () => {
|
|
4343
|
-
const result = await client.activity.getState();
|
|
4344
|
-
if (!result.ok) {
|
|
4345
|
-
throw result.error;
|
|
4346
|
-
}
|
|
4347
|
-
return result.value;
|
|
4348
|
-
})();
|
|
4349
|
-
if (!existing) {
|
|
4350
|
-
activityStateInflight.set(
|
|
4351
|
-
cacheKey,
|
|
4352
|
-
promise.finally(() => {
|
|
4353
|
-
activityStateInflight.delete(cacheKey);
|
|
4354
|
-
})
|
|
4355
|
-
);
|
|
4356
|
-
}
|
|
4357
|
-
const value = await promise;
|
|
4358
|
-
activityStateCache.set(cacheKey, value);
|
|
4359
|
-
setState(value);
|
|
4360
|
-
} catch (loadError) {
|
|
4361
|
-
setError(loadError);
|
|
4362
|
-
} finally {
|
|
4363
|
-
setIsLoading(false);
|
|
4364
|
-
}
|
|
4365
|
-
},
|
|
4366
|
-
[cacheKey, client, enabled]
|
|
4367
|
-
);
|
|
4368
|
-
useEffect(() => {
|
|
4369
|
-
void load(false);
|
|
4370
|
-
}, [load]);
|
|
4371
|
-
const refetch = useCallback(async () => {
|
|
4372
|
-
activityStateCache.delete(cacheKey);
|
|
4373
|
-
await load(true);
|
|
4374
|
-
}, [cacheKey, load]);
|
|
3015
|
+
const { data, isLoading, error, refetch } = activityStateQuery(options);
|
|
4375
3016
|
const dismissMessage = useCallback(
|
|
4376
3017
|
async (code) => {
|
|
3018
|
+
if (!client) return;
|
|
4377
3019
|
const result = await client.activity.dismissMessage(code);
|
|
4378
|
-
if (!result.ok)
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
}
|
|
4382
|
-
setState((prev) => {
|
|
4383
|
-
if (!prev) return prev;
|
|
4384
|
-
return { ...prev, messages: result.value.messages };
|
|
4385
|
-
});
|
|
4386
|
-
activityStateCache.delete(cacheKey);
|
|
4387
|
-
await load(true);
|
|
3020
|
+
if (!result.ok) return;
|
|
3021
|
+
activityStateQuery.clear();
|
|
3022
|
+
await refetch();
|
|
4388
3023
|
},
|
|
4389
|
-
[
|
|
3024
|
+
[client, refetch]
|
|
4390
3025
|
);
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
type: "recommendations",
|
|
4401
|
-
location_id: locationId,
|
|
4402
|
-
limit
|
|
4403
|
-
});
|
|
3026
|
+
return {
|
|
3027
|
+
state: data,
|
|
3028
|
+
messages: data?.messages ?? [],
|
|
3029
|
+
intent: data?.intent ?? "",
|
|
3030
|
+
isLoading,
|
|
3031
|
+
error,
|
|
3032
|
+
refetch,
|
|
3033
|
+
dismissMessage
|
|
3034
|
+
};
|
|
4404
3035
|
}
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
);
|
|
3036
|
+
|
|
3037
|
+
// src/react/hooks/use-recommendations.ts
|
|
3038
|
+
var recommendationsQuery = createCachedQuery({
|
|
3039
|
+
name: "useRecommendations",
|
|
3040
|
+
locationSensitive: true,
|
|
3041
|
+
key: (client, options) => {
|
|
3042
|
+
const locationId = options.locationId ?? client.getLocationId();
|
|
3043
|
+
return cacheKey(client.getPublicKey(), locationId, options.limit);
|
|
3044
|
+
},
|
|
3045
|
+
fetch: async (client, options) => {
|
|
3046
|
+
const locationId = options.locationId ?? client.getLocationId() ?? void 0;
|
|
3047
|
+
const result = await client.activity.getRecommendations({
|
|
3048
|
+
location_id: locationId,
|
|
3049
|
+
limit: options.limit
|
|
3050
|
+
});
|
|
3051
|
+
if (!result.ok) throw result.error;
|
|
3052
|
+
return result.value;
|
|
4412
3053
|
}
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
const
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
4424
|
-
const [error, setError] = useState(null);
|
|
4425
|
-
useEffect(() => {
|
|
4426
|
-
if (previousLocationIdRef.current !== locationId) {
|
|
4427
|
-
recommendationsCache.clear();
|
|
4428
|
-
recommendationsInflight.clear();
|
|
4429
|
-
previousLocationIdRef.current = locationId;
|
|
4430
|
-
}
|
|
4431
|
-
}, [locationId]);
|
|
4432
|
-
const load = useCallback(
|
|
4433
|
-
async (force = false) => {
|
|
4434
|
-
if (!enabled) {
|
|
4435
|
-
setIsLoading(false);
|
|
4436
|
-
return;
|
|
4437
|
-
}
|
|
4438
|
-
setError(null);
|
|
4439
|
-
if (!force) {
|
|
4440
|
-
const cachedResponse = recommendationsCache.get(cacheKey);
|
|
4441
|
-
if (cachedResponse) {
|
|
4442
|
-
setResponse(cachedResponse);
|
|
4443
|
-
setIsLoading(false);
|
|
4444
|
-
return;
|
|
4445
|
-
}
|
|
4446
|
-
}
|
|
4447
|
-
setIsLoading(true);
|
|
4448
|
-
try {
|
|
4449
|
-
const existing = recommendationsInflight.get(cacheKey);
|
|
4450
|
-
const promise = existing ?? (async () => {
|
|
4451
|
-
const result = await client.activity.getRecommendations({
|
|
4452
|
-
location_id: locationId,
|
|
4453
|
-
limit
|
|
4454
|
-
});
|
|
4455
|
-
if (!result.ok) {
|
|
4456
|
-
throw result.error;
|
|
4457
|
-
}
|
|
4458
|
-
return result.value;
|
|
4459
|
-
})();
|
|
4460
|
-
if (!existing) {
|
|
4461
|
-
recommendationsInflight.set(
|
|
4462
|
-
cacheKey,
|
|
4463
|
-
promise.finally(() => {
|
|
4464
|
-
recommendationsInflight.delete(cacheKey);
|
|
4465
|
-
})
|
|
4466
|
-
);
|
|
4467
|
-
}
|
|
4468
|
-
const value = await promise;
|
|
4469
|
-
recommendationsCache.set(cacheKey, value);
|
|
4470
|
-
setResponse(value);
|
|
4471
|
-
} catch (loadError) {
|
|
4472
|
-
setError(loadError);
|
|
4473
|
-
} finally {
|
|
4474
|
-
setIsLoading(false);
|
|
4475
|
-
}
|
|
4476
|
-
},
|
|
4477
|
-
[cacheKey, client, enabled, locationId, limit]
|
|
4478
|
-
);
|
|
4479
|
-
useEffect(() => {
|
|
4480
|
-
void load(false);
|
|
4481
|
-
}, [load]);
|
|
4482
|
-
const refetch = useCallback(async () => {
|
|
4483
|
-
recommendationsCache.delete(cacheKey);
|
|
4484
|
-
await load(true);
|
|
4485
|
-
}, [cacheKey, load]);
|
|
4486
|
-
const recommendations = response?.recommendations ?? [];
|
|
4487
|
-
const intent = response?.intent ?? "";
|
|
4488
|
-
return { recommendations, intent, isLoading, error, refetch };
|
|
4489
|
-
}
|
|
4490
|
-
var deliveryFeeCache = /* @__PURE__ */ new Map();
|
|
4491
|
-
var deliveryFeeInflight = /* @__PURE__ */ new Map();
|
|
4492
|
-
function buildDeliveryFeeCacheKey(client, latitude, longitude, country) {
|
|
4493
|
-
return JSON.stringify({
|
|
4494
|
-
key: client.getPublicKey(),
|
|
4495
|
-
lat: latitude,
|
|
4496
|
-
lng: longitude,
|
|
4497
|
-
country
|
|
4498
|
-
});
|
|
3054
|
+
});
|
|
3055
|
+
function useRecommendations(options = {}) {
|
|
3056
|
+
const { data, isLoading, error, refetch } = recommendationsQuery(options);
|
|
3057
|
+
return {
|
|
3058
|
+
recommendations: data?.recommendations ?? [],
|
|
3059
|
+
intent: data?.intent ?? "",
|
|
3060
|
+
isLoading,
|
|
3061
|
+
error,
|
|
3062
|
+
refetch
|
|
3063
|
+
};
|
|
4499
3064
|
}
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
3065
|
+
|
|
3066
|
+
// src/react/hooks/use-delivery-fee.ts
|
|
3067
|
+
var deliveryFeeQuery = createCachedQuery({
|
|
3068
|
+
name: "useDeliveryFee",
|
|
3069
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.latitude, options.longitude, options.country),
|
|
3070
|
+
fetch: async (client, options) => {
|
|
3071
|
+
const result = await client.delivery.getFee(options.latitude, options.longitude, options.country);
|
|
3072
|
+
if (!result.ok) throw result.error;
|
|
3073
|
+
return result.value;
|
|
4505
3074
|
}
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
const
|
|
4509
|
-
|
|
4510
|
-
[client, latitude, longitude, country]
|
|
4511
|
-
);
|
|
4512
|
-
const cached = deliveryFeeCache.get(cacheKey);
|
|
4513
|
-
const [fee, setFee] = useState(cached ?? null);
|
|
4514
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
4515
|
-
const [error, setError] = useState(null);
|
|
4516
|
-
const requestIdRef = useRef(0);
|
|
4517
|
-
const load = useCallback(
|
|
4518
|
-
async (force = false) => {
|
|
4519
|
-
if (!enabled) {
|
|
4520
|
-
setIsLoading(false);
|
|
4521
|
-
return;
|
|
4522
|
-
}
|
|
4523
|
-
setError(null);
|
|
4524
|
-
if (!force) {
|
|
4525
|
-
const cachedFee = deliveryFeeCache.get(cacheKey);
|
|
4526
|
-
if (cachedFee) {
|
|
4527
|
-
setFee(cachedFee);
|
|
4528
|
-
setIsLoading(false);
|
|
4529
|
-
return;
|
|
4530
|
-
}
|
|
4531
|
-
}
|
|
4532
|
-
setIsLoading(true);
|
|
4533
|
-
const currentRequestId = ++requestIdRef.current;
|
|
4534
|
-
try {
|
|
4535
|
-
const existing = deliveryFeeInflight.get(cacheKey);
|
|
4536
|
-
const promise = existing ?? (async () => {
|
|
4537
|
-
const result = await client.delivery.getFee(latitude, longitude, country);
|
|
4538
|
-
if (!result.ok) {
|
|
4539
|
-
throw result.error;
|
|
4540
|
-
}
|
|
4541
|
-
return result.value;
|
|
4542
|
-
})();
|
|
4543
|
-
if (!existing) {
|
|
4544
|
-
deliveryFeeInflight.set(
|
|
4545
|
-
cacheKey,
|
|
4546
|
-
promise.finally(() => {
|
|
4547
|
-
deliveryFeeInflight.delete(cacheKey);
|
|
4548
|
-
})
|
|
4549
|
-
);
|
|
4550
|
-
}
|
|
4551
|
-
const value = await promise;
|
|
4552
|
-
if (currentRequestId !== requestIdRef.current) return;
|
|
4553
|
-
deliveryFeeCache.set(cacheKey, value);
|
|
4554
|
-
setFee(value);
|
|
4555
|
-
} catch (loadError) {
|
|
4556
|
-
if (currentRequestId !== requestIdRef.current) return;
|
|
4557
|
-
setError(loadError);
|
|
4558
|
-
} finally {
|
|
4559
|
-
if (currentRequestId === requestIdRef.current) {
|
|
4560
|
-
setIsLoading(false);
|
|
4561
|
-
}
|
|
4562
|
-
}
|
|
4563
|
-
},
|
|
4564
|
-
[cacheKey, client, country, enabled, latitude, longitude]
|
|
4565
|
-
);
|
|
4566
|
-
useEffect(() => {
|
|
4567
|
-
void load(false);
|
|
4568
|
-
}, [load]);
|
|
4569
|
-
const refetch = useCallback(async () => {
|
|
4570
|
-
deliveryFeeCache.delete(cacheKey);
|
|
4571
|
-
await load(true);
|
|
4572
|
-
}, [cacheKey, load]);
|
|
4573
|
-
return { fee, isLoading, error, refetch };
|
|
4574
|
-
}
|
|
4575
|
-
var fxRateCache = /* @__PURE__ */ new Map();
|
|
4576
|
-
var fxRateInflight = /* @__PURE__ */ new Map();
|
|
4577
|
-
function buildFxRateCacheKey(client, from, to) {
|
|
4578
|
-
return JSON.stringify({ key: client.getPublicKey(), from, to });
|
|
3075
|
+
});
|
|
3076
|
+
function useDeliveryFee(options) {
|
|
3077
|
+
const { data, isLoading, error, refetch } = deliveryFeeQuery(options);
|
|
3078
|
+
return { fee: data, isLoading, error, refetch };
|
|
4579
3079
|
}
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
3080
|
+
|
|
3081
|
+
// src/react/hooks/use-fx-rate.ts
|
|
3082
|
+
var fxRateQuery = createCachedQuery({
|
|
3083
|
+
name: "useFxRate",
|
|
3084
|
+
key: (client, options) => cacheKey(client.getPublicKey(), options.from, options.to),
|
|
3085
|
+
fetch: async (client, options) => {
|
|
3086
|
+
const result = await client.fx.getRate(options.from, options.to);
|
|
3087
|
+
if (!result.ok) throw result.error;
|
|
3088
|
+
return result.value;
|
|
4585
3089
|
}
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
const
|
|
4589
|
-
|
|
4590
|
-
[client, from, to]
|
|
4591
|
-
);
|
|
4592
|
-
const cached = fxRateCache.get(cacheKey);
|
|
4593
|
-
const [rate, setRate] = useState(cached ?? null);
|
|
4594
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
4595
|
-
const [error, setError] = useState(null);
|
|
4596
|
-
const load = useCallback(
|
|
4597
|
-
async (force = false) => {
|
|
4598
|
-
if (!enabled) {
|
|
4599
|
-
setIsLoading(false);
|
|
4600
|
-
return;
|
|
4601
|
-
}
|
|
4602
|
-
setError(null);
|
|
4603
|
-
if (!force) {
|
|
4604
|
-
const cachedRate = fxRateCache.get(cacheKey);
|
|
4605
|
-
if (cachedRate) {
|
|
4606
|
-
setRate(cachedRate);
|
|
4607
|
-
setIsLoading(false);
|
|
4608
|
-
return;
|
|
4609
|
-
}
|
|
4610
|
-
}
|
|
4611
|
-
setIsLoading(true);
|
|
4612
|
-
try {
|
|
4613
|
-
const existing = fxRateInflight.get(cacheKey);
|
|
4614
|
-
const promise = existing ?? (async () => {
|
|
4615
|
-
const result = await client.fx.getRate(from, to);
|
|
4616
|
-
if (!result.ok) {
|
|
4617
|
-
throw result.error;
|
|
4618
|
-
}
|
|
4619
|
-
return result.value;
|
|
4620
|
-
})();
|
|
4621
|
-
if (!existing) {
|
|
4622
|
-
fxRateInflight.set(
|
|
4623
|
-
cacheKey,
|
|
4624
|
-
promise.finally(() => {
|
|
4625
|
-
fxRateInflight.delete(cacheKey);
|
|
4626
|
-
})
|
|
4627
|
-
);
|
|
4628
|
-
}
|
|
4629
|
-
const value = await promise;
|
|
4630
|
-
fxRateCache.set(cacheKey, value);
|
|
4631
|
-
setRate(value);
|
|
4632
|
-
} catch (loadError) {
|
|
4633
|
-
setError(loadError);
|
|
4634
|
-
} finally {
|
|
4635
|
-
setIsLoading(false);
|
|
4636
|
-
}
|
|
4637
|
-
},
|
|
4638
|
-
[cacheKey, client, enabled, from, to]
|
|
4639
|
-
);
|
|
4640
|
-
useEffect(() => {
|
|
4641
|
-
void load(false);
|
|
4642
|
-
}, [load]);
|
|
4643
|
-
const refetch = useCallback(async () => {
|
|
4644
|
-
fxRateCache.delete(cacheKey);
|
|
4645
|
-
await load(true);
|
|
4646
|
-
}, [cacheKey, load]);
|
|
4647
|
-
return { rate, isLoading, error, refetch };
|
|
4648
|
-
}
|
|
4649
|
-
var bootstrapCache = /* @__PURE__ */ new Map();
|
|
4650
|
-
var bootstrapInflight = /* @__PURE__ */ new Map();
|
|
4651
|
-
function buildBootstrapCacheKey(client) {
|
|
4652
|
-
return JSON.stringify({ key: client.getPublicKey(), type: "bootstrap" });
|
|
3090
|
+
});
|
|
3091
|
+
function useFxRate(options) {
|
|
3092
|
+
const { data, isLoading, error, refetch } = fxRateQuery(options);
|
|
3093
|
+
return { rate: data, isLoading, error, refetch };
|
|
4653
3094
|
}
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
3095
|
+
|
|
3096
|
+
// src/react/hooks/use-bootstrap.ts
|
|
3097
|
+
var bootstrapQuery = createCachedQuery({
|
|
3098
|
+
name: "useBootstrap",
|
|
3099
|
+
key: (client) => cacheKey(client.getPublicKey()),
|
|
3100
|
+
fetch: async (client) => {
|
|
3101
|
+
const result = await client.business.getBootstrap();
|
|
3102
|
+
if (!result.ok) throw result.error;
|
|
3103
|
+
return result.value;
|
|
4659
3104
|
}
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
const
|
|
4663
|
-
|
|
4664
|
-
const [isLoading, setIsLoading] = useState(enabled && !cached);
|
|
4665
|
-
const [error, setError] = useState(null);
|
|
4666
|
-
const load = useCallback(
|
|
4667
|
-
async (force = false) => {
|
|
4668
|
-
if (!enabled) {
|
|
4669
|
-
setIsLoading(false);
|
|
4670
|
-
return;
|
|
4671
|
-
}
|
|
4672
|
-
setError(null);
|
|
4673
|
-
if (!force) {
|
|
4674
|
-
const cachedBootstrap = bootstrapCache.get(cacheKey);
|
|
4675
|
-
if (cachedBootstrap) {
|
|
4676
|
-
setBootstrap(cachedBootstrap);
|
|
4677
|
-
setIsLoading(false);
|
|
4678
|
-
return;
|
|
4679
|
-
}
|
|
4680
|
-
}
|
|
4681
|
-
setIsLoading(true);
|
|
4682
|
-
try {
|
|
4683
|
-
const existing = bootstrapInflight.get(cacheKey);
|
|
4684
|
-
const promise = existing ?? (async () => {
|
|
4685
|
-
const result = await client.business.getBootstrap();
|
|
4686
|
-
if (!result.ok) {
|
|
4687
|
-
throw result.error;
|
|
4688
|
-
}
|
|
4689
|
-
return result.value;
|
|
4690
|
-
})();
|
|
4691
|
-
if (!existing) {
|
|
4692
|
-
bootstrapInflight.set(
|
|
4693
|
-
cacheKey,
|
|
4694
|
-
promise.finally(() => {
|
|
4695
|
-
bootstrapInflight.delete(cacheKey);
|
|
4696
|
-
})
|
|
4697
|
-
);
|
|
4698
|
-
}
|
|
4699
|
-
const value = await promise;
|
|
4700
|
-
bootstrapCache.set(cacheKey, value);
|
|
4701
|
-
setBootstrap(value);
|
|
4702
|
-
} catch (loadError) {
|
|
4703
|
-
setError(loadError);
|
|
4704
|
-
} finally {
|
|
4705
|
-
setIsLoading(false);
|
|
4706
|
-
}
|
|
4707
|
-
},
|
|
4708
|
-
[cacheKey, client, enabled]
|
|
4709
|
-
);
|
|
4710
|
-
useEffect(() => {
|
|
4711
|
-
void load(false);
|
|
4712
|
-
}, [load]);
|
|
4713
|
-
const refetch = useCallback(async () => {
|
|
4714
|
-
bootstrapCache.delete(cacheKey);
|
|
4715
|
-
await load(true);
|
|
4716
|
-
}, [cacheKey, load]);
|
|
4717
|
-
return { bootstrap, isLoading, error, refetch };
|
|
3105
|
+
});
|
|
3106
|
+
function useBootstrap(options = {}) {
|
|
3107
|
+
const { data, isLoading, error, refetch } = bootstrapQuery(options);
|
|
3108
|
+
return { bootstrap: data, isLoading, error, refetch };
|
|
4718
3109
|
}
|
|
4719
3110
|
var ElementsContext = createContext({
|
|
4720
3111
|
elements: null,
|