@datlv-trustshop/shopify-inapp-components 0.2.7 → 0.2.9

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 (226) hide show
  1. package/dist/components/AppList.d.ts +1 -0
  2. package/dist/components/AppList.d.ts.map +1 -0
  3. package/dist/components/AppList.js +1 -0
  4. package/dist/components/AppList.js.map +1 -0
  5. package/dist/components/ArticleList.d.ts +1 -0
  6. package/dist/components/ArticleList.d.ts.map +1 -0
  7. package/dist/components/ArticleList.js +1 -0
  8. package/dist/components/ArticleList.js.map +1 -0
  9. package/dist/components/ArticleSlide.d.ts +1 -0
  10. package/dist/components/ArticleSlide.d.ts.map +1 -0
  11. package/dist/components/ArticleSlide.js +1 -0
  12. package/dist/components/ArticleSlide.js.map +1 -0
  13. package/dist/components/FloatingCard.d.ts +1 -0
  14. package/dist/components/FloatingCard.d.ts.map +1 -0
  15. package/dist/components/FloatingCard.js +5 -4
  16. package/dist/components/FloatingCard.js.map +1 -0
  17. package/dist/components/FooterBanner.d.ts +1 -0
  18. package/dist/components/FooterBanner.d.ts.map +1 -0
  19. package/dist/components/FooterBanner.js +1 -0
  20. package/dist/components/FooterBanner.js.map +1 -0
  21. package/dist/components/GrowApps.d.ts +6 -6
  22. package/dist/components/GrowApps.d.ts.map +1 -0
  23. package/dist/components/GrowApps.js +11 -3
  24. package/dist/components/GrowApps.js.map +1 -0
  25. package/dist/components/ImageLoading.d.ts +1 -0
  26. package/dist/components/ImageLoading.d.ts.map +1 -0
  27. package/dist/components/ImageLoading.js +1 -0
  28. package/dist/components/ImageLoading.js.map +1 -0
  29. package/dist/components/PartnerIntegration.d.ts +8 -8
  30. package/dist/components/PartnerIntegration.d.ts.map +1 -0
  31. package/dist/components/PartnerIntegration.js +15 -76
  32. package/dist/components/PartnerIntegration.js.map +1 -0
  33. package/dist/components/PartnerList.d.ts +1 -0
  34. package/dist/components/PartnerList.d.ts.map +1 -0
  35. package/dist/components/PartnerList.js +1 -0
  36. package/dist/components/PartnerList.js.map +1 -0
  37. package/dist/components/PopupBanner.d.ts +4 -4
  38. package/dist/components/PopupBanner.d.ts.map +1 -0
  39. package/dist/components/PopupBanner.js +5 -1
  40. package/dist/components/PopupBanner.js.map +1 -0
  41. package/dist/components/TopBanner.d.ts +7 -7
  42. package/dist/components/TopBanner.d.ts.map +1 -0
  43. package/dist/components/TopBanner.js +40 -31
  44. package/dist/components/TopBanner.js.map +1 -0
  45. package/dist/components/WhatsNew.d.ts +6 -7
  46. package/dist/components/WhatsNew.d.ts.map +1 -0
  47. package/dist/components/WhatsNew.js +23 -25
  48. package/dist/components/WhatsNew.js.map +1 -0
  49. package/dist/components/index.d.ts +1 -0
  50. package/dist/components/index.d.ts.map +1 -0
  51. package/dist/components/index.js +1 -0
  52. package/dist/components/index.js.map +1 -0
  53. package/dist/components/inlineStyles.d.ts +1 -0
  54. package/dist/components/inlineStyles.d.ts.map +1 -0
  55. package/dist/components/inlineStyles.js +1 -0
  56. package/dist/components/inlineStyles.js.map +1 -0
  57. package/dist/components/styles.d.ts +1 -0
  58. package/dist/components/styles.d.ts.map +1 -0
  59. package/dist/components/styles.js +1 -0
  60. package/dist/components/styles.js.map +1 -0
  61. package/dist/config/component-defaults.d.ts +71 -0
  62. package/dist/config/component-defaults.d.ts.map +1 -0
  63. package/dist/config/component-defaults.js +106 -0
  64. package/dist/config/component-defaults.js.map +1 -0
  65. package/dist/config/internal-config.d.ts +28 -0
  66. package/dist/config/internal-config.d.ts.map +1 -0
  67. package/dist/config/internal-config.js +100 -0
  68. package/dist/config/internal-config.js.map +1 -0
  69. package/dist/core/SDKManager.d.ts +230 -0
  70. package/dist/core/SDKManager.d.ts.map +1 -0
  71. package/dist/core/SDKManager.js +380 -0
  72. package/dist/core/SDKManager.js.map +1 -0
  73. package/dist/core/adapter.d.ts +1 -0
  74. package/dist/core/adapter.d.ts.map +1 -0
  75. package/dist/core/adapter.js +1 -0
  76. package/dist/core/adapter.js.map +1 -0
  77. package/dist/core/engine.d.ts +1 -0
  78. package/dist/core/engine.d.ts.map +1 -0
  79. package/dist/core/engine.js +1 -0
  80. package/dist/core/engine.js.map +1 -0
  81. package/dist/core/fetcher.d.ts +1 -0
  82. package/dist/core/fetcher.d.ts.map +1 -0
  83. package/dist/core/fetcher.js +1 -0
  84. package/dist/core/fetcher.js.map +1 -0
  85. package/dist/core/global-manager.d.ts +1 -0
  86. package/dist/core/global-manager.d.ts.map +1 -0
  87. package/dist/core/global-manager.js +1 -0
  88. package/dist/core/global-manager.js.map +1 -0
  89. package/dist/hooks/index.d.ts +1 -0
  90. package/dist/hooks/index.d.ts.map +1 -0
  91. package/dist/hooks/index.js +1 -0
  92. package/dist/hooks/index.js.map +1 -0
  93. package/dist/hooks/useApps.d.ts +2 -1
  94. package/dist/hooks/useApps.d.ts.map +1 -0
  95. package/dist/hooks/useApps.js +8 -15
  96. package/dist/hooks/useApps.js.map +1 -0
  97. package/dist/hooks/useArticles.d.ts +1 -0
  98. package/dist/hooks/useArticles.d.ts.map +1 -0
  99. package/dist/hooks/useArticles.js +14 -18
  100. package/dist/hooks/useArticles.js.map +1 -0
  101. package/dist/hooks/useBanner.d.ts +2 -1
  102. package/dist/hooks/useBanner.d.ts.map +1 -0
  103. package/dist/hooks/useBanner.js +14 -15
  104. package/dist/hooks/useBanner.js.map +1 -0
  105. package/dist/hooks/useCampaignTracking.d.ts +1 -0
  106. package/dist/hooks/useCampaignTracking.d.ts.map +1 -0
  107. package/dist/hooks/useCampaignTracking.js +1 -0
  108. package/dist/hooks/useCampaignTracking.js.map +1 -0
  109. package/dist/hooks/useDashboard.d.ts +1 -0
  110. package/dist/hooks/useDashboard.d.ts.map +1 -0
  111. package/dist/hooks/useDashboard.js +12 -9
  112. package/dist/hooks/useDashboard.js.map +1 -0
  113. package/dist/hooks/useFloatingCardActions.d.ts +1 -0
  114. package/dist/hooks/useFloatingCardActions.d.ts.map +1 -0
  115. package/dist/hooks/useFloatingCardActions.js +1 -0
  116. package/dist/hooks/useFloatingCardActions.js.map +1 -0
  117. package/dist/hooks/useFloatingCardEngine.d.ts +1 -0
  118. package/dist/hooks/useFloatingCardEngine.d.ts.map +1 -0
  119. package/dist/hooks/useFloatingCardEngine.js +1 -0
  120. package/dist/hooks/useFloatingCardEngine.js.map +1 -0
  121. package/dist/hooks/useFloatingCards.d.ts +3 -2
  122. package/dist/hooks/useFloatingCards.d.ts.map +1 -0
  123. package/dist/hooks/useFloatingCards.js +37 -12
  124. package/dist/hooks/useFloatingCards.js.map +1 -0
  125. package/dist/hooks/useGrowApps.d.ts +1 -0
  126. package/dist/hooks/useGrowApps.d.ts.map +1 -0
  127. package/dist/hooks/useGrowApps.js +1 -0
  128. package/dist/hooks/useGrowApps.js.map +1 -0
  129. package/dist/hooks/usePartnerIntegration.d.ts +5 -4
  130. package/dist/hooks/usePartnerIntegration.d.ts.map +1 -0
  131. package/dist/hooks/usePartnerIntegration.js +10 -38
  132. package/dist/hooks/usePartnerIntegration.js.map +1 -0
  133. package/dist/hooks/useTranslations.d.ts +1 -0
  134. package/dist/hooks/useTranslations.d.ts.map +1 -0
  135. package/dist/hooks/useTranslations.js +5 -3
  136. package/dist/hooks/useTranslations.js.map +1 -0
  137. package/dist/hooks/useWhatsNew.d.ts +1 -0
  138. package/dist/hooks/useWhatsNew.d.ts.map +1 -0
  139. package/dist/hooks/useWhatsNew.js +12 -11
  140. package/dist/hooks/useWhatsNew.js.map +1 -0
  141. package/dist/index.d.ts +38 -22
  142. package/dist/index.d.ts.map +1 -0
  143. package/dist/index.js +76 -22
  144. package/dist/index.js.map +1 -0
  145. package/dist/translations/default.d.ts +1 -0
  146. package/dist/translations/default.d.ts.map +1 -0
  147. package/dist/translations/default.js +1 -0
  148. package/dist/translations/default.js.map +1 -0
  149. package/dist/translations/locales/cn.json +39 -0
  150. package/dist/translations/locales/de.json +39 -0
  151. package/dist/translations/locales/dk.json +39 -0
  152. package/dist/translations/locales/en.json +39 -0
  153. package/dist/translations/locales/es.json +39 -0
  154. package/dist/translations/locales/fr.json +39 -0
  155. package/dist/translations/locales/ie.json +39 -0
  156. package/dist/translations/locales/in.json +39 -0
  157. package/dist/translations/locales/it.json +39 -0
  158. package/dist/translations/locales/jp.json +39 -0
  159. package/dist/translations/locales/nl.json +39 -0
  160. package/dist/translations/locales/nz.json +39 -0
  161. package/dist/translations/locales/pt.json +39 -0
  162. package/dist/translations/locales/se.json +39 -0
  163. package/dist/translations/locales/vi.json +39 -0
  164. package/dist/translations/translation-manager.d.ts +89 -0
  165. package/dist/translations/translation-manager.d.ts.map +1 -0
  166. package/dist/translations/translation-manager.js +239 -0
  167. package/dist/translations/translation-manager.js.map +1 -0
  168. package/dist/types/app.d.ts +1 -0
  169. package/dist/types/app.d.ts.map +1 -0
  170. package/dist/types/app.js +1 -0
  171. package/dist/types/app.js.map +1 -0
  172. package/dist/types/article.d.ts +1 -0
  173. package/dist/types/article.d.ts.map +1 -0
  174. package/dist/types/article.js +1 -0
  175. package/dist/types/article.js.map +1 -0
  176. package/dist/types/banner.d.ts +1 -0
  177. package/dist/types/banner.d.ts.map +1 -0
  178. package/dist/types/banner.js +1 -0
  179. package/dist/types/banner.js.map +1 -0
  180. package/dist/types/component-props.d.ts +140 -0
  181. package/dist/types/component-props.d.ts.map +1 -0
  182. package/dist/types/component-props.js +6 -0
  183. package/dist/types/component-props.js.map +1 -0
  184. package/dist/types/dashboard.d.ts +1 -0
  185. package/dist/types/dashboard.d.ts.map +1 -0
  186. package/dist/types/dashboard.js +1 -0
  187. package/dist/types/dashboard.js.map +1 -0
  188. package/dist/types/index.d.ts +1 -0
  189. package/dist/types/index.d.ts.map +1 -0
  190. package/dist/types/index.js +1 -0
  191. package/dist/types/index.js.map +1 -0
  192. package/dist/types/integration.d.ts +1 -0
  193. package/dist/types/integration.d.ts.map +1 -0
  194. package/dist/types/integration.js +1 -0
  195. package/dist/types/integration.js.map +1 -0
  196. package/dist/types/partner.d.ts +1 -0
  197. package/dist/types/partner.d.ts.map +1 -0
  198. package/dist/types/partner.js +1 -0
  199. package/dist/types/partner.js.map +1 -0
  200. package/dist/types/product-update.d.ts +1 -0
  201. package/dist/types/product-update.d.ts.map +1 -0
  202. package/dist/types/product-update.js +1 -0
  203. package/dist/types/product-update.js.map +1 -0
  204. package/dist/types/translations.d.ts +1 -0
  205. package/dist/types/translations.d.ts.map +1 -0
  206. package/dist/types/translations.js +1 -0
  207. package/dist/types/translations.js.map +1 -0
  208. package/dist/utils/campaignTracking.d.ts +1 -0
  209. package/dist/utils/campaignTracking.d.ts.map +1 -0
  210. package/dist/utils/campaignTracking.js +1 -0
  211. package/dist/utils/campaignTracking.js.map +1 -0
  212. package/dist/utils/cls-monitor.d.ts +1 -0
  213. package/dist/utils/cls-monitor.d.ts.map +1 -0
  214. package/dist/utils/cls-monitor.js +1 -0
  215. package/dist/utils/cls-monitor.js.map +1 -0
  216. package/dist/utils/injectStyles.d.ts +1 -0
  217. package/dist/utils/injectStyles.d.ts.map +1 -0
  218. package/dist/utils/injectStyles.js +1 -0
  219. package/dist/utils/injectStyles.js.map +1 -0
  220. package/dist/utils/sessionManager.d.ts +1 -0
  221. package/dist/utils/sessionManager.d.ts.map +1 -0
  222. package/dist/utils/sessionManager.js +1 -0
  223. package/dist/utils/sessionManager.js.map +1 -0
  224. package/package.json +4 -3
  225. package/dist/provider/DashboardProvider.d.ts +0 -36
  226. package/dist/provider/DashboardProvider.js +0 -200
