@tagadapay/plugin-sdk 2.8.10 → 3.0.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.
Files changed (51) hide show
  1. package/README.md +14 -14
  2. package/dist/index.js +1 -1
  3. package/dist/react/hooks/usePluginConfig.d.ts +1 -0
  4. package/dist/react/hooks/usePluginConfig.js +69 -18
  5. package/dist/react/providers/TagadaProvider.js +1 -4
  6. package/dist/v2/core/client.d.ts +18 -0
  7. package/dist/v2/core/client.js +45 -0
  8. package/dist/v2/core/config/environment.d.ts +8 -0
  9. package/dist/v2/core/config/environment.js +18 -0
  10. package/dist/v2/core/funnelClient.d.ts +84 -0
  11. package/dist/v2/core/funnelClient.js +252 -0
  12. package/dist/v2/core/index.d.ts +2 -0
  13. package/dist/v2/core/index.js +3 -0
  14. package/dist/v2/core/resources/apiClient.js +1 -1
  15. package/dist/v2/core/resources/funnel.d.ts +1 -0
  16. package/dist/v2/core/resources/offers.d.ts +182 -8
  17. package/dist/v2/core/resources/offers.js +25 -0
  18. package/dist/v2/core/resources/products.d.ts +5 -0
  19. package/dist/v2/core/resources/products.js +15 -1
  20. package/dist/v2/core/types.d.ts +1 -0
  21. package/dist/v2/core/utils/funnelQueryKeys.d.ts +23 -0
  22. package/dist/v2/core/utils/funnelQueryKeys.js +23 -0
  23. package/dist/v2/core/utils/index.d.ts +2 -0
  24. package/dist/v2/core/utils/index.js +2 -0
  25. package/dist/v2/core/utils/pluginConfig.js +44 -32
  26. package/dist/v2/core/utils/sessionStorage.d.ts +20 -0
  27. package/dist/v2/core/utils/sessionStorage.js +39 -0
  28. package/dist/v2/index.d.ts +4 -2
  29. package/dist/v2/index.js +1 -1
  30. package/dist/v2/react/components/DebugDrawer.js +99 -2
  31. package/dist/v2/react/hooks/__examples__/FunnelContextExample.d.ts +3 -0
  32. package/dist/v2/react/hooks/__examples__/FunnelContextExample.js +4 -3
  33. package/dist/v2/react/hooks/useClubOffers.d.ts +2 -2
  34. package/dist/v2/react/hooks/useFunnel.d.ts +27 -39
  35. package/dist/v2/react/hooks/useFunnel.js +22 -659
  36. package/dist/v2/react/hooks/useFunnelLegacy.d.ts +52 -0
  37. package/dist/v2/react/hooks/useFunnelLegacy.js +733 -0
  38. package/dist/v2/react/hooks/useOfferQuery.d.ts +109 -0
  39. package/dist/v2/react/hooks/useOfferQuery.js +483 -0
  40. package/dist/v2/react/hooks/useOffersQuery.d.ts +9 -75
  41. package/dist/v2/react/hooks/useProductsQuery.d.ts +1 -0
  42. package/dist/v2/react/hooks/useProductsQuery.js +10 -6
  43. package/dist/v2/react/index.d.ts +8 -4
  44. package/dist/v2/react/index.js +4 -2
  45. package/dist/v2/react/providers/TagadaProvider.d.ts +66 -5
  46. package/dist/v2/react/providers/TagadaProvider.js +120 -6
  47. package/dist/v2/standalone/index.d.ts +20 -0
  48. package/dist/v2/standalone/index.js +22 -0
  49. package/dist/v2/vue/index.d.ts +6 -0
  50. package/dist/v2/vue/index.js +10 -0
  51. package/package.json +6 -1
@@ -2,6 +2,7 @@
2
2
  * Plugin Configuration Utility Functions
3
3
  * Pure functions for plugin configuration management
4
4
  */
