@getecho-ai/react-native-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +350 -0
- package/dist/bridge/CallbackManager.d.ts +46 -0
- package/dist/bridge/CallbackManager.js +117 -0
- package/dist/bridge/WebViewBridge.d.ts +67 -0
- package/dist/bridge/WebViewBridge.js +151 -0
- package/dist/components/EchoChat.d.ts +20 -0
- package/dist/components/EchoChat.js +45 -0
- package/dist/components/EchoChatButton.d.ts +15 -0
- package/dist/components/EchoChatButton.js +65 -0
- package/dist/components/EchoChatModal.d.ts +13 -0
- package/dist/components/EchoChatModal.js +473 -0
- package/dist/components/EchoProvider.d.ts +30 -0
- package/dist/components/EchoProvider.js +240 -0
- package/dist/hooks/useSimpleCart.d.ts +76 -0
- package/dist/hooks/useSimpleCart.js +134 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.js +77 -0
- package/dist/types/index.d.ts +156 -0
- package/dist/types/index.js +5 -0
- package/dist/utils/resolveApiUrl.d.ts +42 -0
- package/dist/utils/resolveApiUrl.js +82 -0
- package/package.json +54 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* EchoProvider - Main context provider for Echo SDK
|
|
4
|
+
*
|
|
5
|
+
* Provides:
|
|
6
|
+
* - SDK configuration (apiKey, callbacks)
|
|
7
|
+
* - User session management
|
|
8
|
+
* - Bridge initialization
|
|
9
|
+
*/
|
|
10
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
11
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.EchoProvider = exports.useEcho = void 0;
|
|
15
|
+
const async_storage_1 = __importDefault(require("@react-native-async-storage/async-storage"));
|
|
16
|
+
const react_1 = require("react");
|
|
17
|
+
const resolveApiUrl_1 = require("../utils/resolveApiUrl");
|
|
18
|
+
/**
|
|
19
|
+
* Generate a UUID v4 string
|
|
20
|
+
*/
|
|
21
|
+
function generateUUID() {
|
|
22
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
23
|
+
const r = (Math.random() * 16) | 0;
|
|
24
|
+
const v = c === "x" ? r : (r & 0x3) | 0x8;
|
|
25
|
+
return v.toString(16);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Check if a string is a valid UUID v4
|
|
30
|
+
*/
|
|
31
|
+
function isValidUUID(str) {
|
|
32
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
33
|
+
return uuidRegex.test(str);
|
|
34
|
+
}
|
|
35
|
+
const EchoContext = (0, react_1.createContext)(null);
|
|
36
|
+
const useEcho = () => {
|
|
37
|
+
const context = (0, react_1.useContext)(EchoContext);
|
|
38
|
+
if (!context) {
|
|
39
|
+
throw new Error("useEcho must be used within EchoProvider");
|
|
40
|
+
}
|
|
41
|
+
return context;
|
|
42
|
+
};
|
|
43
|
+
exports.useEcho = useEcho;
|
|
44
|
+
const EchoProvider = ({ config, children, }) => {
|
|
45
|
+
const [userId, setUserId] = (0, react_1.useState)(config.userId || "");
|
|
46
|
+
const [chatId, setChatId] = (0, react_1.useState)("");
|
|
47
|
+
const [isReady, setIsReady] = (0, react_1.useState)(false);
|
|
48
|
+
// Initialize user ID from storage or generate new one
|
|
49
|
+
(0, react_1.useEffect)(() => {
|
|
50
|
+
const syncUserWithServer = async (id) => {
|
|
51
|
+
const baseUrl = (0, resolveApiUrl_1.resolveApiUrl)(config.apiUrl).replace(/\/+$/, "");
|
|
52
|
+
const controller = new AbortController();
|
|
53
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000);
|
|
54
|
+
try {
|
|
55
|
+
const response = await fetch(`${baseUrl}/api/user`, {
|
|
56
|
+
method: "POST",
|
|
57
|
+
headers: {
|
|
58
|
+
"X-API-Key": config.apiKey,
|
|
59
|
+
"Content-Type": "application/json",
|
|
60
|
+
},
|
|
61
|
+
body: JSON.stringify({ userId: id }),
|
|
62
|
+
signal: controller.signal,
|
|
63
|
+
});
|
|
64
|
+
clearTimeout(timeoutId);
|
|
65
|
+
if (response.ok) {
|
|
66
|
+
const data = await response.json();
|
|
67
|
+
if (data.userIdChanged && data.userId) {
|
|
68
|
+
await async_storage_1.default.setItem("echo_user_id", data.userId);
|
|
69
|
+
setUserId(data.userId);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
clearTimeout(timeoutId);
|
|
75
|
+
if (err instanceof Error && err.name !== "AbortError") {
|
|
76
|
+
console.warn("[EchoSDK] User sync failed:", err.message);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const initUser = async () => {
|
|
81
|
+
try {
|
|
82
|
+
let storedUserId = config.userId;
|
|
83
|
+
let storedChatId = null;
|
|
84
|
+
if (!storedUserId) {
|
|
85
|
+
storedUserId =
|
|
86
|
+
(await async_storage_1.default.getItem("echo_user_id")) || undefined;
|
|
87
|
+
}
|
|
88
|
+
const shouldUseStored = storedUserId && (config.userId || isValidUUID(storedUserId));
|
|
89
|
+
if (!shouldUseStored) {
|
|
90
|
+
// Generate new UUID if no stored ID or old format (non-UUID)
|
|
91
|
+
storedUserId = generateUUID();
|
|
92
|
+
await async_storage_1.default.setItem("echo_user_id", storedUserId);
|
|
93
|
+
}
|
|
94
|
+
setUserId(storedUserId || "");
|
|
95
|
+
await syncUserWithServer(storedUserId || "");
|
|
96
|
+
try {
|
|
97
|
+
storedChatId = await async_storage_1.default.getItem("echo_chat_id");
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
storedChatId = null;
|
|
101
|
+
}
|
|
102
|
+
if (storedChatId && isValidUUID(storedChatId)) {
|
|
103
|
+
setChatId(storedChatId);
|
|
104
|
+
}
|
|
105
|
+
setIsReady(true);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.error("[EchoSDK] Failed to initialize user:", error);
|
|
109
|
+
// Fallback to temp user ID (UUID format)
|
|
110
|
+
const tempId = generateUUID();
|
|
111
|
+
setUserId(tempId);
|
|
112
|
+
await syncUserWithServer(tempId);
|
|
113
|
+
setIsReady(true);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
initUser();
|
|
117
|
+
}, [config.userId, config.apiKey, config.apiUrl]);
|
|
118
|
+
const updateUserId = (0, react_1.useCallback)(async (newUserId) => {
|
|
119
|
+
setUserId(newUserId);
|
|
120
|
+
try {
|
|
121
|
+
await async_storage_1.default.setItem("echo_user_id", newUserId);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
console.error("[EchoSDK] Failed to persist user ID:", error);
|
|
125
|
+
}
|
|
126
|
+
}, []);
|
|
127
|
+
const updateChatId = (0, react_1.useCallback)(async (newChatId) => {
|
|
128
|
+
setChatId(newChatId);
|
|
129
|
+
try {
|
|
130
|
+
await async_storage_1.default.setItem("echo_chat_id", newChatId);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
console.error("[EchoSDK] Failed to persist chat ID:", error);
|
|
134
|
+
}
|
|
135
|
+
}, []);
|
|
136
|
+
/**
|
|
137
|
+
* Identify user with backend (matches web embed behavior)
|
|
138
|
+
* Calls /api/user/identify if userEmail or userIdentifier is provided
|
|
139
|
+
* Updates userId in AsyncStorage if backend returns userIdChanged
|
|
140
|
+
*/
|
|
141
|
+
const identifyUser = (0, react_1.useCallback)(async () => {
|
|
142
|
+
if (!config.userEmail && !config.userIdentifier) {
|
|
143
|
+
return; // Nothing to identify
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
const baseUrl = (0, resolveApiUrl_1.resolveApiUrl)(config.apiUrl).replace(/\/+$/, "");
|
|
147
|
+
const response = await fetch(`${baseUrl}/api/user/identify`, {
|
|
148
|
+
method: "POST",
|
|
149
|
+
headers: {
|
|
150
|
+
"Content-Type": "application/json",
|
|
151
|
+
"X-API-Key": config.apiKey,
|
|
152
|
+
},
|
|
153
|
+
body: JSON.stringify({
|
|
154
|
+
userId,
|
|
155
|
+
email: config.userEmail,
|
|
156
|
+
userIdentifier: config.userIdentifier,
|
|
157
|
+
}),
|
|
158
|
+
});
|
|
159
|
+
const data = await response.json();
|
|
160
|
+
// Handle userIdChanged (same as web embed)
|
|
161
|
+
if (data.userIdChanged && data.userId) {
|
|
162
|
+
console.log("[EchoSDK] userId changed:", userId, "→", data.userId);
|
|
163
|
+
await updateUserId(data.userId);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
console.error("[EchoSDK] Identification failed:", error);
|
|
168
|
+
// Don't block - continue without identification
|
|
169
|
+
}
|
|
170
|
+
}, [
|
|
171
|
+
userId,
|
|
172
|
+
config.apiKey,
|
|
173
|
+
config.apiUrl,
|
|
174
|
+
config.userEmail,
|
|
175
|
+
config.userIdentifier,
|
|
176
|
+
updateUserId,
|
|
177
|
+
]);
|
|
178
|
+
// Auto-identify user when ready and email/identifier is provided
|
|
179
|
+
(0, react_1.useEffect)(() => {
|
|
180
|
+
if (isReady && userId && (config.userEmail || config.userIdentifier)) {
|
|
181
|
+
identifyUser();
|
|
182
|
+
}
|
|
183
|
+
}, [isReady, userId, config.userEmail, config.userIdentifier, identifyUser]);
|
|
184
|
+
// Wrap callbacks with error handling
|
|
185
|
+
const handleAddToCart = (0, react_1.useCallback)(async (product, quantity) => {
|
|
186
|
+
try {
|
|
187
|
+
return await config.callbacks.onAddToCart(product, quantity);
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
console.error("[EchoSDK] onAddToCart error:", error);
|
|
191
|
+
return {
|
|
192
|
+
success: false,
|
|
193
|
+
error: error instanceof Error ? error.message : "ADD_TO_CART_FAILED",
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}, [config.callbacks]);
|
|
197
|
+
const handleGetCart = (0, react_1.useCallback)(async () => {
|
|
198
|
+
try {
|
|
199
|
+
return await config.callbacks.onGetCart();
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
console.error("[EchoSDK] onGetCart error:", error);
|
|
203
|
+
return {
|
|
204
|
+
success: false,
|
|
205
|
+
error: error instanceof Error ? error.message : "GET_CART_FAILED",
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}, [config.callbacks]);
|
|
209
|
+
const handleNavigateToProduct = (0, react_1.useCallback)((productId) => {
|
|
210
|
+
if (config.callbacks.onNavigateToProduct) {
|
|
211
|
+
config.callbacks.onNavigateToProduct(productId);
|
|
212
|
+
}
|
|
213
|
+
}, [config.callbacks.onNavigateToProduct]);
|
|
214
|
+
const handleNavigateToCheckout = (0, react_1.useCallback)(() => {
|
|
215
|
+
if (config.callbacks.onNavigateToCheckout) {
|
|
216
|
+
config.callbacks.onNavigateToCheckout();
|
|
217
|
+
}
|
|
218
|
+
}, [config.callbacks.onNavigateToCheckout]);
|
|
219
|
+
const handleAuthRequired = (0, react_1.useCallback)(() => {
|
|
220
|
+
if (config.callbacks.onAuthRequired) {
|
|
221
|
+
config.callbacks.onAuthRequired();
|
|
222
|
+
}
|
|
223
|
+
}, [config.callbacks.onAuthRequired]);
|
|
224
|
+
const value = {
|
|
225
|
+
config,
|
|
226
|
+
userId,
|
|
227
|
+
chatId,
|
|
228
|
+
isReady,
|
|
229
|
+
updateUserId,
|
|
230
|
+
updateChatId,
|
|
231
|
+
handleAddToCart,
|
|
232
|
+
handleGetCart,
|
|
233
|
+
handleNavigateToProduct,
|
|
234
|
+
handleNavigateToCheckout,
|
|
235
|
+
handleAuthRequired,
|
|
236
|
+
};
|
|
237
|
+
return <EchoContext.Provider value={value}>{children}</EchoContext.Provider>;
|
|
238
|
+
};
|
|
239
|
+
exports.EchoProvider = EchoProvider;
|
|
240
|
+
exports.default = exports.EchoProvider;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useSimpleCart - Ready-to-use cart management hook
|
|
3
|
+
*
|
|
4
|
+
* Provides a minimal cart implementation for quick SDK integration.
|
|
5
|
+
* For production apps, you'll likely want to replace this with your own cart logic.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { EchoProvider, EchoChat, useSimpleCart } from '@getecho-ai/react-native-sdk';
|
|
10
|
+
*
|
|
11
|
+
* function App() {
|
|
12
|
+
* const { cart, callbacks } = useSimpleCart();
|
|
13
|
+
*
|
|
14
|
+
* return (
|
|
15
|
+
* <EchoProvider config={{ apiKey: 'your-key', callbacks }}>
|
|
16
|
+
* <YourApp cart={cart} />
|
|
17
|
+
* <EchoChat />
|
|
18
|
+
* </EchoProvider>
|
|
19
|
+
* );
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import type { Cart, EchoCallbacks } from "../types";
|
|
24
|
+
export type UseSimpleCartOptions = {
|
|
25
|
+
/**
|
|
26
|
+
* Initial cart state
|
|
27
|
+
*/
|
|
28
|
+
initialCart?: Cart;
|
|
29
|
+
/**
|
|
30
|
+
* Called when cart changes (for persistence or sync)
|
|
31
|
+
*/
|
|
32
|
+
onCartChange?: (cart: Cart) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Called when navigating to a product
|
|
35
|
+
*/
|
|
36
|
+
onNavigateToProduct?: (productId: string) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Called when navigating to checkout
|
|
39
|
+
*/
|
|
40
|
+
onNavigateToCheckout?: () => void;
|
|
41
|
+
/**
|
|
42
|
+
* Called when auth is required
|
|
43
|
+
*/
|
|
44
|
+
onAuthRequired?: () => void;
|
|
45
|
+
};
|
|
46
|
+
export type UseSimpleCartReturn = {
|
|
47
|
+
/**
|
|
48
|
+
* Current cart state
|
|
49
|
+
*/
|
|
50
|
+
cart: Cart;
|
|
51
|
+
/**
|
|
52
|
+
* Update cart directly (for external sync)
|
|
53
|
+
*/
|
|
54
|
+
setCart: React.Dispatch<React.SetStateAction<Cart>>;
|
|
55
|
+
/**
|
|
56
|
+
* Clear all items from cart
|
|
57
|
+
*/
|
|
58
|
+
clearCart: () => void;
|
|
59
|
+
/**
|
|
60
|
+
* Remove a specific item from cart
|
|
61
|
+
*/
|
|
62
|
+
removeItem: (productId: string) => void;
|
|
63
|
+
/**
|
|
64
|
+
* Update quantity for a specific item
|
|
65
|
+
*/
|
|
66
|
+
updateQuantity: (productId: string, quantity: number) => void;
|
|
67
|
+
/**
|
|
68
|
+
* Ready-to-use callbacks for EchoProvider
|
|
69
|
+
*/
|
|
70
|
+
callbacks: EchoCallbacks;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Simple cart management hook for quick Echo SDK integration
|
|
74
|
+
*/
|
|
75
|
+
export declare function useSimpleCart(options?: UseSimpleCartOptions): UseSimpleCartReturn;
|
|
76
|
+
export default useSimpleCart;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* useSimpleCart - Ready-to-use cart management hook
|
|
4
|
+
*
|
|
5
|
+
* Provides a minimal cart implementation for quick SDK integration.
|
|
6
|
+
* For production apps, you'll likely want to replace this with your own cart logic.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* import { EchoProvider, EchoChat, useSimpleCart } from '@getecho-ai/react-native-sdk';
|
|
11
|
+
*
|
|
12
|
+
* function App() {
|
|
13
|
+
* const { cart, callbacks } = useSimpleCart();
|
|
14
|
+
*
|
|
15
|
+
* return (
|
|
16
|
+
* <EchoProvider config={{ apiKey: 'your-key', callbacks }}>
|
|
17
|
+
* <YourApp cart={cart} />
|
|
18
|
+
* <EchoChat />
|
|
19
|
+
* </EchoProvider>
|
|
20
|
+
* );
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.useSimpleCart = useSimpleCart;
|
|
26
|
+
const react_1 = require("react");
|
|
27
|
+
const DEFAULT_CART = {
|
|
28
|
+
items: [],
|
|
29
|
+
itemCount: 0,
|
|
30
|
+
total: 0,
|
|
31
|
+
currency: "TRY",
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Simple cart management hook for quick Echo SDK integration
|
|
35
|
+
*/
|
|
36
|
+
function useSimpleCart(options = {}) {
|
|
37
|
+
const { initialCart = DEFAULT_CART, onCartChange, onNavigateToProduct, onNavigateToCheckout, onAuthRequired, } = options;
|
|
38
|
+
const [cart, setCart] = (0, react_1.useState)(initialCart);
|
|
39
|
+
const updateCart = (0, react_1.useCallback)((newCart) => {
|
|
40
|
+
setCart(newCart);
|
|
41
|
+
onCartChange?.(newCart);
|
|
42
|
+
}, [onCartChange]);
|
|
43
|
+
const clearCart = (0, react_1.useCallback)(() => {
|
|
44
|
+
updateCart(DEFAULT_CART);
|
|
45
|
+
}, [updateCart]);
|
|
46
|
+
const removeItem = (0, react_1.useCallback)((productId) => {
|
|
47
|
+
setCart((prev) => {
|
|
48
|
+
const newItems = prev.items.filter((item) => item.productId !== productId);
|
|
49
|
+
const newCart = calculateCartTotals(newItems, prev.currency);
|
|
50
|
+
onCartChange?.(newCart);
|
|
51
|
+
return newCart;
|
|
52
|
+
});
|
|
53
|
+
}, [onCartChange]);
|
|
54
|
+
const updateQuantity = (0, react_1.useCallback)((productId, quantity) => {
|
|
55
|
+
if (quantity <= 0) {
|
|
56
|
+
removeItem(productId);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
setCart((prev) => {
|
|
60
|
+
const newItems = prev.items.map((item) => item.productId === productId ? { ...item, quantity } : item);
|
|
61
|
+
const newCart = calculateCartTotals(newItems, prev.currency);
|
|
62
|
+
onCartChange?.(newCart);
|
|
63
|
+
return newCart;
|
|
64
|
+
});
|
|
65
|
+
}, [onCartChange, removeItem]);
|
|
66
|
+
// Echo SDK callbacks
|
|
67
|
+
const onAddToCart = (0, react_1.useCallback)(async (product, quantity = 1) => {
|
|
68
|
+
setCart((prev) => {
|
|
69
|
+
const existingIndex = prev.items.findIndex((item) => item.productId === product.id);
|
|
70
|
+
let newItems;
|
|
71
|
+
if (existingIndex >= 0) {
|
|
72
|
+
// Update existing item quantity
|
|
73
|
+
newItems = prev.items.map((item, index) => index === existingIndex
|
|
74
|
+
? { ...item, quantity: item.quantity + quantity }
|
|
75
|
+
: item);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
// Add new item
|
|
79
|
+
const newItem = {
|
|
80
|
+
productId: product.id,
|
|
81
|
+
quantity,
|
|
82
|
+
product,
|
|
83
|
+
};
|
|
84
|
+
newItems = [...prev.items, newItem];
|
|
85
|
+
}
|
|
86
|
+
const newCart = calculateCartTotals(newItems, product.currency || prev.currency);
|
|
87
|
+
onCartChange?.(newCart);
|
|
88
|
+
return newCart;
|
|
89
|
+
});
|
|
90
|
+
// Return success with updated count (we calculate it here for immediate response)
|
|
91
|
+
return {
|
|
92
|
+
success: true,
|
|
93
|
+
cartItemCount: cart.itemCount + quantity,
|
|
94
|
+
};
|
|
95
|
+
}, [cart.itemCount, onCartChange]);
|
|
96
|
+
const onGetCart = (0, react_1.useCallback)(async () => {
|
|
97
|
+
return {
|
|
98
|
+
success: true,
|
|
99
|
+
cart,
|
|
100
|
+
};
|
|
101
|
+
}, [cart]);
|
|
102
|
+
const callbacks = {
|
|
103
|
+
onAddToCart,
|
|
104
|
+
onGetCart,
|
|
105
|
+
onNavigateToProduct,
|
|
106
|
+
onNavigateToCheckout,
|
|
107
|
+
onAuthRequired,
|
|
108
|
+
};
|
|
109
|
+
return {
|
|
110
|
+
cart,
|
|
111
|
+
setCart,
|
|
112
|
+
clearCart,
|
|
113
|
+
removeItem,
|
|
114
|
+
updateQuantity,
|
|
115
|
+
callbacks,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Calculate cart totals from items
|
|
120
|
+
*/
|
|
121
|
+
function calculateCartTotals(items, currency) {
|
|
122
|
+
const itemCount = items.reduce((sum, item) => sum + item.quantity, 0);
|
|
123
|
+
const total = items.reduce((sum, item) => {
|
|
124
|
+
const price = item.product?.priceAmount || 0;
|
|
125
|
+
return sum + price * item.quantity;
|
|
126
|
+
}, 0);
|
|
127
|
+
return {
|
|
128
|
+
items,
|
|
129
|
+
itemCount,
|
|
130
|
+
total,
|
|
131
|
+
currency: currency || "TRY",
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
exports.default = useSimpleCart;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Echo React Native SDK
|
|
3
|
+
*
|
|
4
|
+
* AI-powered chat and e-commerce SDK for React Native apps.
|
|
5
|
+
*
|
|
6
|
+
* @example Quick Start (with built-in cart)
|
|
7
|
+
* ```tsx
|
|
8
|
+
* import { EchoProvider, EchoChat, useSimpleCart } from '@getecho-ai/react-native-sdk';
|
|
9
|
+
*
|
|
10
|
+
* function App() {
|
|
11
|
+
* const { callbacks } = useSimpleCart();
|
|
12
|
+
*
|
|
13
|
+
* return (
|
|
14
|
+
* <EchoProvider config={{ apiKey: 'your-key', callbacks }}>
|
|
15
|
+
* <YourApp />
|
|
16
|
+
* <EchoChat />
|
|
17
|
+
* </EchoProvider>
|
|
18
|
+
* );
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @example Production Setup (custom cart)
|
|
23
|
+
* ```tsx
|
|
24
|
+
* import { EchoProvider, EchoChat } from '@getecho-ai/react-native-sdk';
|
|
25
|
+
*
|
|
26
|
+
* function App() {
|
|
27
|
+
* return (
|
|
28
|
+
* <EchoProvider
|
|
29
|
+
* config={{
|
|
30
|
+
* apiKey: 'your-api-key',
|
|
31
|
+
* callbacks: {
|
|
32
|
+
* onAddToCart: async (product, quantity) => {
|
|
33
|
+
* // Your add to cart logic
|
|
34
|
+
* return { success: true, cartItemCount: 5 };
|
|
35
|
+
* },
|
|
36
|
+
* onGetCart: async () => {
|
|
37
|
+
* // Return your cart
|
|
38
|
+
* return { success: true, cart: yourCart };
|
|
39
|
+
* },
|
|
40
|
+
* }
|
|
41
|
+
* }}
|
|
42
|
+
* >
|
|
43
|
+
* <YourApp />
|
|
44
|
+
* <EchoChat />
|
|
45
|
+
* </EchoProvider>
|
|
46
|
+
* );
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export { default as callbackManager } from "./bridge/CallbackManager";
|
|
51
|
+
export { default as webViewBridge } from "./bridge/WebViewBridge";
|
|
52
|
+
export { EchoChat } from "./components/EchoChat";
|
|
53
|
+
export { EchoChatButton } from "./components/EchoChatButton";
|
|
54
|
+
export { EchoChatModal } from "./components/EchoChatModal";
|
|
55
|
+
export { EchoProvider, useEcho } from "./components/EchoProvider";
|
|
56
|
+
export type { UseSimpleCartOptions, UseSimpleCartReturn, } from "./hooks/useSimpleCart";
|
|
57
|
+
export { useSimpleCart } from "./hooks/useSimpleCart";
|
|
58
|
+
export type { ActionType, AddToCartResult, BridgeMessage, BridgeMessageType, CallbackResult, Cart, CartItem, ChatMessage, EchoCallbacks, EchoConfig, EchoTheme, GetCartResult, MessageAction, Product, UISettings, } from "./types";
|
|
59
|
+
export { getLocalhostUrl, resolveApiUrl } from "./utils/resolveApiUrl";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Echo React Native SDK
|
|
4
|
+
*
|
|
5
|
+
* AI-powered chat and e-commerce SDK for React Native apps.
|
|
6
|
+
*
|
|
7
|
+
* @example Quick Start (with built-in cart)
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { EchoProvider, EchoChat, useSimpleCart } from '@getecho-ai/react-native-sdk';
|
|
10
|
+
*
|
|
11
|
+
* function App() {
|
|
12
|
+
* const { callbacks } = useSimpleCart();
|
|
13
|
+
*
|
|
14
|
+
* return (
|
|
15
|
+
* <EchoProvider config={{ apiKey: 'your-key', callbacks }}>
|
|
16
|
+
* <YourApp />
|
|
17
|
+
* <EchoChat />
|
|
18
|
+
* </EchoProvider>
|
|
19
|
+
* );
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @example Production Setup (custom cart)
|
|
24
|
+
* ```tsx
|
|
25
|
+
* import { EchoProvider, EchoChat } from '@getecho-ai/react-native-sdk';
|
|
26
|
+
*
|
|
27
|
+
* function App() {
|
|
28
|
+
* return (
|
|
29
|
+
* <EchoProvider
|
|
30
|
+
* config={{
|
|
31
|
+
* apiKey: 'your-api-key',
|
|
32
|
+
* callbacks: {
|
|
33
|
+
* onAddToCart: async (product, quantity) => {
|
|
34
|
+
* // Your add to cart logic
|
|
35
|
+
* return { success: true, cartItemCount: 5 };
|
|
36
|
+
* },
|
|
37
|
+
* onGetCart: async () => {
|
|
38
|
+
* // Return your cart
|
|
39
|
+
* return { success: true, cart: yourCart };
|
|
40
|
+
* },
|
|
41
|
+
* }
|
|
42
|
+
* }}
|
|
43
|
+
* >
|
|
44
|
+
* <YourApp />
|
|
45
|
+
* <EchoChat />
|
|
46
|
+
* </EchoProvider>
|
|
47
|
+
* );
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
52
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
53
|
+
};
|
|
54
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
|
+
exports.resolveApiUrl = exports.getLocalhostUrl = exports.useSimpleCart = exports.useEcho = exports.EchoProvider = exports.EchoChatModal = exports.EchoChatButton = exports.EchoChat = exports.webViewBridge = exports.callbackManager = void 0;
|
|
56
|
+
var CallbackManager_1 = require("./bridge/CallbackManager");
|
|
57
|
+
Object.defineProperty(exports, "callbackManager", { enumerable: true, get: function () { return __importDefault(CallbackManager_1).default; } });
|
|
58
|
+
// Bridge utilities (advanced usage)
|
|
59
|
+
var WebViewBridge_1 = require("./bridge/WebViewBridge");
|
|
60
|
+
Object.defineProperty(exports, "webViewBridge", { enumerable: true, get: function () { return __importDefault(WebViewBridge_1).default; } });
|
|
61
|
+
var EchoChat_1 = require("./components/EchoChat");
|
|
62
|
+
Object.defineProperty(exports, "EchoChat", { enumerable: true, get: function () { return EchoChat_1.EchoChat; } });
|
|
63
|
+
var EchoChatButton_1 = require("./components/EchoChatButton");
|
|
64
|
+
Object.defineProperty(exports, "EchoChatButton", { enumerable: true, get: function () { return EchoChatButton_1.EchoChatButton; } });
|
|
65
|
+
var EchoChatModal_1 = require("./components/EchoChatModal");
|
|
66
|
+
Object.defineProperty(exports, "EchoChatModal", { enumerable: true, get: function () { return EchoChatModal_1.EchoChatModal; } });
|
|
67
|
+
// Components
|
|
68
|
+
var EchoProvider_1 = require("./components/EchoProvider");
|
|
69
|
+
Object.defineProperty(exports, "EchoProvider", { enumerable: true, get: function () { return EchoProvider_1.EchoProvider; } });
|
|
70
|
+
Object.defineProperty(exports, "useEcho", { enumerable: true, get: function () { return EchoProvider_1.useEcho; } });
|
|
71
|
+
// Hooks
|
|
72
|
+
var useSimpleCart_1 = require("./hooks/useSimpleCart");
|
|
73
|
+
Object.defineProperty(exports, "useSimpleCart", { enumerable: true, get: function () { return useSimpleCart_1.useSimpleCart; } });
|
|
74
|
+
// Utilities
|
|
75
|
+
var resolveApiUrl_1 = require("./utils/resolveApiUrl");
|
|
76
|
+
Object.defineProperty(exports, "getLocalhostUrl", { enumerable: true, get: function () { return resolveApiUrl_1.getLocalhostUrl; } });
|
|
77
|
+
Object.defineProperty(exports, "resolveApiUrl", { enumerable: true, get: function () { return resolveApiUrl_1.resolveApiUrl; } });
|