@@ -19,3 +19,4 @@ export declare function trackCampaignClick(shopId: string, campaignId: string |
19
19
  * Useful for testing or when session changes
20
20
  */
21
21
  export declare function clearViewTrackingCache(): void;
22
+ //# sourceMappingURL=campaignTracking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"campaignTracking.d.ts","sourceRoot":"","sources":["../../src/utils/campaignTracking.ts"],"names":[],"mappings":"AAoCA;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GAAG,MAAM,EAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,CAsCf;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GAAG,MAAM,EAC3B,OAAO,GAAE;IACP,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC3B,GACL,OAAO,CAAC,IAAI,CAAC,CAwCf;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
@@ -116,3 +116,4 @@ export async function trackCampaignClick(shopId, campaignId, options = {}) {
116
116
  export function clearViewTrackingCache() {
117
117
  viewTrackingMap.clear();
118
118
  }
119
+ //# sourceMappingURL=campaignTracking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"campaignTracking.js","sourceRoot":"","sources":["../../src/utils/campaignTracking.ts"],"names":[],"mappings":"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","sourcesContent":["import { getSessionId } from './sessionManager';\n\nconst TRACKING_BASE_URL = 'https://ops.trustshop.io';\n\n/**\n * View tracking deduplication map\n * Key: ${sessionId}-${campaignId}\n * Value: timestamp in milliseconds\n */\nconst viewTrackingMap = new Map<string, number>();\n\n/**\n * Deduplication threshold for view tracking (5 seconds)\n */\nconst VIEW_DEDUP_THRESHOLD_MS = 5000;\n\n/**\n * Get current page context from URL\n */\nfunction getPageContext(): string {\n if (typeof window === 'undefined') {\n return '/';\n }\n \n // Get the current pathname\n const pathname = window.location.pathname;\n \n // In Shopify admin apps, the actual route might be in hash\n const hash = window.location.hash;\n if (hash && hash.startsWith('#/')) {\n return hash.substring(1); // Remove the '#'\n }\n \n return pathname;\n}\n\n/**\n * Track campaign view\n * Handles deduplication and fire-and-forget requests\n */\nexport async function trackCampaignView(\n shopId: string,\n campaignId: string | number,\n metadata?: Record<string, any>\n): Promise<void> {\n const sessionId = getSessionId();\n const dedupKey = `${sessionId}-${campaignId}`;\n const now = Date.now();\n \n // Check for deduplication\n const lastTracked = viewTrackingMap.get(dedupKey);\n if (lastTracked && (now - lastTracked) < VIEW_DEDUP_THRESHOLD_MS) {\n return;\n }\n \n // Update tracking map\n viewTrackingMap.set(dedupKey, now);\n \n const payload = {\n session_id: sessionId,\n page_context: getPageContext(),\n metadata: {\n source: 'in-app-trustshop',\n placement: 'floating-card',\n ...metadata,\n },\n };\n \n const url = `${TRACKING_BASE_URL}/api/shops/${shopId}/campaigns/${campaignId}/track/view`;\n // Fire and forget - no await, no error handling that would break UI\n void fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n },\n body: JSON.stringify(payload),\n credentials: 'include',\n }).catch(error => {\n // Log error in development\n console.error('[Campaign Tracking] View tracking failed:', error);\n });\n}\n\n/**\n * Track campaign click\n * Tracks immediately without debouncing\n */\nexport async function trackCampaignClick(\n shopId: string,\n campaignId: string | number,\n options: {\n actionType?: string;\n ctaId?: string;\n ctaKey?: string;\n timeToAction?: number;\n metadata?: Record<string, any>;\n } = {}\n): Promise<void> {\n const { actionType, ctaId, ctaKey, timeToAction, metadata } = options;\n \n // Validate that at least one required field is present\n if (!actionType && !ctaId && !ctaKey) {\n return;\n }\n \n const sessionId = getSessionId();\n \n const payload: any = {\n session_id: sessionId,\n page_context: getPageContext(),\n metadata: {\n source: 'in-app-trustshop',\n placement: 'floating-card',\n ...metadata,\n },\n };\n \n // Add optional fields if provided\n if (actionType) payload.action_type = actionType;\n if (ctaId) payload.cta_id = ctaId;\n if (ctaKey) payload.cta_key = ctaKey;\n if (timeToAction !== undefined) payload.time_to_action = timeToAction;\n \n const url = `${TRACKING_BASE_URL}/api/shops/${shopId}/campaigns/${campaignId}/track/click`;\n // Fire and forget - no await, no error handling that would break UI\n void fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n },\n body: JSON.stringify(payload),\n credentials: 'include',\n }).catch(error => {\n // Log error in development\n console.error('[Campaign Tracking] Click tracking failed:', error);\n });\n}\n\n/**\n * Clear view tracking deduplication cache\n * Useful for testing or when session changes\n */\nexport function clearViewTrackingCache(): void {\n viewTrackingMap.clear();\n}"]}
@@ -48,3 +48,4 @@ export declare function startCLSMonitoring(options?: CLSMonitorOptions): CLSMoni
48
48
  export declare function stopCLSMonitoring(): void;
49
49
  export declare function getCLSMetrics(): CLSMetrics | null;
50
50
  export {};
51
+ //# sourceMappingURL=cls-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cls-monitor.d.ts","sourceRoot":"","sources":["../../src/utils/cls-monitor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,UAAU,gBAAiB,SAAQ,gBAAgB;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,IAAI,CAAC,EAAE,IAAI,CAAC;QACZ,YAAY,EAAE,eAAe,CAAC;QAC9B,WAAW,EAAE,eAAe,CAAC;KAC9B,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;IACxC,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;IACpD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;CACnD;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAoC;IACpD,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;gBAExB,OAAO,GAAE,iBAAsB;IAW3C,KAAK,IAAI,IAAI;IA+Bb,OAAO,CAAC,kBAAkB;IA2C1B,OAAO,CAAC,QAAQ;IA6BhB,IAAI,IAAI,IAAI;IAWZ,KAAK,IAAI,IAAI;IAQb,aAAa,IAAI,UAAU;IAQ3B,OAAO,CAAC,mBAAmB;IAM3B,MAAM,CAAC,2BAA2B,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,OAAO,EAAE;IAiB1E,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;CAiBxE;AAKD,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,UAAU,CAM1E;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC;AAED,wBAAgB,aAAa,IAAI,UAAU,GAAG,IAAI,CAEjD"}
@@ -182,3 +182,4 @@ export function stopCLSMonitoring() {
182
182
  export function getCLSMetrics() {
183
183
  return globalMonitor ? globalMonitor.getCurrentCLS() : null;
184
184
  }
185
+ //# sourceMappingURL=cls-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cls-monitor.js","sourceRoot":"","sources":["../../src/utils/cls-monitor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLS (Cumulative Layout Shift) Monitoring Utility\n * Tracks and reports layout shifts for performance optimization\n */\n\ninterface LayoutShiftEntry extends PerformanceEntry {\n value: number;\n hadRecentInput: boolean;\n sources?: Array<{\n node?: Node;\n previousRect: DOMRectReadOnly;\n currentRect: DOMRectReadOnly;\n }>;\n}\n\nexport interface CLSMetrics {\n value: number;\n entries: LayoutShiftEntry[];\n timestamp: number;\n}\n\nexport interface CLSMonitorOptions {\n threshold?: number;\n onShift?: (metrics: CLSMetrics) => void;\n onThresholdExceeded?: (metrics: CLSMetrics) => void;\n debug?: boolean;\n reportToConsole?: boolean;\n reportToAnalytics?: (metrics: CLSMetrics) => void;\n}\n\nexport class CLSMonitor {\n private observer: PerformanceObserver | null = null;\n private clsValue = 0;\n private clsEntries: LayoutShiftEntry[] = [];\n private options: Required<CLSMonitorOptions>;\n private sessionValue = 0;\n private sessionEntries: LayoutShiftEntry[] = [];\n private lastShiftTime = 0;\n private readonly SESSION_GAP = 5000; // 5 seconds\n\n constructor(options: CLSMonitorOptions = {}) {\n this.options = {\n threshold: options.threshold || 0.1, // Good CLS threshold\n onShift: options.onShift || (() => {}),\n onThresholdExceeded: options.onThresholdExceeded || (() => {}),\n debug: options.debug || false,\n reportToConsole: options.reportToConsole || false,\n reportToAnalytics: options.reportToAnalytics || (() => {}),\n };\n }\n\n start(): void {\n if (!this.supportsLayoutShift()) {\n console.warn('PerformanceObserver for layout-shift not supported');\n return;\n }\n\n try {\n this.observer = new PerformanceObserver((list) => {\n const entries = list.getEntries() as LayoutShiftEntry[];\n \n for (const entry of entries) {\n // Ignore shifts with recent input (user-initiated)\n if (!entry.hadRecentInput) {\n this.processLayoutShift(entry);\n }\n }\n });\n\n this.observer.observe({ \n type: 'layout-shift', \n buffered: true \n });\n\n if (this.options.debug) {\n console.log('CLS Monitor started');\n }\n } catch (error) {\n console.error('Failed to start CLS Monitor:', error);\n }\n }\n\n private processLayoutShift(entry: LayoutShiftEntry): void {\n const now = Date.now();\n \n // Check if this is part of a new session\n if (now - this.lastShiftTime > this.SESSION_GAP) {\n // Start new session\n this.sessionValue = 0;\n this.sessionEntries = [];\n }\n \n this.lastShiftTime = now;\n this.sessionValue += entry.value;\n this.sessionEntries.push(entry);\n \n // Update cumulative value (max session value)\n if (this.sessionValue > this.clsValue) {\n this.clsValue = this.sessionValue;\n this.clsEntries = [...this.sessionEntries];\n }\n\n const metrics: CLSMetrics = {\n value: this.clsValue,\n entries: this.clsEntries,\n timestamp: now,\n };\n\n // Report shift\n this.options.onShift(metrics);\n\n // Check threshold\n if (this.clsValue > this.options.threshold) {\n this.options.onThresholdExceeded(metrics);\n }\n\n // Debug logging\n if (this.options.debug || this.options.reportToConsole) {\n this.logShift(entry, metrics);\n }\n\n // Report to analytics\n this.options.reportToAnalytics(metrics);\n }\n\n private logShift(entry: LayoutShiftEntry, metrics: CLSMetrics): void {\n const affectedElements = entry.sources?.map(source => {\n if (source.node && source.node.nodeType === 1) {\n const element = source.node as Element;\n return {\n element: element.tagName,\n id: element.id,\n className: element.className,\n previousRect: source.previousRect,\n currentRect: source.currentRect,\n };\n }\n return null;\n }).filter(Boolean) || [];\n\n console.group(`🎯 Layout Shift Detected`);\n console.log('Shift Value:', entry.value.toFixed(4));\n console.log('Session CLS:', this.sessionValue.toFixed(4));\n console.log('Total CLS:', metrics.value.toFixed(4));\n console.log('Threshold:', this.options.threshold);\n console.log('Status:', metrics.value > this.options.threshold ? '❌ Bad' : '✅ Good');\n \n if (affectedElements.length > 0) {\n console.log('Affected Elements:', affectedElements);\n }\n \n console.groupEnd();\n }\n\n stop(): void {\n if (this.observer) {\n this.observer.disconnect();\n this.observer = null;\n \n if (this.options.debug) {\n console.log('CLS Monitor stopped');\n }\n }\n }\n\n reset(): void {\n this.clsValue = 0;\n this.clsEntries = [];\n this.sessionValue = 0;\n this.sessionEntries = [];\n this.lastShiftTime = 0;\n }\n\n getCurrentCLS(): CLSMetrics {\n return {\n value: this.clsValue,\n entries: this.clsEntries,\n timestamp: Date.now(),\n };\n }\n\n private supportsLayoutShift(): boolean {\n return typeof PerformanceObserver !== 'undefined' && \n PerformanceObserver.supportedEntryTypes?.includes('layout-shift');\n }\n\n // Helper method to identify problematic elements\n static identifyProblematicElements(entries: LayoutShiftEntry[]): Element[] {\n const problematicElements = new Set<Element>();\n \n for (const entry of entries) {\n if (entry.sources) {\n for (const source of entry.sources) {\n if (source.node && source.node.nodeType === 1) {\n problematicElements.add(source.node as Element);\n }\n }\n }\n }\n \n return Array.from(problematicElements);\n }\n\n // Helper to get CLS attribution\n static getAttribution(entries: LayoutShiftEntry[]): Map<string, number> {\n const attribution = new Map<string, number>();\n \n for (const entry of entries) {\n if (entry.sources) {\n for (const source of entry.sources) {\n if (source.node && source.node.nodeType === 1) {\n const element = source.node as Element;\n const key = `${element.tagName}${element.id ? '#' + element.id : ''}${element.className ? '.' + element.className.split(' ').join('.') : ''}`;\n attribution.set(key, (attribution.get(key) || 0) + entry.value);\n }\n }\n }\n }\n \n return attribution;\n }\n}\n\n// Singleton instance for easy global usage\nlet globalMonitor: CLSMonitor | null = null;\n\nexport function startCLSMonitoring(options?: CLSMonitorOptions): CLSMonitor {\n if (!globalMonitor) {\n globalMonitor = new CLSMonitor(options);\n globalMonitor.start();\n }\n return globalMonitor;\n}\n\nexport function stopCLSMonitoring(): void {\n if (globalMonitor) {\n globalMonitor.stop();\n globalMonitor = null;\n }\n}\n\nexport function getCLSMetrics(): CLSMetrics | null {\n return globalMonitor ? globalMonitor.getCurrentCLS() : null;\n}"]}
@@ -12,3 +12,4 @@ export declare function injectClsStyles(): void;
12
12
  * Remove injected styles (for cleanup)
13
13
  */
14
14
  export declare function removeClsStyles(): void;
15
+ //# sourceMappingURL=injectStyles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectStyles.d.ts","sourceRoot":"","sources":["../../src/utils/injectStyles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,eAAO,MAAM,mBAAmB,uuCAmE/B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAkBtC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAStC"}
@@ -103,3 +103,4 @@ export function removeClsStyles() {
103
103
  styleElement.remove();
104
104
  }
105
105
  }
106
+ //# sourceMappingURL=injectStyles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectStyles.js","sourceRoot":"","sources":["../../src/utils/injectStyles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,QAAQ,GAAG,8BAA8B,CAAC;AAEhD,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmElC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,uCAAuC;IACvC,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO,CAAC,aAAa;IACvB,CAAC;IAED,IAAI,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,mBAAmB;IAC7B,CAAC;IAED,kCAAkC;IAClC,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACrD,YAAY,CAAC,EAAE,GAAG,QAAQ,CAAC;IAC3B,YAAY,CAAC,WAAW,GAAG,mBAAmB,CAAC;IAE/C,oCAAoC;IACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC;IAC9C,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO;IACT,CAAC;IAED,MAAM,YAAY,GAAG,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvD,IAAI,YAAY,EAAE,CAAC;QACjB,YAAY,CAAC,MAAM,EAAE,CAAC;IACxB,CAAC;AACH,CAAC","sourcesContent":["/**\n * Automatically inject CLS fix styles into the document\n * This ensures the styles are always applied without requiring manual imports\n */\n\nconst STYLE_ID = 'ts-shopify-polaris-cls-fixes';\n\nexport const polarisClsFixStyles = `\n/* Critical Polaris CLS Fixes */\n.Polaris-ShadowBevel {\n min-height: inherit !important;\n will-change: contents;\n}\n\n.Polaris-Card {\n min-height: 100px;\n contain: layout style;\n}\n\n.Polaris-Tabs__Panel {\n min-height: 350px;\n contain: layout;\n}\n\n.Polaris-Tabs__TabPanel {\n min-height: inherit;\n}\n\n.Polaris-Box {\n /* Prevent height changes from dynamic content */\n contain: style;\n}\n\n/* Skeleton state improvements */\n.Polaris-SkeletonBodyText,\n.Polaris-SkeletonDisplayText,\n.Polaris-SkeletonThumbnail {\n animation: none !important;\n background: linear-gradient(\n 90deg,\n #f0f0f0 25%,\n #f8f8f8 50%,\n #f0f0f0 75%\n );\n background-size: 200% 100%;\n animation: pulse 1.5s ease-in-out infinite !important;\n}\n\n@keyframes pulse {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n}\n\n/* Prevent layout shifts from Polaris transitions */\n.Polaris-Card,\n.Polaris-Banner,\n.Polaris-CalloutCard {\n transform: translateZ(0);\n will-change: transform;\n}\n\n/* Fix for navigation tabs */\n.custom-tabs-wrapper-dashboard {\n min-height: 400px;\n}\n\n/* GPU acceleration for transforms */\n[style*=\"transform\"] {\n will-change: transform;\n}\n`;\n\n/**\n * Inject CLS fix styles into the document head\n * This is called automatically when the SDK initializes\n */\nexport function injectClsStyles(): void {\n // Check if styles are already injected\n if (typeof document === 'undefined') {\n return; // SSR safety\n }\n \n if (document.getElementById(STYLE_ID)) {\n return; // Already injected\n }\n\n // Create and inject style element\n const styleElement = document.createElement('style');\n styleElement.id = STYLE_ID;\n styleElement.textContent = polarisClsFixStyles;\n \n // Add to head (or body as fallback)\n const target = document.head || document.body;\n target.appendChild(styleElement);\n}\n\n/**\n * Remove injected styles (for cleanup)\n */\nexport function removeClsStyles(): void {\n if (typeof document === 'undefined') {\n return;\n }\n \n const styleElement = document.getElementById(STYLE_ID);\n if (styleElement) {\n styleElement.remove();\n }\n}"]}
@@ -14,3 +14,4 @@ export declare function clearSession(): void;
14
14
  * Check if a session exists
15
15
  */
16
16
  export declare function hasSession(): boolean;
17
+ //# sourceMappingURL=sessionManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionManager.d.ts","sourceRoot":"","sources":["../../src/utils/sessionManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAaH;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAqBrC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAQnC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAQpC"}
@@ -60,3 +60,4 @@ export function hasSession() {
60
60
  return false;
61
61
  }
62
62
  }
63
+ //# sourceMappingURL=sessionManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionManager.js","sourceRoot":"","sources":["../../src/utils/sessionManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,cAAc,GAAG,4BAA4B,CAAC;AAEpD;;GAEG;AACH,SAAS,iBAAiB;IACxB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3D,OAAO,QAAQ,SAAS,IAAI,MAAM,EAAE,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,iBAAiB,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,CAAC;QACH,+CAA+C;QAC/C,IAAI,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAEvD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,0BAA0B;YAC1B,SAAS,GAAG,iBAAiB,EAAE,CAAC;YAChC,cAAc,CAAC,OAAO,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;QACpD,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,8CAA8C;QAC9C,OAAO,CAAC,IAAI,CAAC,0DAA0D,EAAE,KAAK,CAAC,CAAC;QAChF,OAAO,iBAAiB,EAAE,CAAC;IAC7B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO;IAE1C,IAAI,CAAC;QACH,cAAc,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IAEhD,IAAI,CAAC;QACH,OAAO,cAAc,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC","sourcesContent":["/**\n * Session management utility for campaign tracking\n */\n\nconst SESSION_ID_KEY = 'trustshop_inapp_session_id';\n\n/**\n * Generate a unique session ID\n */\nfunction generateSessionId(): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 15);\n return `sess_${timestamp}_${random}`;\n}\n\n/**\n * Get or create session ID\n * Session persists for the browser session (using sessionStorage)\n */\nexport function getSessionId(): string {\n if (typeof window === 'undefined') {\n return generateSessionId();\n }\n\n try {\n // Check if session ID exists in sessionStorage\n let sessionId = sessionStorage.getItem(SESSION_ID_KEY);\n \n if (!sessionId) {\n // Generate new session ID\n sessionId = generateSessionId();\n sessionStorage.setItem(SESSION_ID_KEY, sessionId);\n }\n \n return sessionId;\n } catch (error) {\n // Fallback if sessionStorage is not available\n console.warn('SessionStorage not available, using temporary session ID', error);\n return generateSessionId();\n }\n}\n\n/**\n * Clear current session\n */\nexport function clearSession(): void {\n if (typeof window === 'undefined') return;\n \n try {\n sessionStorage.removeItem(SESSION_ID_KEY);\n } catch (error) {\n console.warn('Failed to clear session', error);\n }\n}\n\n/**\n * Check if a session exists\n */\nexport function hasSession(): boolean {\n if (typeof window === 'undefined') return false;\n \n try {\n return sessionStorage.getItem(SESSION_ID_KEY) !== null;\n } catch {\n return false;\n }\n}"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datlv-trustshop/shopify-inapp-components",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "private": false,
5
5
  "description": "React TypeScript components for Shopify in-app dashboard content",
6
6
  "main": "dist/index.js",
@@ -10,8 +10,9 @@
10
10
  "dist"
11
11
  ],
