1 | 'use client'; // Indicates this is a client-side component |
2 | import OneSDK from '@frankieone/one-sdk'; |
3 | import { useEffect, useRef, useState } from 'react'; |
4 | |
5 | // Assign environment variables to constants for customer ID, API key, and base URL |
6 | const CUSTOMER_ID = import.meta.env.VITE_CUSTOMER_ID; |
7 | const API_KEY = import.meta.env.VITE_API_KEY; |
8 | const FRANKIE_BASE_URL = import.meta.env.VITE_FRANKIE_BASE_URL; |
9 | |
10 | /** |
11 | * OneSDKHandler component initializes and manages the FrankieOne SDK instance. |
12 | * @param {Object} config - Configuration object to override default SDK setup. |
13 | * @returns {Object} - Returns the SDK instance, error, and loading state. |
14 | */ |
15 | const OneSDKHandler = ({ config }) => { |
16 | // State hooks for managing SDK instance, error, and loading status |
17 | console.log('???'); |
18 | const [oneSDKInstance, setOneSDKInstance] = useState(null); |
19 | const [error, setError] = useState(null); |
20 | const [loading, setLoading] = useState(false); |
21 | |
22 | // useRef to track SDK initialization and prevent reinitialization |
23 | const initializedRef = useRef(false); |
24 | |
25 | /** |
26 | * Generates a base64-encoded token for authorization. |
27 | * @returns {string} - Base64-encoded authorization string. |
28 | */ |
29 | const parseAuthToken = () => btoa(`${CUSTOMER_ID}:${API_KEY}`); |
30 | |
31 | /** |
32 | * Fetches a session token from the backend by authenticating |
33 | * with the FrankieOne API. |
34 | * @returns {Object|null} - Returns the session token or null on error. |
35 | */ |
36 | const generateToken = async () => { |
37 | try { |
38 | const tokenResponse = await fetch( |
39 | `${FRANKIE_BASE_URL}/auth/v2/machine-session`, |
40 | { |
41 | method: 'POST', |
42 | headers: { |
43 | authorization: `machine ${parseAuthToken()}`, |
44 | 'Content-Type': 'application/json', |
45 | }, |
46 | body: JSON.stringify({ |
47 | permissions: { |
48 | preset: 'one-sdk', |
49 | reference: `demo-${new Date().toISOString()}`, // Optional: Custom reference |
50 | }, |
51 | }), |
52 | } |
53 | ); |
54 | return await tokenResponse.json(); // Return the parsed response as JSON |
55 | } catch (error) { |
56 | setError(error.message); // Capture error message in state |
57 | return null; // Return null in case of error |
58 | } |
59 | }; |
60 | |
61 | /** |
62 | * Initializes the OneSDK instance using the provided token and configuration. |
63 | */ |
64 | const generateOneSDKInstance = async () => { |
65 | setLoading(true); // Set loading to true while SDK is initializing |
66 | |
67 | // Fetch token from the backend |
68 | const tokenSession = await generateToken(); |
69 | if (!tokenSession) return; // Exit if no valid token is fetched |
70 | |
71 | // Default SDK configuration, can be overridden by the `config` prop |
72 | const defaultConfig = { |
73 | mode: 'development', // Set mode to development (adjust as needed) |
74 | recipe: { |
75 | form: { |
76 | provider: { |
77 | name: 'react', |
78 | googleApiKey: import.meta.env.VITE_GOOGLE_PLACES_API_KEY, |
79 | }, |
80 | }, |
81 | }, |
82 | }; |
83 | |
84 | const SDKConfig = config || defaultConfig; // Use the passed config or the default one |
85 | |
86 | try { |
87 | // Initialize the OneSDK with the fetched token and configuration |
88 | const oneSDKInit = await OneSDK({ |
89 | session: tokenSession, |
90 | ...SDKConfig, |
91 | }); |
92 | setOneSDKInstance(oneSDKInit); // Set SDK instance in state |
93 | } catch (error) { |
94 | setError(error.message); // Capture initialization errors |
95 | } finally { |
96 | setLoading(false); // Reset loading state after initialization |
97 | } |
98 | }; |
99 | |
100 | /** |
101 | * useEffect hook to initialize the SDK once on component mount. |
102 | * Prevents reinitialization on re-render using `initializedRef`. |
103 | */ |
104 | useEffect(() => { |
105 | if (!initializedRef.current) { |
106 | generateOneSDKInstance(); // Initialize the SDK instance |
107 | initializedRef.current = true; // Set to true to prevent re-initialization |
108 | } |
109 | }, [config]); // Re-run if the config prop changes |
110 | |
111 | // Return SDK instance, error message (if any), and loading state |
112 | return { |
113 | oneSDKInstance, |
114 | error, |
115 | loading, |
116 | }; |
117 | }; |
118 | |
119 | export default OneSDKHandler; |