5
+ import { isLocalEnvironment } from '../config/environment';
5
6
  import { resolveEnvValue } from './env';
6
7
  /**
7
8
  * Load local development configuration
@@ -15,13 +16,8 @@ const loadLocalDevConfig = async (configVariant = 'default') => {
15
16
  return null;
16
17
  }
17
18
  // Only try to load local config in TRUE local development (not deployed CDN instances)
18
- // Exclude CDN subdomains (e.g., instance-id.cdn.localhost) by checking for 'cdn.' prefix
19
- const isLocalDev = typeof window !== 'undefined' &&
20
- (window.location.hostname === 'localhost' ||
21
- window.location.hostname === '127.0.0.1' ||
22
- window.location.hostname.includes('ngrok-free.app')) &&
23
- !window.location.hostname.includes('.cdn.');
24
- if (!isLocalDev) {
19
+ // Exclude CDN subdomains (e.g., instance-id.cdn.localhost)
20
+ if (!isLocalEnvironment(true)) {
25
21
  return null;
26
22
  }
27
23
  // Load local store/account config
@@ -99,28 +95,23 @@ const loadStaticResources = async () => {
99
95
  return null;
100
96
  }
101
97
  // Only try to load in TRUE local development (not deployed CDN instances)
102
- // Exclude CDN subdomains (e.g., instance-id.cdn.localhost) by checking for 'cdn.' prefix
103
- const isLocalDev = typeof window !== 'undefined' &&
104
- (window.location.hostname === 'localhost' ||
105
- window.location.hostname === '127.0.0.1' ||
106
- window.location.hostname.includes('ngrok-free.app')) &&
107
- !window.location.hostname.includes('.cdn.');
108
- if (!isLocalDev) {
98
+ // Exclude CDN subdomains (e.g., instance-id.cdn.localhost)
99
+ if (!isLocalEnvironment(true)) {
109
100
  return null;
110
101
  }
111
102
  // Load static resources file
112
- console.log('🛠️ Attempting to load /config/resources.static.json...');
103
+ console.log('🛠️ [V2] Attempting to load /config/resources.static.json...');
113
104
  const response = await fetch('/config/resources.static.json');
114
105
  if (!response.ok) {
115
- console.log('🛠️ resources.static.json not found or failed to load');
106
+ console.log('🛠️ [V2] resources.static.json not found or failed to load');
116
107
  return null;
117
108
  }
118
109
  const staticResources = await response.json();
119
- console.log('🛠️ ✅ Loaded local static resources:', staticResources);
110
+ console.log('🛠️ [V2] ✅ Loaded local static resources:', staticResources);
120
111
  return staticResources;
121
112
  }
122
113
  catch (error) {
123
- console.error('🛠️ ❌ Error loading static resources:', error);
114
+ console.error('🛠️ [V2] ❌ Error loading static resources:', error);
124
115
  return null;
125
116
  }
126
117
  };
@@ -180,41 +171,70 @@ const loadProductionConfig = async () => {
180
171
  * Handles local dev, production, and raw config
181
172
  */