12
12
  "scripts": {
13
- "build": "tsc",
14
- "dev": "tsc --watch",
13
+ "build": "tsc && node scripts/copy-translations.js",
14
+ "dev": "tsc --watch --preserveWatchOutput",
15
+ "watch": "tsc --watch --preserveWatchOutput",
15
16
  "test": "jest",
16
17
  "lint": "eslint src --ext ts,tsx",
17
18
  "type-check": "tsc --noEmit",
@@ -1,36 +0,0 @@
1
- import React, { ReactNode } from "react";
2
- import { DashboardEngine } from "../core/engine";
3
- import { DashboardData, DashboardConfig, DashboardState } from "../types";
4
- import { SDKTranslations } from "../types/translations";
5
- export interface DashboardContextValue {
6
- engine: DashboardEngine;
7
- state: DashboardState;
8
- refresh: () => Promise<void>;
9
- isInitialized: boolean;
10
- locale: string;
11
- translations: Required<SDKTranslations>;
12
- }
13
- export declare const DashboardContext: React.Context<DashboardContextValue | null>;
14
- export declare const useDashboardContext: () => DashboardContextValue;
15
- export interface DashboardProviderProps {
16
- children: ReactNode;
17
- config: DashboardConfig;
18
- locale?: string;
19
- translations?: SDKTranslations;
20
- autoInit?: boolean;
21
- autoRefreshOnLocaleChange?: boolean;
22
- onError?: (error: Error) => void;
23
- onLoad?: (data: DashboardData) => void;
24
- onLocaleChange?: (newLocale: string, oldLocale: string) => void;
25
- onFallbackUsed?: (requested: string, actual: string) => void;
26
- }
27
- /**
28
- * DashboardProvider - Lightweight provider that connects to the global manager
29
- *
30
- * Multiple providers can be used throughout the app and they will all share:
31
- * - The same engine instance
32
- * - The same data/cache
33
- * - The same locale state
34
- * - Deduplicated API calls
35
- */
36
- export declare const DashboardProvider: React.FC<DashboardProviderProps>;
@@ -1,200 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import React, { createContext, useEffect, useState, useCallback, useMemo, useRef, } from "react";
3
- import { GlobalDashboardManager } from "../core/global-manager";
4
- import { defaultTranslations } from "../translations/default";
5
- import { injectClsStyles } from "../utils/injectStyles";
6
- export const DashboardContext = createContext(null);
7
- export const useDashboardContext = () => {
8
- const context = React.useContext(DashboardContext);
9
- if (!context) {
10
- throw new Error('useDashboardContext must be used within a DashboardProvider');
11
- }
12
- return context;
13
- };
14
- /**
15
- * DashboardProvider - Lightweight provider that connects to the global manager
16
- *
17
- * Multiple providers can be used throughout the app and they will all share:
18
- * - The same engine instance
19
- * - The same data/cache
20
- * - The same locale state
21
- * - Deduplicated API calls
22
- */
23
- export const DashboardProvider = ({ children, config, locale, translations, autoInit = true, autoRefreshOnLocaleChange = true, onError, onLoad, onLocaleChange, onFallbackUsed, }) => {
24
- const [state, setState] = useState({
25
- data: null,
26
- loading: false,
27
- error: null,
28
- lastFetch: null,
29
- });
30
- // Generate unique ID for this provider instance
31
- const providerIdRef = useRef(`provider-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`);
32
- // Track if we've called onLoad for this data
33
- const lastDataRef = useRef(null);
34
- const lastLocaleRef = useRef(locale || config.locale || "en");
35
- // Get the global manager
36
- const manager = useMemo(() => GlobalDashboardManager.getInstance(), []);
37
- // Create config with current locale
38
- const currentConfig = useMemo(() => ({
39
- ...config,
40
- locale: locale || config.locale || "en",
41
- }), [config, locale]);
42
- // Inject CLS fix styles on mount (only once globally)
43
- useEffect(() => {
44
- injectClsStyles();
45
- }, []);
46
- // Register this provider
47
- useEffect(() => {
48
- const providerId = providerIdRef.current;
49
- manager.registerProvider(providerId, currentConfig, autoRefreshOnLocaleChange);
50
- return () => {
51
- manager.unregisterProvider(providerId);
52
- };
53
- }, [manager, currentConfig, autoRefreshOnLocaleChange]);
54
- // Subscribe to global state changes
55
- useEffect(() => {
56
- const providerId = providerIdRef.current;
57
- const unsubscribe = manager.subscribe(providerId, (globalState) => {
58
- setState(globalState);
59
- // Handle callbacks
60
- if (globalState.data && globalState.data !== lastDataRef.current) {
61
- lastDataRef.current = globalState.data;
62
- // Check for fallback usage
63
- if (globalState.data.fallback_used && onFallbackUsed) {
64
- onFallbackUsed(globalState.data.requested_locale || locale || "en", globalState.data.locale || "en");
65
- }
66
- if (onLoad) {
67
- onLoad(globalState.data);
68
- }
69
- }
70
- if (globalState.error && onError) {
71
- onError(globalState.error);
72
- }
73
- });
74
- return unsubscribe;
75
- }, [manager, locale, onError, onLoad, onFallbackUsed]);
76
- // Handle locale changes
77
- useEffect(() => {
78
- if (!locale)
79
- return;
80
- const currentLocale = manager.getCurrentLocale();
81
- if (currentLocale !== locale) {
82
- const oldLocale = lastLocaleRef.current;
83
- lastLocaleRef.current = locale;
84
- if (autoRefreshOnLocaleChange) {
85
- // Always call setLocale which will handle initialization if needed
86
- manager.setLocale(locale).catch((error) => {
87
- console.error('Failed to set locale:', error);
88
- if (onError) {
89
- onError(error instanceof Error ? error : new Error('Failed to set locale'));
90
- }
91
- });
92
- }
93
- else {
94
- // Just update config without refresh
95
- const engine = manager.getEngine();
96
- if (engine) {
97
- engine.updateLocale(locale);
98
- }
99
- else {
100
- // No engine yet, update config for future initialization
101
- manager.registerProvider(providerIdRef.current, currentConfig);
102
- }
103
- }
104
- if (onLocaleChange) {
105
- onLocaleChange(locale, oldLocale);
106
- }
107
- }
108
- }, [locale, manager, autoRefreshOnLocaleChange, onLocaleChange, onError, currentConfig]);
109
- // Auto-init on mount if requested
110
- useEffect(() => {
111
- if (autoInit) {
112
- // Always attempt to initialize when autoInit is true
113
- // The manager will handle deduplication
114
- manager.init(currentConfig).catch((error) => {
115
- console.error("Failed to auto-initialize dashboard:", error);
116
- if (onError) {
117
- onError(error instanceof Error
118
- ? error
119
- : new Error("Failed to initialize dashboard"));
120
- }
121
- });
122
- }
123
- }, [autoInit, manager, currentConfig, onError]);
124
- // Create refresh function
125
- const refresh = useCallback(async () => {
126
- try {
127
- await manager.refresh();
128
- }
129
- catch (error) {
130
- console.error("Failed to refresh dashboard:", error);
131
- if (onError) {
132
- onError(error instanceof Error
133
- ? error
134
- : new Error("Failed to refresh dashboard"));
135
- }
136
- throw error;
137
- }
138
- }, [manager, onError]);
139
- // Merge translations with defaults
140
- const mergedTranslations = useMemo(() => {
141
- if (!translations)
142
- return defaultTranslations;
143
- return {
144
- whatsNew: {
145
- ...defaultTranslations.whatsNew,
146
- ...translations.whatsNew,
147
- tabs: {
148
- ...defaultTranslations.whatsNew.tabs,
149
- ...translations.whatsNew?.tabs,
150
- },
151
- buttonViewAll: {
152
- ...defaultTranslations.whatsNew.buttonViewAll,
153
- ...translations.whatsNew?.buttonViewAll,
154
- },
155
- },
156
- growApps: {
157
- ...defaultTranslations.growApps,
158
- ...translations.growApps,
159
- },
160
- banner: {
161
- ...defaultTranslations.banner,
162
- ...translations.banner,
163
- },
164
- partnerIntegration: {
165
- ...defaultTranslations.partnerIntegration,
166
- ...translations.partnerIntegration,
167
- },
168
- };
169
- }, [translations]);
170
- // Get engine from manager (might be null initially)
171
- const engine = manager.getEngine();
172
- // Create stable context value
173
- const contextValue = useMemo(() => {
174
- if (!engine)
175
- return null;
176
- return {
177
- engine,
178
- state,
179
- refresh,
180
- isInitialized: manager.isInitialized(),
181
- locale: manager.getCurrentLocale(),
182
- translations: mergedTranslations,
183
- };
184
- }, [engine, state, refresh, manager, mergedTranslations]);
185
- // If engine not ready yet, we can still render children
186
- // This allows components to mount even if engine isn't initialized
187
- if (!contextValue) {
188
- // Create a placeholder context that will update once engine is ready
189
- const placeholderContext = {
190
- engine: null, // Will be replaced when ready
191
- state,
192
- refresh,
193
- isInitialized: false,
194
- locale: manager.getCurrentLocale(),
195
- translations: mergedTranslations,
196
- };
197
- return (_jsx(DashboardContext.Provider, { value: placeholderContext, children: children }));
198
- }
199
- return (_jsx(DashboardContext.Provider, { value: contextValue, children: children }));
200
- };