@tagadapay/plugin-sdk 2.3.0 → 2.3.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/README.md CHANGED
@@ -15,6 +15,7 @@ A comprehensive React SDK for building plugins on the TagadaPay platform. Create
15
15
  ### Plugin Development
16
16
 
17
17
  - **[Plugin Configuration](./docs/PLUGIN_CONFIG.md)** - How to access store context, config, and branding
18
+ - **[Initialization Modes](#-initialization-modes)** - Choose between blocking and non-blocking initialization
18
19
  - **[Google Autocomplete](./docs/README-google-autocomplete.md)** - Address autocomplete with Google Places API
19
20
  - **[ISO Data](./docs/README-iso-data.md)** - Country and region data with Google integration
20
21
 
@@ -164,6 +165,95 @@ function App() {
164
165
  export default App;
165
166
  ```
166
167
 
168
+ ## 🚀 Initialization Modes
169
+
170
+ The TagadaProvider supports two initialization modes to give you control over when your components render:
171
+
172
+ ### Non-Blocking Mode (Default - Recommended)
173
+
174
+ ```tsx
175
+ <TagadaProvider>
176
+ {/* Children render immediately after config loads */}
177
+ <YourApp />
178
+ </TagadaProvider>
179
+
180
+ // OR explicitly
181
+ <TagadaProvider blockUntilSessionReady={false}>
182
+ <YourApp />
183
+ </TagadaProvider>
184
+ ```
185
+
186
+ **Flow:**
187
+ 1. **Phase 1 & 2** ✅ Plugin config loads → Children render immediately
188
+ 2. **Phase 3** 🔄 Session initialization runs in background
189
+ 3. **API calls** 🔄 Hooks automatically wait for session to be ready
190
+
191
+ **Benefits:**
192
+ - ⚡ **Faster rendering** - UI appears immediately
193
+ - 🎯 **Better UX** - Show loading states while session initializes
194
+ - 🔄 **Automatic waiting** - Hooks handle session timing for you
195
+
196
+ ### Blocking Mode (Legacy Behavior)
197
+
198
+ ```tsx
199
+ <TagadaProvider blockUntilSessionReady={true}>
200
+ {/* Children render only after ALL initialization completes */}
201
+ <YourApp />
202
+ </TagadaProvider>
203
+ ```
204
+
205
+ **Flow:**
206
+ 1. **All Phases** ⏳ Config + Session must complete before children render
207
+ 2. **API calls** ✅ Work immediately (no waiting needed)
208
+
209
+ **Use when:**
210
+ - 🔄 **Migrating** from older SDK versions
211
+ - 🎯 **Simple apps** that don't need progressive loading
212
+
213
+ ### Console Logs
214
+
215
+ The SDK logs help you understand which mode you're using:
216
+
217
+ **Non-blocking mode:**
218
+ ```
219
+ ✅ Phase 1 & 2 Complete - Plugin config loaded
220
+ 🚀 Non-blocking mode: Children can now render - Phase 3 will continue in background
221
+ 🔄 [useCheckout] Waiting for session initialization to complete...
222
+ ✅ Phase 3 Complete - Session initialization completed successfully
223
+ ✅ [useCheckout] Session initialized, proceeding with checkout init
224
+ ```
225
+
226
+ **Blocking mode:**
227
+ ```
228
+ ✅ Phase 1 & 2 Complete - Plugin config loaded
229
+ ⏳ Blocking mode: Children will render after Phase 3 completes
230
+ ✅ Phase 3 Complete - Session initialization completed successfully
231
+ ```
232
+
233
+ ### TagadaProvider API
234
+
235
+ ```tsx
236
+ interface TagadaProviderProps {
237
+ children: ReactNode;
238
+ environment?: 'local' | 'development' | 'staging' | 'production';
239
+ customApiConfig?: Partial<EnvironmentConfig>;
240
+ debugMode?: boolean;
241
+ localConfig?: string; // LOCAL DEV ONLY: Override config variant
242
+ blockUntilSessionReady?: boolean; // Default: false
243
+ }
244
+ ```
245
+
246
+ | Prop | Type | Default | Description |
247
+ |------|------|---------|-------------|
248
+ | `children` | `ReactNode` | - | Your plugin components |
249
+ | `environment` | `string` | auto-detect | Override environment detection |
250
+ | `customApiConfig` | `object` | - | Custom API configuration |
251
+ | `debugMode` | `boolean` | auto (false in prod) | Enable debug features |
252
+ | `localConfig` | `string` | `'default'` | Config variant for local dev |
253
+ | `blockUntilSessionReady` | `boolean` | `false` | Use legacy blocking behavior |
254
+
255
+ > **Version Compatibility:** The `blockUntilSessionReady` option was added in v2.3.0. For older versions, the blocking behavior was the default and only option.
256
+
167
257
  ### Development vs Production
168
258
 
169
259
  | Environment | Store/Account ID | Deployment Config | How it Works |
@@ -1,7 +1,6 @@
1
1
  import { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import { useCurrency } from '../hooks/useCurrency';
3
3
  import { useTagadaContext } from '../providers/TagadaProvider';
4
- import { collectTrackingData } from '../utils/trackingUtils';
5
4
  import { usePluginConfig } from './usePluginConfig';
6
5
  export function useCheckout(options = {}) {
7
6
  const { apiService, updateCheckoutDebugData, refreshCoordinator, currency, isSessionInitialized } = useTagadaContext();
@@ -78,13 +77,9 @@ export function useCheckout(options = {}) {
78
77
  setIsLoading(true);
79
78
  setError(null);
80
79
  try {
81
- // Collect tracking data
82
- const trackingData = await collectTrackingData();
83
- // Enhanced customerMetadata with tracking data
80
+ // Enhanced customerMetadata without tracking data
84
81
  const enhancedCustomerMetadata = {
85
82
  ...params.customerMetadata,
86
- localStorage: trackingData.localStorageData,
87
- cookies: trackingData.trackingCookiesData,
88
83
  };
89
84
  const requestBody = {
90
85
  ...params,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tagadapay/plugin-sdk",
3
- "version": "2.3.0",
3
+ "version": "2.3.2",
4
4
  "description": "Modern React SDK for building Tagada Pay plugins",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,24 +0,0 @@
1
- export interface TrackingData {
2
- trackingCookiesData: Record<string, string>;
3
- localStorageData: Record<string, string>;
4
- }
5
- /**
6
- * Define pixel tracking cookie patterns for various platforms
7
- */
8
- export declare const trackingCookiePatterns: RegExp[];
9
- /**
10
- * Function to get cookies with retry logic
11
- */
12
- export declare const getCookiesWithRetry: (maxRetries?: number, delay?: number) => Promise<string[]>;
13
- /**
14
- * Collect localStorage data as dictionary
15
- */
16
- export declare const getLocalStorageData: () => Record<string, string>;
17
- /**
18
- * Collect tracking cookies data based on defined patterns
19
- */
20
- export declare const getTrackingCookiesData: () => Promise<Record<string, string>>;
21
- /**
22
- * Collect all tracking data (localStorage and cookies)
23
- */
24
- export declare const collectTrackingData: () => Promise<TrackingData>;
@@ -1,172 +0,0 @@
1
- /**
2
- * Define pixel tracking cookie patterns for various platforms
3
- */
4
- export const trackingCookiePatterns = [
5
- // Meta/Facebook pixels
6
- /^_fbp/,
7
- /^_fbc/,
8
- /^fr$/,
9
- /^_fbq/,
10
- /^fbq/,
11
- /^sb$/,
12
- // Google Analytics & Ads
13
- /^_ga/,
14
- /^_gid/,
15
- /^_gcl_au/,
16
- /^_gac_/,
17
- /^_gtag/,
18
- /^_gat/,
19
- /^_dc_gtm_/,
20
- /^_gtm/,
21
- // Google Ads
22
- /^_gcl_/,
23
- /^_gclid/,
24
- /^_gclsrc/,
25
- // Snapchat
26
- /^_scid/,
27
- /^_sctr/,
28
- /^_schn/,
29
- /^_scpx/,
30
- // TikTok
31
- /^_ttp/,
32
- /^_tt_enable_cookie/,
33
- /^_ttclid/,
34
- /^_tta/,
35
- // Pinterest
36
- /^_pin/,
37
- /^_pinterest_/,
38
- /^_pinid/,
39
- // Twitter/X
40
- /^_twitter/,
41
- /^_twid/,
42
- /^muc_ads/,
43
- // LinkedIn
44
- /^_li/,
45
- /^AnalyticsSyncHistory/,
46
- /^bcookie/,
47
- /^bscookie/,
48
- // Microsoft/Bing
49
- /^_uetsid/,
50
- /^_uetvid/,
51
- /^MUID/,
52
- /^_msdcs/,
53
- // Amazon
54
- /^ad-id/,
55
- /^ad-privacy/,
56
- // CVG tracking
57
- /^__cvg_uid/,
58
- /^__cvg_sid/,
59
- /^__cvg_session/,
60
- // Shopify tracking
61
- /^_shopify_y/,
62
- /^_shopify_s/,
63
- /^_shopify_ga/,
64
- /^_shopify_ga_/,
65
- /^_shopify_sa_p/,
66
- /^_shopify_sa_t/,
67
- // General tracking
68
- /^_awc/,
69
- /^_aw_/,
70
- /^utm_/,
71
- /^_clck/,
72
- /^_clsk/,
73
- ];
74
- /**
75
- * Function to get cookies with retry logic
76
- */
77
- export const getCookiesWithRetry = async (maxRetries = 3, delay = 100) => {
78
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
79
- try {
80
- const cookies = document.cookie.split('; ');
81
- if (cookies.length > 0 && cookies[0] !== '') {
82
- return cookies;
83
- }
84
- // If no cookies found, wait and retry
85
- if (attempt < maxRetries) {
86
- console.log(`Cookie collection attempt ${attempt} failed, retrying in ${delay}ms...`);
87
- await new Promise((resolve) => setTimeout(resolve, delay));
88
- }
89
- }
90
- catch (error) {
91
- console.warn(`Cookie collection attempt ${attempt} failed:`, error);
92
- if (attempt < maxRetries) {
93
- await new Promise((resolve) => setTimeout(resolve, delay));
94
- }
95
- }
96
- }
97
- return [];
98
- };
99
- /**
100
- * Collect localStorage data as dictionary
101
- */
102
- export const getLocalStorageData = () => {
103
- const localStorageData = {};
104
- try {
105
- for (let i = 0; i < localStorage.length; i++) {
106
- const key = localStorage.key(i);
107
- if (key) {
108
- localStorageData[key] = localStorage.getItem(key) || '';
109
- }
110
- }
111
- }
112
- catch (error) {
113
- console.warn('Failed to read localStorage:', error);
114
- }
115
- return localStorageData;
116
- };
117
- /**
118
- * Collect tracking cookies data based on defined patterns
119
- */
120
- export const getTrackingCookiesData = async () => {
121
- const trackingCookiesData = {};
122
- try {
123
- // Get cookies with retry logic
124
- const cookies = await getCookiesWithRetry();
125
- if (cookies.length === 0) {
126
- console.warn('No cookies found after retry attempts');
127
- }
128
- else {
129
- console.log(`Successfully collected ${cookies.length} cookies`);
130
- }
131
- cookies.forEach((cookie) => {
132
- const [key, ...valueParts] = cookie.split('=');
133
- const value = valueParts.join('='); // Handle values that might contain =
134
- if (key && trackingCookiePatterns.some((pattern) => pattern.test(key))) {
135
- try {
136
- trackingCookiesData[key] = decodeURIComponent(value || '');
137
- }
138
- catch (error) {
139
- // If decoding fails, use raw value
140
- trackingCookiesData[key] = value || '';
141
- }
142
- }
143
- });
144
- // Log specific cookies we're looking for
145
- const importantCookies = ['_shopify_y', '__cvg_uid', '_fbp', '_ga'];
146
- importantCookies.forEach((cookieName) => {
147
- if (trackingCookiesData[cookieName]) {
148
- console.log(`Found ${cookieName}:`, trackingCookiesData[cookieName]);
149
- }
150
- else {
151
- console.log(`Missing ${cookieName} cookie`);
152
- }
153
- });
154
- }
155
- catch (error) {
156
- console.warn('Failed to read tracking cookies:', error);
157
- }
158
- return trackingCookiesData;
159
- };
160
- /**
161
- * Collect all tracking data (localStorage and cookies)
162
- */
163
- export const collectTrackingData = async () => {
164
- const [localStorageData, trackingCookiesData] = await Promise.all([
165
- Promise.resolve(getLocalStorageData()),
166
- getTrackingCookiesData(),
167
- ]);
168
- return {
169
- localStorageData,
170
- trackingCookiesData,
171
- };
172
- };