182
173
  export const loadPluginConfig = async (configVariant = 'default', rawConfig) => {
174
+ console.log('🔧 [V2] loadPluginConfig called with variant:', configVariant);
183
175
  // Load static resources first (only in local dev)
184
176
  const staticResources = await loadStaticResources();
177
+ console.log('🔧 [V2] Static resources loaded:', {
178
+ hasStaticResources: !!staticResources,
179
+ staticResourcesKeys: staticResources ? Object.keys(staticResources) : [],
180
+ });
185
181
  // If raw config is provided, use it directly
186
182
  if (rawConfig) {
187
- return {
183
+ const result = {
188
184
  storeId: rawConfig.storeId,
189
185
  accountId: rawConfig.accountId,
190
186
  basePath: rawConfig.basePath ?? '/',
191
187
  config: rawConfig.config ?? {},
192
188
  staticResources: staticResources ?? undefined,
193
189
  };
190
+ console.log('🔧 [V2] Final config (raw):', {
191
+ hasStoreId: !!result.storeId,
192
+ hasStaticResources: !!result.staticResources,
193
+ staticResourcesKeys: result.staticResources ? Object.keys(result.staticResources) : [],
194
+ });
195
+ return result;
194
196
  }
195
197
  else {
196
198
  const rawConfig = await createRawPluginConfig();
197
199
  if (rawConfig) {
198
- return {
200
+ const result = {
199
201
  ...rawConfig,
200
202
  staticResources: staticResources ?? undefined,
201
203
  };
204
+ console.log('🔧 [V2] Final config (createRawPluginConfig):', {
205
+ hasStoreId: !!result.storeId,
206
+ hasStaticResources: !!result.staticResources,
207
+ staticResourcesKeys: result.staticResources ? Object.keys(result.staticResources) : [],
208
+ });
209
+ return result;
202
210
  }
203
211
  }
204
212
  // Try local development config
205
213
  const localConfig = await loadLocalDevConfig(configVariant);
206
214
  if (localConfig) {
207
- return {
215
+ const result = {
208
216
  ...localConfig,
209
217
  staticResources: staticResources ?? undefined,
210
218
  };
219
+ console.log('🔧 [V2] Final config (local):', {
220
+ hasStoreId: !!result.storeId,
221
+ hasStaticResources: !!result.staticResources,
222
+ staticResourcesKeys: result.staticResources ? Object.keys(result.staticResources) : [],
223
+ });
224
+ return result;
211
225
  }
212
226
  // Fall back to production config
213
227
  const productionConfig = await loadProductionConfig();
214
- return {
228
+ const result = {
215
229
  ...productionConfig,
216
230
  staticResources: staticResources ?? undefined,
217
231
  };
232
+ console.log('🔧 [V2] Final config (production):', {
233
+ hasStoreId: !!result.storeId,
234
+ hasStaticResources: !!result.staticResources,
235
+ staticResourcesKeys: result.staticResources ? Object.keys(result.staticResources) : [],
236
+ });
237
+ return result;
218
238
  };
219
239
  /**
220
240
  * Helper to load local config file for development (from /config directory)
@@ -223,11 +243,7 @@ export const loadPluginConfig = async (configVariant = 'default', rawConfig) =>
223
243
  export async function loadLocalConfig(configName = 'default', defaultConfig) {
224
244
  try {
225
245
  // Only load in localhost
226
- const isLocalhost = typeof window !== 'undefined' &&
227
- (window.location.hostname === 'localhost' ||
228
- window.location.hostname.includes('.localhost') ||
229
- window.location.hostname.includes('127.0.0.1'));
230
- if (!isLocalhost) {
246
+ if (!isLocalEnvironment()) {
231
247
  return null;
232
248
  }
233
249
  if (defaultConfig) {
@@ -267,11 +283,7 @@ export async function loadLocalConfig(configName = 'default', defaultConfig) {
267
283
  export async function createRawPluginConfig() {
268
284
  try {
269
285
  // Only run in true localhost - production should use meta tags
270
- const isLocalhost = typeof window !== 'undefined' &&
271
- (window.location.hostname === 'localhost' ||
272
- window.location.hostname.includes('.localhost') ||
273
- window.location.hostname.includes('127.0.0.1'));
274
- if (!isLocalhost) {
286
+ if (!isLocalEnvironment()) {
275
287
  console.log('[createRawPluginConfig] Not localhost, skipping - will use meta tags in production');
276
288
  return undefined;
277
289
  }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Session Storage Utilities - Core SDK (Framework-agnostic)
3
+ * Handles session persistence using browser cookies
4
+ */
5
+ /**
6
+ * Save funnel session ID to browser cookie
7
+ */
8
+ export declare function setFunnelSessionCookie(sessionId: string): void;
9
+ /**
10
+ * Retrieve funnel session ID from browser cookie
11
+ */
12
+ export declare function getFunnelSessionCookie(): string | undefined;
13
+ /**
14
+ * Clear funnel session cookie
15
+ */
16
+ export declare function clearFunnelSessionCookie(): void;
17
+ /**
18
+ * Check if a funnel session cookie exists
19
+ */
20
+ export declare function hasFunnelSessionCookie(): boolean;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Session Storage Utilities - Core SDK (Framework-agnostic)
3
+ * Handles session persistence using browser cookies
4
+ */
5
+ const FUNNEL_SESSION_COOKIE_NAME = 'tgd-funnel-session-id';
6
+ const SESSION_MAX_AGE = 30 * 24 * 60 * 60; // 30 days
7
+ /**
8
+ * Save funnel session ID to browser cookie
9
+ */
10
+ export function setFunnelSessionCookie(sessionId) {
11
+ if (typeof document === 'undefined')
12
+ return;
13
+ document.cookie = `${FUNNEL_SESSION_COOKIE_NAME}=${sessionId}; path=/; max-age=${SESSION_MAX_AGE}; SameSite=Lax`;
14
+ }
15
+ /**
16
+ * Retrieve funnel session ID from browser cookie
17
+ */
18
+ export function getFunnelSessionCookie() {
19
+ if (typeof document === 'undefined')
20
+ return undefined;
21
+ const cookie = document.cookie
22
+ .split('; ')
23
+ .find((row) => row.startsWith(`${FUNNEL_SESSION_COOKIE_NAME}=`));
24
+ return cookie ? cookie.split('=')[1] : undefined;
25
+ }
26
+ /**
27
+ * Clear funnel session cookie
28
+ */
29
+ export function clearFunnelSessionCookie() {
30
+ if (typeof document === 'undefined')
31
+ return;
32
+ document.cookie = `${FUNNEL_SESSION_COOKIE_NAME}=; path=/; max-age=0`;
33
+ }
34
+ /**
35
+ * Check if a funnel session cookie exists
36
+ */
37
+ export function hasFunnelSessionCookie() {
38
+ return !!getFunnelSessionCookie();
39
+ }
@@ -14,7 +14,7 @@ export * from './core/pathRemapping';
14
14
  export type { CheckoutData, CheckoutInitParams, CheckoutLineItem, CheckoutSession, CheckoutSessionPreview, Promotion } from './core/resources/checkout';
15
15
  export type { Order, OrderLineItem } from './core/utils/order';
16
16
  export type { PostPurchaseOffer, PostPurchaseOfferItem, PostPurchaseOfferSummary } from './core/resources/postPurchases';
17
- export type { Offer, OfferItem, OfferSummary } from './core/resources/offers';
17
+ export type { Offer, OfferSummary, OfferSummaryItem } from './core/resources/offers';
18
18
  export type { OrderBumpOffer, OrderBumpPreview } from './core/utils/orderBump';
19
19
  export type { ApplePayToken, CardPaymentMethod, Payment, PaymentInstrumentCustomer, PaymentInstrumentCustomerResponse, PaymentInstrumentResponse, PaymentOptions, PaymentResponse } from './core/resources/payments';
20
20
  export type { ShippingRate, ShippingRatesResponse } from './core/resources/shippingRates';
@@ -23,8 +23,10 @@ export type { ToggleOrderBumpResponse, VipOffer, VipPreviewResponse } from './co
23
23
  export type { StoreConfig } from './core/resources/storeConfig';
24
24
  export { FunnelActionType } from './core/resources/funnel';
25
25
  export type { BackNavigationActionData, CartUpdatedActionData, DirectNavigationActionData, FormSubmitActionData, FunnelContextUpdateRequest, FunnelContextUpdateResponse, FunnelAction as FunnelEvent, FunnelInitializeRequest, FunnelInitializeResponse, FunnelNavigateRequest, FunnelNavigateResponse, FunnelNavigationAction, FunnelNavigationResult, NextAction, OfferAcceptedActionData, OfferDeclinedActionData, PaymentFailedActionData, PaymentSuccessActionData, SimpleFunnelContext } from './core/resources/funnel';
26
- export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCredits, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffers, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useRemappableParams, useShippingRates, useSimpleFunnel, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers } from './react';
26
+ export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCredits, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useFunnelLegacy, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffer, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useRemappableParams, useShippingRates, useSimpleFunnel, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers } from './react';
27
+ export type { DebugScript } from './react';
27
28
  export type { TranslateFunction, TranslationText, UseTranslationOptions, UseTranslationResult } from './react/hooks/useTranslation';
29
+ export type { FunnelContextValue } from './react/hooks/useFunnel';
28
30
  export type { ClubOffer, ClubOfferItem, ClubOfferLineItem, ClubOfferSummary, UseClubOffersOptions, UseClubOffersResult } from './react/hooks/useClubOffers';
29
31
  export type { UseCreditsOptions, UseCreditsResult } from './react/hooks/useCredits';
30
32
  export type { UseLoginOptions, UseLoginResult } from './react/hooks/useLogin';
package/dist/v2/index.js CHANGED
@@ -15,4 +15,4 @@ export * from './core/utils/products';
15
15
  export * from './core/pathRemapping';
16
16
  export { FunnelActionType } from './core/resources/funnel';
17
17
  // React exports (hooks and components only, types are exported above)
18
- export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCredits, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffers, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useRemappableParams, useShippingRates, useSimpleFunnel, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers } from './react';
18
+ export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCredits, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useFunnelLegacy, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffer, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useRemappableParams, useShippingRates, useSimpleFunnel, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers } from './react';
@@ -77,6 +77,8 @@ export const DebugDrawer = ({ isOpen, onClose }) => {
77
77
  const context = useTagadaContext();
78
78
  const pluginConfig = usePluginConfig();
79
79
  const [activeTab, setActiveTab] = useState('overview');
80
+ const [runningScripts, setRunningScripts] = useState(new Set());
81
+ const [scriptResults, setScriptResults] = useState({});
80
82
  // Handler to jump to a specific step using direct_navigation
81
83
  const handleJumpToStep = async (stepId, stepName) => {
82
84
  // Try to get sessionId from debug data or context
@@ -168,7 +170,49 @@ export const DebugDrawer = ({ isOpen, onClose }) => {
168
170
  const itemsTab = context.debugCheckout.isActive && context.debugCheckout.data?.checkout?.summary
169
171
  ? [{ id: 'items', label: 'Items' }]
170
172
  : [];
171
- const tabs = [...baseTabs, ...funnelTab, ...checkoutTab, ...itemsTab, { id: 'raw', label: 'Raw Data' }];
173
+ // Add scripts tab if debug scripts are available
174
+ const scriptsTab = context.debugScripts && context.debugScripts.length > 0
175
+ ? [{ id: 'scripts', label: `Scripts (${context.debugScripts.length})` }]
176
+ : [];
177
+ const tabs = [
178
+ ...baseTabs,
179
+ ...funnelTab,
180
+ ...checkoutTab,
181
+ ...itemsTab,
182
+ ...scriptsTab,
183
+ { id: 'raw', label: 'Raw Data' },
184
+ ];
185
+ // Handler to run a debug script
186
+ const handleRunScript = async (scriptId) => {
187
+ const script = context.debugScripts?.find((s) => s.id === scriptId);
188
+ if (!script)
189
+ return;
190
+ setRunningScripts((prev) => new Set(prev).add(scriptId));
191
+ setScriptResults((prev) => ({ ...prev, [scriptId]: undefined }));
192
+ try {
193
+ await script.run(context);
194
+ setScriptResults((prev) => ({
195
+ ...prev,
196
+ [scriptId]: { success: true, message: 'Script executed successfully' },
197
+ }));
198
+ }
199
+ catch (error) {
200
+ setScriptResults((prev) => ({
201
+ ...prev,
202
+ [scriptId]: {
203
+ success: false,
204
+ message: error instanceof Error ? error.message : 'Script failed',
205
+ },
206
+ }));
207
+ }
208
+ finally {
209
+ setRunningScripts((prev) => {
210
+ const next = new Set(prev);
211
+ next.delete(scriptId);
212
+ return next;
213
+ });
214
+ }
215
+ };
172
216
  return (_jsxs(_Fragment, { children: [_jsx("div", { style: {
173
217
  position: 'fixed',
174
218
  top: 0,
@@ -681,6 +725,59 @@ export const DebugDrawer = ({ isOpen, onClose }) => {
681
725
  fontSize: '11px',
682
726
  margin: 0,
683
727
  whiteSpace: 'pre-wrap',
684
- }, children: context.debugCheckout.error.stack }))] })] })), _jsxs("div", { children: [_jsx("h4", { style: { margin: '0 0 12px 0', color: '#60a5fa' }, children: "Full Checkout Data" }), _jsx(TreeView, { data: context.debugCheckout.data, name: "checkoutData" })] })] })) : (_jsx("p", { style: { color: '#6b7280' }, children: "No checkout hook active" }))] })), activeTab === 'raw' && (_jsxs("div", { children: [_jsx("h3", { style: { margin: '0 0 16px 0', color: '#60a5fa' }, children: "Raw Context Data" }), _jsx("div", { style: { fontSize: '12px' }, children: _jsx(TreeView, { data: context, name: "tagadaContext", maxLevel: 4 }) })] }))] })] })] }));
728
+ }, children: context.debugCheckout.error.stack }))] })] })), _jsxs("div", { children: [_jsx("h4", { style: { margin: '0 0 12px 0', color: '#60a5fa' }, children: "Full Checkout Data" }), _jsx(TreeView, { data: context.debugCheckout.data, name: "checkoutData" })] })] })) : (_jsx("p", { style: { color: '#6b7280' }, children: "No checkout hook active" }))] })), activeTab === 'scripts' && (_jsxs("div", { children: [_jsx("h3", { style: { margin: '0 0 12px 0', color: '#60a5fa', fontSize: '14px' }, children: "\uD83D\uDEE0\uFE0F Debug Scripts" }), _jsx("p", { style: { margin: '0 0 16px 0', fontSize: '11px', color: '#9ca3af' }, children: "Template-provided scripts for debugging and testing. Click a script to run it." }), context.debugScripts && context.debugScripts.length > 0 ? (_jsx("div", { style: { display: 'grid', gap: '10px' }, children: (() => {
729
+ const grouped = context.debugScripts.reduce((acc, script) => {
730
+ const category = script.category || 'General';
731
+ if (!acc[category])
732
+ acc[category] = [];
733
+ acc[category].push(script);
734
+ return acc;
735
+ }, {});
736
+ return Object.entries(grouped).map(([category, scripts]) => (_jsxs("div", { children: [_jsx("div", { style: {
737
+ fontSize: '11px',
738
+ color: '#9ca3af',
739
+ fontWeight: 'bold',
740
+ marginBottom: '8px',
741
+ textTransform: 'uppercase',
742
+ letterSpacing: '0.5px',
743
+ }, children: category }), _jsx("div", { style: { display: 'grid', gap: '8px' }, children: scripts.map((script) => {
744
+ const isRunning = runningScripts.has(script.id);
745
+ const result = scriptResults[script.id];
746
+ return (_jsxs("div", { style: {
747
+ border: '1px solid #374151',
748
+ borderRadius: '6px',
749
+ padding: '10px 12px',
750
+ backgroundColor: '#111827',
751
+ }, children: [_jsxs("div", { style: {
752
+ display: 'flex',
753
+ justifyContent: 'space-between',
754
+ alignItems: 'flex-start',
755
+ gap: '12px',
756
+ }, children: [_jsxs("div", { style: { flex: 1 }, children: [_jsx("div", { style: {
757
+ color: '#f9fafb',
758
+ fontWeight: 'bold',
759
+ fontSize: '12px',
760
+ marginBottom: '4px',
761
+ }, children: script.name }), script.description && (_jsx("div", { style: { fontSize: '11px', color: '#9ca3af' }, children: script.description }))] }), _jsx("button", { onClick: () => handleRunScript(script.id), disabled: isRunning, style: {
762
+ backgroundColor: isRunning ? '#374151' : '#3b82f6',
763
+ color: '#fff',
764
+ border: 'none',
765
+ borderRadius: '4px',
766
+ padding: '6px 12px',
767
+ fontSize: '11px',
768
+ fontWeight: 'bold',
769
+ cursor: isRunning ? 'not-allowed' : 'pointer',
770
+ transition: 'background-color 0.2s',
771
+ minWidth: '60px',
772
+ }, children: isRunning ? '⏳' : '▶ Run' })] }), result && (_jsxs("div", { style: {
773
+ marginTop: '8px',
774
+ padding: '6px 8px',
775
+ borderRadius: '4px',
776
+ fontSize: '10px',
777
+ backgroundColor: result.success ? '#065f46' : '#7f1d1d',
778
+ color: result.success ? '#6ee7b7' : '#fca5a5',
779
+ }, children: [result.success ? '✅' : '❌', " ", result.message] }))] }, script.id));
780
+ }) })] }, category)));
781
+ })() })) : (_jsx("p", { style: { color: '#6b7280' }, children: "No debug scripts available" }))] })), activeTab === 'raw' && (_jsxs("div", { children: [_jsx("h3", { style: { margin: '0 0 16px 0', color: '#60a5fa' }, children: "Raw Context Data" }), _jsx("div", { style: { fontSize: '12px' }, children: _jsx(TreeView, { data: context, name: "tagadaContext", maxLevel: 4 }) })] }))] })] })] }));
685
782
  };
