omni-sync-sdk 0.7.1 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +0 -0
- package/README.md +144 -0
- package/dist/index.d.mts +1 -3
- package/dist/index.d.ts +1 -3
- package/dist/index.js +4 -6
- package/dist/index.mjs +4 -6
- package/package.json +9 -10
package/LICENSE
ADDED
|
File without changes
|
package/README.md
CHANGED
|
@@ -1921,6 +1921,148 @@ When building a store, implement these pages:
|
|
|
1921
1921
|
|
|
1922
1922
|
---
|
|
1923
1923
|
|
|
1924
|
+
## Error Handling & Toast Notifications
|
|
1925
|
+
|
|
1926
|
+
For a polished user experience, use toast notifications to show success/error messages. We recommend [Sonner](https://sonner.emilkowal.ski/) - a lightweight toast library.
|
|
1927
|
+
|
|
1928
|
+
### Setup Toast Notifications
|
|
1929
|
+
|
|
1930
|
+
```bash
|
|
1931
|
+
npm install sonner
|
|
1932
|
+
```
|
|
1933
|
+
|
|
1934
|
+
Add the Toaster component to your app layout:
|
|
1935
|
+
|
|
1936
|
+
```tsx
|
|
1937
|
+
// app/layout.tsx or App.tsx
|
|
1938
|
+
import { Toaster } from 'sonner';
|
|
1939
|
+
|
|
1940
|
+
export default function RootLayout({ children }) {
|
|
1941
|
+
return (
|
|
1942
|
+
<html>
|
|
1943
|
+
<body>
|
|
1944
|
+
{children}
|
|
1945
|
+
<Toaster
|
|
1946
|
+
position="top-right"
|
|
1947
|
+
richColors
|
|
1948
|
+
closeButton
|
|
1949
|
+
toastOptions={{
|
|
1950
|
+
duration: 4000,
|
|
1951
|
+
}}
|
|
1952
|
+
/>
|
|
1953
|
+
</body>
|
|
1954
|
+
</html>
|
|
1955
|
+
);
|
|
1956
|
+
}
|
|
1957
|
+
```
|
|
1958
|
+
|
|
1959
|
+
### Handling SDK Errors
|
|
1960
|
+
|
|
1961
|
+
The SDK throws `OmniSyncError` with helpful messages. Wrap SDK calls in try/catch:
|
|
1962
|
+
|
|
1963
|
+
```tsx
|
|
1964
|
+
import { toast } from 'sonner';
|
|
1965
|
+
import { OmniSyncError } from 'omni-sync-sdk';
|
|
1966
|
+
|
|
1967
|
+
// Add to cart with toast feedback
|
|
1968
|
+
const handleAddToCart = async (productId: string, quantity: number) => {
|
|
1969
|
+
try {
|
|
1970
|
+
omni.addToLocalCart({ productId, quantity });
|
|
1971
|
+
toast.success('Added to cart!');
|
|
1972
|
+
} catch (error) {
|
|
1973
|
+
if (error instanceof OmniSyncError) {
|
|
1974
|
+
toast.error(error.message);
|
|
1975
|
+
} else {
|
|
1976
|
+
toast.error('Something went wrong');
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
};
|
|
1980
|
+
|
|
1981
|
+
// Checkout with toast feedback
|
|
1982
|
+
const handleCheckout = async () => {
|
|
1983
|
+
try {
|
|
1984
|
+
const order = await omni.submitGuestOrder();
|
|
1985
|
+
toast.success(`Order placed! Order #${order.orderNumber}`);
|
|
1986
|
+
// Navigate to success page
|
|
1987
|
+
} catch (error) {
|
|
1988
|
+
if (error instanceof OmniSyncError) {
|
|
1989
|
+
// Show specific error message from SDK
|
|
1990
|
+
toast.error(error.message);
|
|
1991
|
+
} else {
|
|
1992
|
+
toast.error('Failed to place order. Please try again.');
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
};
|
|
1996
|
+
```
|
|
1997
|
+
|
|
1998
|
+
### Common Error Messages
|
|
1999
|
+
|
|
2000
|
+
| Error | When it occurs |
|
|
2001
|
+
| ------------------------------ | ---------------------------------- |
|
|
2002
|
+
| `Cart is empty` | Trying to checkout with empty cart |
|
|
2003
|
+
| `Customer email is required` | Missing email at checkout |
|
|
2004
|
+
| `Shipping address is required` | Missing shipping address |
|
|
2005
|
+
| `Product not found` | Invalid product ID |
|
|
2006
|
+
| `Insufficient inventory` | Not enough stock |
|
|
2007
|
+
| `Invalid quantity` | Quantity < 1 or > available |
|
|
2008
|
+
|
|
2009
|
+
### Custom Hook for SDK Operations (Optional)
|
|
2010
|
+
|
|
2011
|
+
Create a reusable hook for SDK operations with automatic toast handling:
|
|
2012
|
+
|
|
2013
|
+
```tsx
|
|
2014
|
+
// hooks/useOmniAction.ts
|
|
2015
|
+
import { useState } from 'react';
|
|
2016
|
+
import { toast } from 'sonner';
|
|
2017
|
+
import { OmniSyncError } from 'omni-sync-sdk';
|
|
2018
|
+
|
|
2019
|
+
export function useOmniAction<T>() {
|
|
2020
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
2021
|
+
|
|
2022
|
+
const execute = async (
|
|
2023
|
+
action: () => Promise<T>,
|
|
2024
|
+
options?: {
|
|
2025
|
+
successMessage?: string;
|
|
2026
|
+
errorMessage?: string;
|
|
2027
|
+
onSuccess?: (result: T) => void;
|
|
2028
|
+
}
|
|
2029
|
+
): Promise<T | null> => {
|
|
2030
|
+
setIsLoading(true);
|
|
2031
|
+
try {
|
|
2032
|
+
const result = await action();
|
|
2033
|
+
if (options?.successMessage) {
|
|
2034
|
+
toast.success(options.successMessage);
|
|
2035
|
+
}
|
|
2036
|
+
options?.onSuccess?.(result);
|
|
2037
|
+
return result;
|
|
2038
|
+
} catch (error) {
|
|
2039
|
+
const message =
|
|
2040
|
+
error instanceof OmniSyncError
|
|
2041
|
+
? error.message
|
|
2042
|
+
: options?.errorMessage || 'Something went wrong';
|
|
2043
|
+
toast.error(message);
|
|
2044
|
+
return null;
|
|
2045
|
+
} finally {
|
|
2046
|
+
setIsLoading(false);
|
|
2047
|
+
}
|
|
2048
|
+
};
|
|
2049
|
+
|
|
2050
|
+
return { execute, isLoading };
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2053
|
+
// Usage:
|
|
2054
|
+
const { execute, isLoading } = useOmniAction();
|
|
2055
|
+
|
|
2056
|
+
const handlePlaceOrder = () => {
|
|
2057
|
+
execute(() => omni.submitGuestOrder(), {
|
|
2058
|
+
successMessage: 'Order placed successfully!',
|
|
2059
|
+
onSuccess: (order) => navigate(`/order/${order.orderId}`),
|
|
2060
|
+
});
|
|
2061
|
+
};
|
|
2062
|
+
```
|
|
2063
|
+
|
|
2064
|
+
---
|
|
2065
|
+
|
|
1924
2066
|
## Important Rules
|
|
1925
2067
|
|
|
1926
2068
|
### DO:
|
|
@@ -1928,9 +2070,11 @@ When building a store, implement these pages:
|
|
|
1928
2070
|
- Install `omni-sync-sdk` and use it for ALL data
|
|
1929
2071
|
- Import types from the SDK
|
|
1930
2072
|
- Handle loading states and errors
|
|
2073
|
+
- **Use toast notifications (Sonner) for user feedback on actions**
|
|
1931
2074
|
- Persist cart ID in localStorage
|
|
1932
2075
|
- Persist customer token after login
|
|
1933
2076
|
- **Check `descriptionFormat` and render HTML with `dangerouslySetInnerHTML` when format is `'html'`**
|
|
2077
|
+
- **Wrap SDK calls in try/catch and show error toasts**
|
|
1934
2078
|
|
|
1935
2079
|
### DON'T:
|
|
1936
2080
|
|
package/dist/index.d.mts
CHANGED
|
@@ -2051,9 +2051,7 @@ declare class OmniSyncClient {
|
|
|
2051
2051
|
*/
|
|
2052
2052
|
completeGuestCheckout(checkoutId: string, options?: {
|
|
2053
2053
|
clearCartOnSuccess?: boolean;
|
|
2054
|
-
}): Promise<
|
|
2055
|
-
orderId: string;
|
|
2056
|
-
}>;
|
|
2054
|
+
}): Promise<GuestOrderResponse>;
|
|
2057
2055
|
/**
|
|
2058
2056
|
* Create order from custom data (not from local cart)
|
|
2059
2057
|
* Use this if you manage cart state yourself
|
package/dist/index.d.ts
CHANGED
|
@@ -2051,9 +2051,7 @@ declare class OmniSyncClient {
|
|
|
2051
2051
|
*/
|
|
2052
2052
|
completeGuestCheckout(checkoutId: string, options?: {
|
|
2053
2053
|
clearCartOnSuccess?: boolean;
|
|
2054
|
-
}): Promise<
|
|
2055
|
-
orderId: string;
|
|
2056
|
-
}>;
|
|
2054
|
+
}): Promise<GuestOrderResponse>;
|
|
2057
2055
|
/**
|
|
2058
2056
|
* Create order from custom data (not from local cart)
|
|
2059
2057
|
* Use this if you manage cart state yourself
|
package/dist/index.js
CHANGED
|
@@ -1747,12 +1747,10 @@ var OmniSyncClient = class {
|
|
|
1747
1747
|
});
|
|
1748
1748
|
return {
|
|
1749
1749
|
orderId: orderResult.orderId,
|
|
1750
|
-
orderNumber: orderResult.orderId,
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
// Actual total comes from server
|
|
1755
|
-
message: "Order created successfully (tracked)"
|
|
1750
|
+
orderNumber: orderResult.orderNumber || orderResult.orderId,
|
|
1751
|
+
status: orderResult.status || "pending",
|
|
1752
|
+
total: orderResult.total ?? 0,
|
|
1753
|
+
message: orderResult.message || "Order created successfully"
|
|
1756
1754
|
};
|
|
1757
1755
|
}
|
|
1758
1756
|
} catch {
|
package/dist/index.mjs
CHANGED
|
@@ -1722,12 +1722,10 @@ var OmniSyncClient = class {
|
|
|
1722
1722
|
});
|
|
1723
1723
|
return {
|
|
1724
1724
|
orderId: orderResult.orderId,
|
|
1725
|
-
orderNumber: orderResult.orderId,
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
// Actual total comes from server
|
|
1730
|
-
message: "Order created successfully (tracked)"
|
|
1725
|
+
orderNumber: orderResult.orderNumber || orderResult.orderId,
|
|
1726
|
+
status: orderResult.status || "pending",
|
|
1727
|
+
total: orderResult.total ?? 0,
|
|
1728
|
+
message: orderResult.message || "Order created successfully"
|
|
1731
1729
|
};
|
|
1732
1730
|
}
|
|
1733
1731
|
} catch {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omni-sync-sdk",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "Official SDK for building e-commerce storefronts with OmniSync Platform. Perfect for vibe-coded sites, AI-built stores (Cursor, Lovable, v0), and custom storefronts.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -16,14 +16,6 @@
|
|
|
16
16
|
"dist",
|
|
17
17
|
"README.md"
|
|
18
18
|
],
|
|
19
|
-
"scripts": {
|
|
20
|
-
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
21
|
-
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
22
|
-
"lint": "eslint \"src/**/*.ts\"",
|
|
23
|
-
"test": "vitest run",
|
|
24
|
-
"test:watch": "vitest",
|
|
25
|
-
"prepublishOnly": "pnpm build"
|
|
26
|
-
},
|
|
27
19
|
"keywords": [
|
|
28
20
|
"omni-sync",
|
|
29
21
|
"e-commerce",
|
|
@@ -72,5 +64,12 @@
|
|
|
72
64
|
"typescript": {
|
|
73
65
|
"optional": true
|
|
74
66
|
}
|
|
67
|
+
},
|
|
68
|
+
"scripts": {
|
|
69
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
70
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
71
|
+
"lint": "eslint \"src/**/*.ts\"",
|
|
72
|
+
"test": "vitest run",
|
|
73
|
+
"test:watch": "vitest"
|
|
75
74
|
}
|
|
76
|
-
}
|
|
75
|
+
}
|