686
783
  export default DebugDrawer;
@@ -3,6 +3,9 @@
3
3
  *
4
4
  * This example demonstrates how to access data from previous steps
5
5
  * using the funnel context, including order, customer, and other resources.
6
+ *
7
+ * Note: Funnel initialization is now configured at the provider level:
8
+ * <TagadaProvider autoInitializeFunnel={true} funnelId="...">
6
9
  */
7
10
  export declare function FunnelContextExample(): import("react/jsx-runtime").JSX.Element;
8
11
  /**
@@ -4,12 +4,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  *
5
5
  * This example demonstrates how to access data from previous steps
6
6
  * using the funnel context, including order, customer, and other resources.
7
+ *
8
+ * Note: Funnel initialization is now configured at the provider level:
9
+ * <TagadaProvider autoInitializeFunnel={true} funnelId="...">
7
10
  */
8
11
  import { useFunnel } from '../useFunnel';
9
12
  export function FunnelContextExample() {
10
- const { context, isLoading, isInitialized } = useFunnel({
11
- autoInitialize: true,
12
- });
13
+ const { context, isLoading, isInitialized } = useFunnel();
13
14
  if (isLoading) {
14
15
  return _jsx("div", { children: "Loading funnel session..." });
15
16
  }
@@ -9,7 +9,7 @@ export interface ClubOfferItem {
9
9
  variant: {
10
10
  name: string;
11
11
  description: string;
12
- imageUrl: string;
12
+ imageUrl: string | null;
13
13
  grams: number;
14
14
  };
15
15
  unitAmount: number;
@@ -31,7 +31,7 @@ export interface ClubOfferLineItem {
31
31
  id: string;
32
32
  name: string;
33
33
  description: string | null;
34
- imageUrl: string;
34
+ imageUrl: string | null;
35
35
  grams: number;
36
36
  product: {
37
37
  id: string;
@@ -1,52 +1,40 @@
1
1
  /**
2
- * useFunnel Hook (v2) - TanStack Query-based funnel navigation
2
+ * useFunnel Hook - Access funnel state and navigation methods
3
3
  *
4
- * Modern implementation using TanStack Query for state management
5
- * and the v2 ApiClient for API calls.
4
+ * This hook consumes the funnel state from TagadaProvider. All complex
5
+ * initialization and session management is handled at the provider level.
6
+ *
7
+ * Usage:
8
+ * ```tsx
9
+ * // In your root component or layout:
10
+ * <TagadaProvider funnelId="funnelv2_xxx" autoInitializeFunnel={true}>
11
+ * <YourApp />
12
+ * </TagadaProvider>
13
+ *
14
+ * // In any child component:
15
+ * const { context, next, isLoading } = useFunnel();
16
+ * ```
6
17
  */
7
18
  import { FunnelAction, FunnelNavigationResult, SimpleFunnelContext } from '../../core/resources/funnel';
8
- export interface UseFunnelOptions {
9
- funnelId?: string;
10
- currentStepId?: string;
11
- onNavigate?: (result: FunnelNavigationResult) => void | boolean;
12
- onError?: (error: Error) => void;
13
- autoInitialize?: boolean;
14
- enabled?: boolean;
15
- }
16
- export interface UseFunnelResult {
17
- next: (event: FunnelAction) => Promise<any>;
18
- goToStep: (stepId: string) => Promise<any>;
19
- updateContext: (updates: Partial<SimpleFunnelContext>) => Promise<void>;
19
+ import { FunnelState } from '../../core/funnelClient';
20
+ export interface FunnelContextValue extends FunnelState {
20
21
  currentStep: {
21
22
  id: string;
22
- };
23
- context: SimpleFunnelContext | null;
24
- isLoading: boolean;
25
- isInitialized: boolean;
26
- isNavigating: boolean;
23
+ } | null;
24
+ next: (event: FunnelAction) => Promise<FunnelNavigationResult>;
25
+ goToStep: (stepId: string) => Promise<FunnelNavigationResult>;
26
+ updateContext: (updates: Partial<SimpleFunnelContext>) => Promise<void>;
27
27
  initializeSession: (entryStepId?: string) => Promise<void>;
28
28
  endSession: () => Promise<void>;
29
29
  retryInitialization: () => Promise<void>;
30
- initializationError: Error | null;
31
- isSessionLoading: boolean;
32
- sessionError: Error | null;
33
- refetch: () => void;
30
+ refetch: () => Promise<void>;
34
31
  }
35
32
  /**
36
- * React Hook for Funnel Navigation (Plugin SDK v2)
33
+ * Hook to access funnel state and methods
37
34
  *
38
- * Modern funnel navigation using TanStack Query for state management
39
- * and the v2 ApiClient architecture.
40
- */
41
- export declare function useFunnel(options?: UseFunnelOptions): UseFunnelResult;
42
- /**
43
- * Simplified funnel hook for basic step tracking (v2)
35
+ * This hook simply returns the funnel state from TagadaProvider.
36
+ * All complex logic is handled at the provider level.
37
+ *
38
+ * @returns FunnelContextValue with state and methods
44
39
  */
45
- export declare function useSimpleFunnel(funnelId: string, initialStepId?: string): {
46
- currentStepId: string;
47
- next: (event: FunnelAction) => Promise<any>;
48
- goToStep: (stepId: string) => Promise<any>;
49
- isLoading: boolean;
50
- context: SimpleFunnelContext<{}> | null;
51
- };
52
- export type { FunnelAction as FunnelEvent, FunnelNavigationAction, FunnelNavigationResult, SimpleFunnelContext } from '../../core/resources/funnel';
40
+ export declare function useFunnel(): FunnelContextValue;