@sonordev/site-kit 4.0.1 → 4.1.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.
Files changed (276) hide show
  1. package/agent-manifest.json +6 -1
  2. package/dist/AnalyticsProvider-G5P5RQOA.js +31 -0
  3. package/dist/{AnalyticsProvider-UE34SYF2.js.map → AnalyticsProvider-G5P5RQOA.js.map} +1 -1
  4. package/dist/AnalyticsProvider-NGQLQL5N.mjs +10 -0
  5. package/dist/{AnalyticsProvider-NSXC6IOO.mjs.map → AnalyticsProvider-NGQLQL5N.mjs.map} +1 -1
  6. package/dist/ChatWidget-AYKZBKJH.js +20 -0
  7. package/dist/{ChatWidget-OW37OU3Z.js.map → ChatWidget-AYKZBKJH.js.map} +1 -1
  8. package/dist/ChatWidget-LPFHRK7U.mjs +11 -0
  9. package/dist/{ChatWidget-ASWCGCJJ.mjs.map → ChatWidget-LPFHRK7U.mjs.map} +1 -1
  10. package/dist/DatePicker-4WNKNNCV.mjs +4 -0
  11. package/dist/DatePicker-4WNKNNCV.mjs.map +1 -0
  12. package/dist/DatePicker-VPZR7RU3.js +13 -0
  13. package/dist/DatePicker-VPZR7RU3.js.map +1 -0
  14. package/dist/EngageWidget-HKPAJAMR.js +18 -0
  15. package/dist/{EngageWidget-MXOCMVBQ.js.map → EngageWidget-HKPAJAMR.js.map} +1 -1
  16. package/dist/EngageWidget-KDE7BYAK.mjs +9 -0
  17. package/dist/{EngageWidget-67UZ3P5P.mjs.map → EngageWidget-KDE7BYAK.mjs.map} +1 -1
  18. package/dist/FileField-DDDNSRMR.js +91 -0
  19. package/dist/FileField-DDDNSRMR.js.map +1 -0
  20. package/dist/FileField-SU4HTY4F.mjs +85 -0
  21. package/dist/FileField-SU4HTY4F.mjs.map +1 -0
  22. package/dist/{FormSpotlight-6MXGX6TU.mjs → FormSpotlight-B6TJPNYN.mjs} +7 -6
  23. package/dist/FormSpotlight-B6TJPNYN.mjs.map +1 -0
  24. package/dist/{FormSpotlight-LOR57ENP.js → FormSpotlight-M4S57VC6.js} +20 -19
  25. package/dist/FormSpotlight-M4S57VC6.js.map +1 -0
  26. package/dist/{FormStage-H35FBWTX.js → FormStage-2ASJGNOX.js} +16 -16
  27. package/dist/FormStage-2ASJGNOX.js.map +1 -0
  28. package/dist/{FormStage-ZLZD5EW4.mjs → FormStage-GH7SA6FQ.mjs} +6 -6
  29. package/dist/FormStage-GH7SA6FQ.mjs.map +1 -0
  30. package/dist/ManagedForm-D2JT3QV3.js +23 -0
  31. package/dist/ManagedForm-D2JT3QV3.js.map +1 -0
  32. package/dist/ManagedForm-RCC7NEV2.mjs +14 -0
  33. package/dist/ManagedForm-RCC7NEV2.mjs.map +1 -0
  34. package/dist/{SignalCore-HEXXYFSX.mjs → SignalCore-36PY3SRB.mjs} +5 -5
  35. package/dist/{SignalCore-HEXXYFSX.mjs.map → SignalCore-36PY3SRB.mjs.map} +1 -1
  36. package/dist/{SignalCore-EUMJIPDK.js → SignalCore-7H4ZGFZO.js} +11 -11
  37. package/dist/{SignalCore-EUMJIPDK.js.map → SignalCore-7H4ZGFZO.js.map} +1 -1
  38. package/dist/SitemapSync-AYVBNCH4.js +17 -0
  39. package/dist/{SitemapSync-HKUEDDG6.js.map → SitemapSync-AYVBNCH4.js.map} +1 -1
  40. package/dist/SitemapSync-HKAG3JU3.mjs +8 -0
  41. package/dist/{SitemapSync-T4QDPMFG.mjs.map → SitemapSync-HKAG3JU3.mjs.map} +1 -1
  42. package/dist/analytics/index.js +9 -9
  43. package/dist/analytics/index.mjs +4 -4
  44. package/dist/{chunk-ZGQUIL7L.js → chunk-2ACKOMAL.js} +105 -514
  45. package/dist/chunk-2ACKOMAL.js.map +1 -0
  46. package/dist/{chunk-52K556WM.js → chunk-2IH5FM2A.js} +14 -14
  47. package/dist/{chunk-52K556WM.js.map → chunk-2IH5FM2A.js.map} +1 -1
  48. package/dist/{chunk-PVE6G5XQ.mjs → chunk-2RJ5UHAC.mjs} +3 -3
  49. package/dist/{chunk-PVE6G5XQ.mjs.map → chunk-2RJ5UHAC.mjs.map} +1 -1
  50. package/dist/{chunk-VL2WAC22.js → chunk-3GJBSUVS.js} +14 -14
  51. package/dist/{chunk-VL2WAC22.js.map → chunk-3GJBSUVS.js.map} +1 -1
  52. package/dist/chunk-4ROQDPUE.mjs +60 -0
  53. package/dist/chunk-4ROQDPUE.mjs.map +1 -0
  54. package/dist/{chunk-4JEJTQYC.mjs → chunk-5GAOZTMW.mjs} +3 -3
  55. package/dist/{chunk-4JEJTQYC.mjs.map → chunk-5GAOZTMW.mjs.map} +1 -1
  56. package/dist/{chunk-NU5DJUVI.js → chunk-5JFJJNWS.js} +12 -192
  57. package/dist/chunk-5JFJJNWS.js.map +1 -0
  58. package/dist/{chunk-JGTIVQIN.mjs → chunk-7CYSA5EN.mjs} +3 -3
  59. package/dist/{chunk-JGTIVQIN.mjs.map → chunk-7CYSA5EN.mjs.map} +1 -1
  60. package/dist/{chunk-CTZHLX2B.mjs → chunk-7JES77WC.mjs} +5 -182
  61. package/dist/chunk-7JES77WC.mjs.map +1 -0
  62. package/dist/{chunk-DG34TZ6T.mjs → chunk-A4E6EOU4.mjs} +5 -5
  63. package/dist/{chunk-DG34TZ6T.mjs.map → chunk-A4E6EOU4.mjs.map} +1 -1
  64. package/dist/{chunk-YNIZKOEW.js → chunk-A624YYDG.js} +2 -2
  65. package/dist/{chunk-YNIZKOEW.js.map → chunk-A624YYDG.js.map} +1 -1
  66. package/dist/chunk-ANTVZSQI.mjs +183 -0
  67. package/dist/chunk-ANTVZSQI.mjs.map +1 -0
  68. package/dist/{chunk-2LKWN26R.mjs → chunk-D7IY27X5.mjs} +3 -3
  69. package/dist/{chunk-2LKWN26R.mjs.map → chunk-D7IY27X5.mjs.map} +1 -1
  70. package/dist/{chunk-QXIVUWQZ.js → chunk-DAGLPS6P.js} +8 -8
  71. package/dist/{chunk-QXIVUWQZ.js.map → chunk-DAGLPS6P.js.map} +1 -1
  72. package/dist/{chunk-XAMUTD4I.mjs → chunk-DBZU2TRZ.mjs} +3 -3
  73. package/dist/{chunk-XAMUTD4I.mjs.map → chunk-DBZU2TRZ.mjs.map} +1 -1
  74. package/dist/{chunk-I424AZPT.js → chunk-DCITIONV.js} +4 -4
  75. package/dist/{chunk-I424AZPT.js.map → chunk-DCITIONV.js.map} +1 -1
  76. package/dist/chunk-DVYYGHSG.js +285 -0
  77. package/dist/chunk-DVYYGHSG.js.map +1 -0
  78. package/dist/{chunk-62QRWS2I.mjs → chunk-FJ5EMPCK.mjs} +8 -8
  79. package/dist/{chunk-62QRWS2I.mjs.map → chunk-FJ5EMPCK.mjs.map} +1 -1
  80. package/dist/{chunk-6SHBMFYM.mjs → chunk-FNOCLT4A.mjs} +3 -3
  81. package/dist/{chunk-6SHBMFYM.mjs.map → chunk-FNOCLT4A.mjs.map} +1 -1
  82. package/dist/chunk-FQ4BDJXG.js +46 -0
  83. package/dist/chunk-FQ4BDJXG.js.map +1 -0
  84. package/dist/{chunk-EDFZ6EMM.js → chunk-FYPA5GLS.js} +15 -15
  85. package/dist/{chunk-EDFZ6EMM.js.map → chunk-FYPA5GLS.js.map} +1 -1
  86. package/dist/chunk-G7IMEY5T.mjs +44 -0
  87. package/dist/chunk-G7IMEY5T.mjs.map +1 -0
  88. package/dist/chunk-GJVC7KKL.mjs +508 -0
  89. package/dist/chunk-GJVC7KKL.mjs.map +1 -0
  90. package/dist/{chunk-Q7HLRTZA.js → chunk-HK33JRWA.js} +16 -16
  91. package/dist/{chunk-Q7HLRTZA.js.map → chunk-HK33JRWA.js.map} +1 -1
  92. package/dist/{chunk-ARBOKZAU.mjs → chunk-IUZ2RH4V.mjs} +3 -4
  93. package/dist/chunk-IUZ2RH4V.mjs.map +1 -0
  94. package/dist/{chunk-62RQTXHX.js → chunk-L6WWNP2N.js} +5 -5
  95. package/dist/{chunk-62RQTXHX.js.map → chunk-L6WWNP2N.js.map} +1 -1
  96. package/dist/chunk-LAWESLXJ.js +511 -0
  97. package/dist/chunk-LAWESLXJ.js.map +1 -0
  98. package/dist/{chunk-LYDTOFXJ.mjs → chunk-LB7LHVWI.mjs} +107 -503
  99. package/dist/chunk-LB7LHVWI.mjs.map +1 -0
  100. package/dist/{chunk-OIBQYBEL.mjs → chunk-LMKDQCU7.mjs} +3 -3
  101. package/dist/{chunk-OIBQYBEL.mjs.map → chunk-LMKDQCU7.mjs.map} +1 -1
  102. package/dist/{chunk-RZW4XVG5.js → chunk-LRHECSZK.js} +14 -14
  103. package/dist/{chunk-RZW4XVG5.js.map → chunk-LRHECSZK.js.map} +1 -1
  104. package/dist/{chunk-L5Q2ZJJM.js → chunk-MKQZVTD3.js} +6 -6
  105. package/dist/{chunk-L5Q2ZJJM.js.map → chunk-MKQZVTD3.js.map} +1 -1
  106. package/dist/chunk-MU3D5IO7.mjs +283 -0
  107. package/dist/chunk-MU3D5IO7.mjs.map +1 -0
  108. package/dist/{chunk-Z74IVGJB.mjs → chunk-MXPGAJLM.mjs} +4 -4
  109. package/dist/{chunk-Z74IVGJB.mjs.map → chunk-MXPGAJLM.mjs.map} +1 -1
  110. package/dist/{chunk-7QDTXT4N.js → chunk-NF3QVKWU.js} +6 -7
  111. package/dist/chunk-NF3QVKWU.js.map +1 -0
  112. package/dist/chunk-NSIRG3C3.js +148 -0
  113. package/dist/chunk-NSIRG3C3.js.map +1 -0
  114. package/dist/{chunk-WHGVQJG4.js → chunk-NTFLRRTQ.js} +8 -8
  115. package/dist/{chunk-WHGVQJG4.js.map → chunk-NTFLRRTQ.js.map} +1 -1
  116. package/dist/{chunk-NDB7EIOI.js → chunk-O554YMPI.js} +3 -3
  117. package/dist/{chunk-NDB7EIOI.js.map → chunk-O554YMPI.js.map} +1 -1
  118. package/dist/chunk-PKCEJWLD.mjs +6 -0
  119. package/dist/{chunk-6GFEJH4F.mjs.map → chunk-PKCEJWLD.mjs.map} +1 -1
  120. package/dist/{chunk-MJY7LYOV.mjs → chunk-QYLGVXRX.mjs} +4 -4
  121. package/dist/{chunk-MJY7LYOV.mjs.map → chunk-QYLGVXRX.mjs.map} +1 -1
  122. package/dist/chunk-R35CW6MM.js +8 -0
  123. package/dist/{chunk-34WY5XN2.js.map → chunk-R35CW6MM.js.map} +1 -1
  124. package/dist/chunk-S4U44UUD.mjs +138 -0
  125. package/dist/chunk-S4U44UUD.mjs.map +1 -0
  126. package/dist/{chunk-LDRE2ELU.js → chunk-SEH2K6NG.js} +12 -12
  127. package/dist/{chunk-LDRE2ELU.js.map → chunk-SEH2K6NG.js.map} +1 -1
  128. package/dist/chunk-TH2ANDPK.mjs +104 -0
  129. package/dist/chunk-TH2ANDPK.mjs.map +1 -0
  130. package/dist/{chunk-KHJYA64F.mjs → chunk-U2CJZ6O5.mjs} +2 -2
  131. package/dist/{chunk-KHJYA64F.mjs.map → chunk-U2CJZ6O5.mjs.map} +1 -1
  132. package/dist/{chunk-5GPFPMDQ.mjs → chunk-UDHQNYBD.mjs} +4 -4
  133. package/dist/{chunk-5GPFPMDQ.mjs.map → chunk-UDHQNYBD.mjs.map} +1 -1
  134. package/dist/chunk-UTANIZUO.js +110 -0
  135. package/dist/chunk-UTANIZUO.js.map +1 -0
  136. package/dist/{chunk-QABZPSHD.js → chunk-VJAUA77N.js} +5 -5
  137. package/dist/{chunk-QABZPSHD.js.map → chunk-VJAUA77N.js.map} +1 -1
  138. package/dist/{chunk-CBUK2XB3.js → chunk-VOYLJCHB.js} +9 -9
  139. package/dist/{chunk-CBUK2XB3.js.map → chunk-VOYLJCHB.js.map} +1 -1
  140. package/dist/{chunk-XCCW4Y3B.mjs → chunk-VPBLW4ZN.mjs} +5 -5
  141. package/dist/{chunk-XCCW4Y3B.mjs.map → chunk-VPBLW4ZN.mjs.map} +1 -1
  142. package/dist/{chunk-6535RSF5.mjs → chunk-WJJQWAG2.mjs} +3 -3
  143. package/dist/{chunk-6535RSF5.mjs.map → chunk-WJJQWAG2.mjs.map} +1 -1
  144. package/dist/chunk-WNUUVBD7.js +64 -0
  145. package/dist/chunk-WNUUVBD7.js.map +1 -0
  146. package/dist/{chunk-DPTNQVMK.mjs → chunk-XCCMVJUA.mjs} +3 -3
  147. package/dist/{chunk-DPTNQVMK.mjs.map → chunk-XCCMVJUA.mjs.map} +1 -1
  148. package/dist/chunk-XRQ47XDA.js +188 -0
  149. package/dist/chunk-XRQ47XDA.js.map +1 -0
  150. package/dist/{chunk-YGWWLTH5.js → chunk-ZDXGB3UC.js} +4 -4
  151. package/dist/{chunk-YGWWLTH5.js.map → chunk-ZDXGB3UC.js.map} +1 -1
  152. package/dist/cli/index.js +3 -3
  153. package/dist/cli/index.mjs +1 -1
  154. package/dist/client/index.js +5 -5
  155. package/dist/client/index.mjs +4 -4
  156. package/dist/cms/index.d.ts +23 -0
  157. package/dist/cms/index.d.ts.map +1 -1
  158. package/dist/cms/index.js +2 -2
  159. package/dist/cms/index.mjs +1 -1
  160. package/dist/cms/server-api.d.ts.map +1 -1
  161. package/dist/cms/server.js +4 -4
  162. package/dist/cms/server.mjs +1 -1
  163. package/dist/commerce/index.js +56 -56
  164. package/dist/commerce/index.mjs +5 -5
  165. package/dist/engage/EngageWidget.d.ts.map +1 -1
  166. package/dist/engage/dependency-contract.test.d.ts +2 -0
  167. package/dist/engage/dependency-contract.test.d.ts.map +1 -0
  168. package/dist/engage/index.js +10 -9
  169. package/dist/engage/index.js.map +1 -1
  170. package/dist/engage/index.mjs +7 -6
  171. package/dist/engage/index.mjs.map +1 -1
  172. package/dist/engage/socket-loader.d.ts +13 -0
  173. package/dist/engage/socket-loader.d.ts.map +1 -1
  174. package/dist/fleet/index.js +9 -9
  175. package/dist/fleet/index.mjs +5 -5
  176. package/dist/forms/FileField.d.ts +31 -0
  177. package/dist/forms/FileField.d.ts.map +1 -0
  178. package/dist/forms/FormClient.d.ts +10 -1
  179. package/dist/forms/FormClient.d.ts.map +1 -1
  180. package/dist/forms/FormEnhancer.d.ts +72 -0
  181. package/dist/forms/FormEnhancer.d.ts.map +1 -0
  182. package/dist/forms/FormField.d.ts +26 -3
  183. package/dist/forms/FormField.d.ts.map +1 -1
  184. package/dist/forms/FormSpotlight.d.ts.map +1 -1
  185. package/dist/forms/FormStage.d.ts.map +1 -1
  186. package/dist/forms/HoneypotField.d.ts +8 -2
  187. package/dist/forms/HoneypotField.d.ts.map +1 -1
  188. package/dist/forms/ManagedForm.d.ts +1 -1
  189. package/dist/forms/ManagedForm.d.ts.map +1 -1
  190. package/dist/forms/ServerForm.d.ts +73 -0
  191. package/dist/forms/ServerForm.d.ts.map +1 -0
  192. package/dist/forms/StaticForm.d.ts +50 -0
  193. package/dist/forms/StaticForm.d.ts.map +1 -0
  194. package/dist/forms/field-controls.d.ts +7 -0
  195. package/dist/forms/field-controls.d.ts.map +1 -0
  196. package/dist/forms/index.d.ts +7 -0
  197. package/dist/forms/index.d.ts.map +1 -1
  198. package/dist/forms/index.js +33 -557
  199. package/dist/forms/index.js.map +1 -1
  200. package/dist/forms/index.mjs +14 -550
  201. package/dist/forms/index.mjs.map +1 -1
  202. package/dist/forms/normalize-config.d.ts +18 -0
  203. package/dist/forms/normalize-config.d.ts.map +1 -0
  204. package/dist/forms/server.d.ts +5 -0
  205. package/dist/forms/server.d.ts.map +1 -1
  206. package/dist/forms/server.js +47 -0
  207. package/dist/forms/server.js.map +1 -1
  208. package/dist/forms/server.mjs +44 -1
  209. package/dist/forms/server.mjs.map +1 -1
  210. package/dist/forms/static-form.test.d.ts +2 -0
  211. package/dist/forms/static-form.test.d.ts.map +1 -0
  212. package/dist/forms/static.d.ts +17 -0
  213. package/dist/forms/static.d.ts.map +1 -0
  214. package/dist/forms/static.js +20 -0
  215. package/dist/forms/static.js.map +1 -0
  216. package/dist/forms/static.mjs +11 -0
  217. package/dist/forms/static.mjs.map +1 -0
  218. package/dist/forms/types.d.ts +7 -0
  219. package/dist/forms/types.d.ts.map +1 -1
  220. package/dist/forms/useForm.d.ts.map +1 -1
  221. package/dist/images/index.js +11 -11
  222. package/dist/images/index.mjs +4 -4
  223. package/dist/index.js +109 -109
  224. package/dist/index.mjs +9 -9
  225. package/dist/layout/client.js +9 -9
  226. package/dist/layout/client.mjs +8 -8
  227. package/dist/layout/index.js +11 -11
  228. package/dist/layout/index.mjs +9 -9
  229. package/dist/maps/index.js +5 -5
  230. package/dist/maps/index.mjs +3 -3
  231. package/dist/search/index.js +4 -4
  232. package/dist/search/index.mjs +3 -3
  233. package/dist/seo/client.js +5 -5
  234. package/dist/seo/client.mjs +4 -4
  235. package/dist/seo/index.js +14 -14
  236. package/dist/seo/index.mjs +6 -6
  237. package/dist/seo/server.js +5 -5
  238. package/dist/seo/server.mjs +1 -1
  239. package/dist/server/index.js +3 -3
  240. package/dist/server/index.mjs +2 -2
  241. package/dist/shared/build-entries.d.ts +6 -0
  242. package/dist/shared/build-entries.d.ts.map +1 -1
  243. package/dist/shared/no-cjs-require.test.d.ts +2 -0
  244. package/dist/shared/no-cjs-require.test.d.ts.map +1 -0
  245. package/dist/shared/version.d.ts +1 -1
  246. package/dist/signal/index.js +11 -11
  247. package/dist/signal/index.mjs +2 -2
  248. package/dist/{socket-loader-YEAQZ3XC.js → socket-loader-2NYBMBFQ.js} +2 -2
  249. package/dist/socket-loader-2NYBMBFQ.js.map +1 -0
  250. package/dist/{socket-loader-JHNN2QK4.mjs → socket-loader-JA2DI2RT.mjs} +2 -2
  251. package/dist/socket-loader-JA2DI2RT.mjs.map +1 -0
  252. package/dist/sync/index.js +16 -16
  253. package/dist/sync/index.mjs +4 -4
  254. package/package.json +28 -11
  255. package/dist/AnalyticsProvider-NSXC6IOO.mjs +0 -10
  256. package/dist/AnalyticsProvider-UE34SYF2.js +0 -31
  257. package/dist/ChatWidget-ASWCGCJJ.mjs +0 -10
  258. package/dist/ChatWidget-OW37OU3Z.js +0 -19
  259. package/dist/EngageWidget-67UZ3P5P.mjs +0 -9
  260. package/dist/EngageWidget-MXOCMVBQ.js +0 -18
  261. package/dist/FormSpotlight-6MXGX6TU.mjs.map +0 -1
  262. package/dist/FormSpotlight-LOR57ENP.js.map +0 -1
  263. package/dist/FormStage-H35FBWTX.js.map +0 -1
  264. package/dist/FormStage-ZLZD5EW4.mjs.map +0 -1
  265. package/dist/SitemapSync-HKUEDDG6.js +0 -17
  266. package/dist/SitemapSync-T4QDPMFG.mjs +0 -8
  267. package/dist/chunk-34WY5XN2.js +0 -8
  268. package/dist/chunk-6GFEJH4F.mjs +0 -6
  269. package/dist/chunk-7QDTXT4N.js.map +0 -1
  270. package/dist/chunk-ARBOKZAU.mjs.map +0 -1
  271. package/dist/chunk-CTZHLX2B.mjs.map +0 -1
  272. package/dist/chunk-LYDTOFXJ.mjs.map +0 -1
  273. package/dist/chunk-NU5DJUVI.js.map +0 -1
  274. package/dist/chunk-ZGQUIL7L.js.map +0 -1
  275. package/dist/socket-loader-JHNN2QK4.mjs.map +0 -1
  276. package/dist/socket-loader-YEAQZ3XC.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/forms/DatePicker.tsx"],"names":["useState","useRef","useCallback","useEffect","jsxs","jsx","week"],"mappings":"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","file":"chunk-DVYYGHSG.js","sourcesContent":["'use client'\n\nimport React, { useState, useRef, useEffect, useCallback } from 'react'\n\ninterface DatePickerProps {\n value: string // YYYY-MM-DD or empty\n onChange: (value: string) => void\n id?: string\n name?: string\n required?: boolean\n minDate?: string // YYYY-MM-DD\n placeholder?: string\n className?: string\n style?: React.CSSProperties\n}\n\nconst DAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']\nconst MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']\n\nfunction pad(n: number): string {\n return n < 10 ? `0${n}` : `${n}`\n}\n\nfunction toDateStr(y: number, m: number, d: number): string {\n return `${y}-${pad(m + 1)}-${pad(d)}`\n}\n\nfunction parseDate(str: string): { year: number; month: number; day: number } | null {\n if (!str) return null\n const [y, m, d] = str.split('-').map(Number)\n if (!y || !m || !d) return null\n return { year: y, month: m - 1, day: d }\n}\n\nfunction getDaysInMonth(year: number, month: number): number {\n return new Date(year, month + 1, 0).getDate()\n}\n\nfunction getFirstDayOfMonth(year: number, month: number): number {\n return new Date(year, month, 1).getDay()\n}\n\nfunction formatDisplay(dateStr: string): string {\n const parsed = parseDate(dateStr)\n if (!parsed) return ''\n return `${MONTHS[parsed.month]} ${parsed.day}, ${parsed.year}`\n}\n\nexport function DatePicker({\n value,\n onChange,\n id,\n name,\n required,\n minDate,\n placeholder = 'Select a date',\n className = '',\n style,\n}: DatePickerProps) {\n const today = new Date()\n const todayStr = toDateStr(today.getFullYear(), today.getMonth(), today.getDate())\n // Only restrict dates when a minDate is explicitly configured. Defaulting to\n // today silently disabled every valid day for past-date fields (birthdates).\n const effectiveMin = minDate || ''\n\n const parsed = parseDate(value)\n const [viewYear, setViewYear] = useState(parsed?.year || today.getFullYear())\n const [viewMonth, setViewMonth] = useState(parsed?.month ?? today.getMonth())\n const [open, setOpen] = useState(false)\n // Container-morph exit: the calendar plays its collapse animation before\n // unmounting, so picking a date morphs the panel back into the tile.\n const [closing, setClosing] = useState(false)\n const closeTimer = useRef<number | null>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n const closeAnimated = useCallback(() => {\n if (closeTimer.current !== null) return\n setClosing(true)\n closeTimer.current = window.setTimeout(() => {\n closeTimer.current = null\n setClosing(false)\n setOpen(false)\n }, 180)\n }, [])\n useEffect(\n () => () => {\n if (closeTimer.current !== null) window.clearTimeout(closeTimer.current)\n },\n [],\n )\n\n // Close on click outside\n useEffect(() => {\n if (!open) return\n const handler = (e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n closeAnimated()\n }\n }\n document.addEventListener('mousedown', handler)\n return () => document.removeEventListener('mousedown', handler)\n }, [open, closeAnimated])\n\n // Close on escape\n useEffect(() => {\n if (!open) return\n const handler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') closeAnimated()\n }\n window.addEventListener('keydown', handler)\n return () => window.removeEventListener('keydown', handler)\n }, [open, closeAnimated])\n\n const prevMonth = useCallback(() => {\n if (viewMonth === 0) { setViewMonth(11); setViewYear(y => y - 1) }\n else setViewMonth(m => m - 1)\n }, [viewMonth])\n\n const nextMonth = useCallback(() => {\n if (viewMonth === 11) { setViewMonth(0); setViewYear(y => y + 1) }\n else setViewMonth(m => m + 1)\n }, [viewMonth])\n\n const selectDay = useCallback((day: number) => {\n const dateStr = toDateStr(viewYear, viewMonth, day)\n onChange(dateStr)\n closeAnimated()\n }, [viewYear, viewMonth, onChange, closeAnimated])\n\n const isDisabled = useCallback((day: number): boolean => {\n const dateStr = toDateStr(viewYear, viewMonth, day)\n return dateStr < effectiveMin\n }, [viewYear, viewMonth, effectiveMin])\n\n const isSelected = useCallback((day: number): boolean => {\n if (!value) return false\n return toDateStr(viewYear, viewMonth, day) === value\n }, [viewYear, viewMonth, value])\n\n const isToday = useCallback((day: number): boolean => {\n return toDateStr(viewYear, viewMonth, day) === todayStr\n }, [viewYear, viewMonth, todayStr])\n\n // Build calendar grid\n const daysInMonth = getDaysInMonth(viewYear, viewMonth)\n const firstDay = getFirstDayOfMonth(viewYear, viewMonth)\n const weeks: (number | null)[][] = []\n let week: (number | null)[] = Array(firstDay).fill(null)\n\n for (let d = 1; d <= daysInMonth; d++) {\n week.push(d)\n if (week.length === 7) { weeks.push(week); week = [] }\n }\n if (week.length > 0) {\n while (week.length < 7) week.push(null)\n weeks.push(week)\n }\n\n return (\n <div ref={containerRef} className={`sk-datepicker ${className}`} style={{ position: 'relative', ...style }}>\n {/* Hidden native input for form submission */}\n <input type=\"hidden\" name={name} value={value || ''} />\n\n {/* Trigger button styled as input */}\n <button\n type=\"button\"\n id={id}\n onClick={() => (open ? closeAnimated() : setOpen(true))}\n aria-required={required}\n aria-expanded={open}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n padding: 'var(--sk-input-padding, 10px 12px)',\n backgroundColor: 'var(--sk-input-bg, #fff)',\n border: `1px solid ${open ? 'var(--sk-input-border-focus, #2563eb)' : 'var(--sk-input-border, #d1d5db)'}`,\n borderRadius: 'var(--sk-input-radius, 0.375rem)',\n fontSize: 'var(--sk-font-size, 14px)',\n color: value ? 'var(--sk-form-success-text, #111)' : 'var(--sk-text-tertiary, #9ca3af)',\n cursor: 'pointer',\n outline: 'none',\n textAlign: 'left',\n }}\n >\n {/* Keyed by value: the picked date stamps in with a pop as the\n calendar morphs back into the tile. */}\n <span key={value || 'empty'} className={value ? 'sk-datepicker__value--stamp' : undefined}>\n {value ? formatDisplay(value) : placeholder}\n </span>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" style={{ opacity: 0.5, flexShrink: 0 }}>\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\" />\n <line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\" />\n <line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\" />\n </svg>\n </button>\n\n {/* Calendar dropdown — morphs out of the tile (sk-cal-out) and back in\n on selection (sk-cal-in via data-sk-closing before unmount). */}\n {open && (\n <div\n className=\"sk-datepicker__pop\"\n data-sk-closing={closing ? 'true' : undefined}\n style={{\n position: 'absolute',\n top: '100%',\n left: 0,\n right: 0,\n marginTop: '4px',\n backgroundColor: 'var(--sk-input-bg, #fff)',\n border: '1px solid var(--sk-input-border, #d1d5db)',\n borderRadius: 'var(--sk-input-radius, 0.375rem)',\n boxShadow: '0 10px 25px rgba(0,0,0,0.3)',\n zIndex: 50,\n padding: '12px',\n minWidth: '280px',\n }}\n >\n {/* Month/Year header */}\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '12px' }}>\n <button\n type=\"button\"\n onClick={prevMonth}\n style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '4px 8px', color: 'var(--sk-label-color, #6b7280)', fontSize: '18px', lineHeight: 1 }}\n aria-label=\"Previous month\"\n >\n &lsaquo;\n </button>\n <span style={{ fontWeight: 600, fontSize: '14px', color: 'var(--sk-form-success-text, #111)' }}>\n {MONTHS[viewMonth]} {viewYear}\n </span>\n <button\n type=\"button\"\n onClick={nextMonth}\n style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '4px 8px', color: 'var(--sk-label-color, #6b7280)', fontSize: '18px', lineHeight: 1 }}\n aria-label=\"Next month\"\n >\n &rsaquo;\n </button>\n </div>\n\n {/* Day headers */}\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: '2px', marginBottom: '4px' }}>\n {DAYS.map(d => (\n <div key={d} style={{ textAlign: 'center', fontSize: '11px', fontWeight: 600, color: 'var(--sk-text-tertiary, #9ca3af)', padding: '4px 0', textTransform: 'uppercase', letterSpacing: '0.05em' }}>\n {d}\n </div>\n ))}\n </div>\n\n {/* Day grid */}\n {weeks.map((week, wi) => (\n <div key={wi} style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: '2px' }}>\n {week.map((day, di) => {\n if (day === null) {\n return <div key={di} style={{ padding: '6px' }} />\n }\n\n const disabled = isDisabled(day)\n const selected = isSelected(day)\n const todayMark = isToday(day)\n\n return (\n <button\n key={di}\n type=\"button\"\n disabled={disabled}\n onClick={() => selectDay(day)}\n style={{\n padding: '6px',\n textAlign: 'center',\n fontSize: '13px',\n fontWeight: selected ? 700 : todayMark ? 600 : 400,\n borderRadius: '6px',\n border: todayMark && !selected ? '1px solid var(--sk-primary, #2563eb)' : '1px solid transparent',\n background: selected ? 'var(--sk-primary, #2563eb)' : 'transparent',\n color: disabled\n ? 'var(--sk-text-tertiary, #9ca3af)'\n : selected\n ? '#fff'\n : 'var(--sk-form-success-text, #111)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.4 : 1,\n transition: 'background 0.15s, color 0.15s',\n }}\n onMouseEnter={(e) => {\n if (!disabled && !selected) {\n ;(e.target as HTMLElement).style.background = 'var(--sk-input-border, #e5e7eb)'\n }\n }}\n onMouseLeave={(e) => {\n if (!disabled && !selected) {\n ;(e.target as HTMLElement).style.background = 'transparent'\n }\n }}\n aria-label={`${MONTHS[viewMonth]} ${day}, ${viewYear}`}\n aria-selected={selected}\n >\n {day}\n </button>\n )\n })}\n </div>\n ))}\n\n {/* Today shortcut */}\n <div style={{ marginTop: '8px', textAlign: 'center' }}>\n <button\n type=\"button\"\n onClick={() => { onChange(todayStr); setOpen(false) }}\n style={{\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n fontSize: '12px',\n fontWeight: 600,\n color: 'var(--sk-primary, #2563eb)',\n padding: '4px 8px',\n }}\n >\n Today\n </button>\n </div>\n </div>\n )}\n </div>\n )\n}\n"]}
@@ -1,23 +1,23 @@
1
1
  'use client';
2
- import { resolveSiteHost, publishSiteCredential } from './chunk-DPTNQVMK.mjs';
3
- import { FleetHeartbeat } from './chunk-XCCW4Y3B.mjs';
2
+ import { resolveSiteHost, publishSiteCredential } from './chunk-XCCMVJUA.mjs';
3
+ import { FleetHeartbeat } from './chunk-VPBLW4ZN.mjs';
4
4
  import { useDeferredActivation } from './chunk-ZVBLXXNJ.mjs';
5
- import { SignalBridge } from './chunk-OIBQYBEL.mjs';
5
+ import { SignalBridge } from './chunk-LMKDQCU7.mjs';
6
6
  import { getOrCreateVisitorId, getOrCreateSessionId } from './chunk-ZZQAGCSI.mjs';
7
7
  import React, { useState, useRef, useCallback, Suspense } from 'react';
8
8
  import dynamic from 'next/dynamic';
9
9
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
10
 
11
11
  var LazyAnalyticsProvider = dynamic(
12
- () => import('./AnalyticsProvider-NSXC6IOO.mjs').then((m) => ({ default: m.AnalyticsProvider })),
12
+ () => import('./AnalyticsProvider-NGQLQL5N.mjs').then((m) => ({ default: m.AnalyticsProvider })),
13
13
  { ssr: false }
14
14
  );
15
15
  var LazyEngageWidget = dynamic(
16
- () => import('./EngageWidget-67UZ3P5P.mjs').then((m) => ({ default: m.EngageWidget })),
16
+ () => import('./EngageWidget-KDE7BYAK.mjs').then((m) => ({ default: m.EngageWidget })),
17
17
  { ssr: false }
18
18
  );
19
19
  var LazySitemapSync = dynamic(
20
- () => import('./SitemapSync-T4QDPMFG.mjs').then((m) => ({ default: m.SitemapSync })),
20
+ () => import('./SitemapSync-HKAG3JU3.mjs').then((m) => ({ default: m.SitemapSync })),
21
21
  { ssr: false }
22
22
  );
23
23
  function SiteKitClientProviders({
@@ -133,5 +133,5 @@ function SiteKitClientProviders({
133
133
  }
134
134
 
135
135
  export { SiteKitClientProviders };
136
- //# sourceMappingURL=chunk-62QRWS2I.mjs.map
137
- //# sourceMappingURL=chunk-62QRWS2I.mjs.map
136
+ //# sourceMappingURL=chunk-FJ5EMPCK.mjs.map
137
+ //# sourceMappingURL=chunk-FJ5EMPCK.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/layout/SiteKitClientProviders.tsx"],"names":[],"mappings":"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","file":"chunk-62QRWS2I.mjs","sourcesContent":["'use client'\n\n/**\n * SiteKitClientProviders — Client Island\n *\n * This is the 'use client' boundary for SiteKitLayout.\n * It composes the client-only providers (Analytics, Engage, Signal, SitemapSync)\n * that require React context or browser APIs.\n *\n * All modules are lazy-loaded via next/dynamic so their JS is only downloaded\n * when the feature is enabled — keeping the initial bundle lightweight.\n *\n * All modules share a unified identity (visitor ID + session ID) read from\n * the storage-backed singleton (shared/identity), ensuring consistent\n * tracking across Analytics, Signal, and Engage.\n *\n * 4.0 INVARIANT — CHILDREN ARE NEVER WRAPPED. Every module here renders as a\n * childless sibling AFTER {children}; nothing provides context around page\n * content. That makes the prerender-bailout / remount-flash class of bug\n * structurally impossible. Do not reintroduce a wrapper.\n *\n * Props are passed down from the server-side SiteKitLayout component,\n * which reads env vars at render time.\n */\n\nimport React, { Suspense, useCallback, useRef, useState, type ReactNode } from 'react'\nimport dynamic from 'next/dynamic'\nimport {\n getOrCreateVisitorId,\n getOrCreateSessionId,\n} from '../shared/identity'\n// Defer non-critical module mounting until the page is quiet: the lazy\n// modules below are dynamic(ssr:false) and never render on the server, but\n// rendering them during hydration still kicks off their chunk downloads +\n// mount effects inside the critical startup window. useDeferredActivation\n// holds them until window.load + idle or first interaction — the same\n// strategy as the hand-rolled per-site deferrals this replaces (upforge\n// `deferred-analytics.tsx`, TPS `DeferredAnalytics.tsx`). The hook is public\n// (`@sonordev/site-kit/client`) so sites can reuse it for their own scripts.\nimport { useDeferredActivation } from '../shared/defer'\n// Single source of truth for seeding the token manager + the __SITE_KIT_*\n// globals — shared with the public `SiteKitCredential` component that\n// non-core layouts (agency-site-kit) use. Do not re-inline it here.\nimport { publishSiteCredential, resolveSiteHost } from '../shared/publishCredential'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\n// Lazy-load feature modules — JS only downloaded when feature is enabled\nconst LazyAnalyticsProvider = dynamic(\n () => import('../analytics/AnalyticsProvider').then(m => ({ default: m.AnalyticsProvider })),\n { ssr: false },\n)\nconst LazyEngageWidget = dynamic(\n () => import('../engage/EngageWidget').then(m => ({ default: m.EngageWidget })),\n { ssr: false },\n)\nconst LazySitemapSync = dynamic(\n () => import('../SitemapSync').then(m => ({ default: m.SitemapSync })),\n { ssr: false },\n)\n// SignalBridge is imported STATICALLY, not via dynamic(ssr:false): it is a\n// tiny SSR-safe context shell that renders children immediately and\n// lazy-loads its machinery (SignalCore) as a childless sibling internally.\n// Wrapping children in a dynamic(ssr:false) component was the old SSR-bailout\n// failure mode — do not reintroduce it.\nimport { SignalBridge } from '../signal/SignalBridge'\n// Fleet heartbeat: a deferred, CHILDLESS SIBLING (like Analytics/Engage) that\n// reports this site's kit version + active modules once per session, so the\n// platform can see version drift across the fleet. Tiny and SSR-safe — renders\n// null until the shared idle gate fires; never wraps page content.\nimport { FleetHeartbeat } from '../fleet/FleetHeartbeat'\nimport type { FleetModule } from '../fleet/contract'\n\nexport interface SiteKitClientProvidersProps {\n children: ReactNode\n apiKey: string\n apiUrl: string\n projectId?: string\n analytics?: boolean | AnalyticsConfig\n engage?: boolean | EngageConfig\n signal?: boolean | SignalConfig\n sitemapSync?: boolean\n /**\n * Fleet heartbeat — reports kit version + active modules to Sonor once per\n * session so the platform can track version drift and key state across every\n * site. Default true. Deferred exactly like Analytics; never in the hydration\n * path, carries no visitor data.\n */\n fleet?: boolean\n /**\n * Defer Analytics / Engage / SitemapSync until window load + idle or first\n * interaction (default true). Pass false to restore legacy eager mounting\n * on hydration. SignalBridge is never deferred — it must apply experiment\n * variants as early as possible.\n */\n defer?: boolean\n debug?: boolean\n /** Browser-safe Google Maps key, resolved server-side by SiteKitLayout. */\n mapsBrowserKey?: string\n}\n\nexport function SiteKitClientProviders({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = true,\n fleet = true,\n defer = true,\n debug = false,\n mapsBrowserKey,\n}: SiteKitClientProvidersProps) {\n // One shared activation gate for all deferred siblings, so they mount in a\n // single commit instead of staggered re-renders.\n const modulesReady = useDeferredActivation(defer)\n // Hoist analytics config so the `site` dimension is resolvable up here.\n const analyticsConfig: AnalyticsConfig =\n typeof analytics === 'object' ? analytics : {}\n\n // Resolve the sub-site identifier — the dimension that lets one Sonor project\n // host many sites (e.g. truepowersystems.com + ohiopowerstudies.com under one\n // TPS project). Precedence lives in resolveSiteHost (shared contract):\n // explicit `analytics.site` > NEXT_PUBLIC_SITE_URL host > window.location.host.\n // Needed as a local too — SignalBridge and the analytics config read it below.\n const site = resolveSiteHost(analyticsConfig.site)\n\n // Seed the token manager + publish the window globals modules read from.\n // No-op on the server; runs during render so it lands before child effects.\n publishSiteCredential({ apiKey, apiUrl, site, debug, mapsBrowserKey })\n\n // Unified identity — single source of truth for all modules\n const [visitorId] = useState(() => getOrCreateVisitorId())\n const [sessionId] = useState(() => getOrCreateSessionId())\n\n // Page metadata bridge: Analytics writes, Signal reads\n const pageMetadataRef = useRef<Record<string, unknown> | null>(null)\n const onPageMetadata = useCallback((metadata: Record<string, unknown>) => {\n pageMetadataRef.current = metadata\n }, [])\n\n // Children render FIRST and are never re-parented. Siblings accumulate after.\n const siblings: ReactNode[] = []\n\n // SignalBridge — childless sibling (4.0: useSignal reads the module store,\n // so it no longer needs to wrap anything). Not gated on modulesReady:\n // experiment variants must apply as early as possible.\n if (signal) {\n const signalConfig: SignalConfig =\n typeof signal === 'object' ? signal : {}\n siblings.push(\n <SignalBridge\n key=\"sk-signal\"\n enabled\n realtime={signalConfig.realtime !== false}\n experiments={signalConfig.experiments !== false}\n behaviorTracking={signalConfig.behaviorTracking !== false}\n visitorId={visitorId}\n sessionId={sessionId}\n pageMetadataRef={pageMetadataRef}\n />,\n )\n }\n\n // Add Analytics if enabled (renders alongside, doesn't wrap).\n //\n // CRITICAL: LazyAnalyticsProvider is dynamic(..., { ssr: false }). Wrapping\n // {content} inside an ssr:false component makes the entire page tree skip\n // server rendering — the route de-opts to 100% client rendering and the\n // hero / LCP element only paints after hydration (mobile LCP ~4s, Lighthouse\n // ~85). Analytics tracks via effects + a metadata ref, so it never needs to\n // wrap page content — mount it as a childless sibling, exactly like Engage.\n // Each deferred sibling is appended as `{modulesReady && <Module/>}` so the\n // children slot never moves in the tree — flipping ready only mounts the\n // sibling, it never remounts page content.\n if (analytics) {\n siblings.push(\n <React.Fragment key=\"sk-analytics\">\n {modulesReady && (\n <Suspense fallback={null}>\n <LazyAnalyticsProvider\n apiUrl={apiUrl}\n apiKey={apiKey}\n site={site}\n trackPageViews={analyticsConfig.trackPageViews !== false}\n trackWebVitals={analyticsConfig.trackWebVitals !== false}\n trackScrollDepth={analyticsConfig.trackScrollDepth !== false}\n trackClicks={analyticsConfig.trackClicks !== false}\n sessionTimeout={analyticsConfig.sessionDuration}\n excludePaths={analyticsConfig.excludePaths}\n debug={debug}\n externalVisitorId={visitorId}\n externalSessionId={sessionId}\n onPageMetadata={onPageMetadata}\n />\n </Suspense>\n )}\n </React.Fragment>,\n )\n }\n\n // Engage widget — childless sibling\n if (engage) {\n const engageConfig: EngageConfig =\n typeof engage === 'object' ? engage : {}\n siblings.push(\n <React.Fragment key=\"sk-engage\">\n {modulesReady && (\n <LazyEngageWidget\n apiUrl={apiUrl}\n apiKey={apiKey}\n projectId={projectId}\n position={engageConfig.position || 'bottom-right'}\n zIndex={engageConfig.zIndex}\n chatEnabled={engageConfig.chatEnabled !== false}\n />\n )}\n </React.Fragment>,\n )\n }\n\n // SitemapSync — childless sibling\n if (sitemapSync) {\n siblings.push(\n <React.Fragment key=\"sk-sitemap\">\n {modulesReady && <LazySitemapSync debug={debug} />}\n </React.Fragment>,\n )\n }\n\n // Fleet heartbeat — childless sibling on the same modulesReady idle gate.\n // Reports the modules actually enabled on THIS layout (honest client-observable\n // set) so the platform can answer \"which version / modules is each site\n // running\". defer={false}: the modulesReady gate already handled deferral, so\n // the heartbeat fires on mount (still bounded to once per session internally).\n if (fleet) {\n const activeModules: FleetModule[] = []\n if (analytics) activeModules.push('analytics')\n if (engage) activeModules.push('engage')\n if (signal) activeModules.push('signal')\n if (sitemapSync) activeModules.push('sitemapSync')\n siblings.push(\n <React.Fragment key=\"sk-fleet\">\n {modulesReady && (\n <FleetHeartbeat\n apiUrl={apiUrl}\n apiKey={apiKey}\n site={site}\n modules={activeModules}\n defer={false}\n debug={debug}\n />\n )}\n </React.Fragment>,\n )\n }\n\n return (\n <>\n {children}\n {siblings}\n </>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/layout/SiteKitClientProviders.tsx"],"names":[],"mappings":";;;;;;;;;AA+CA,IAAM,qBAAA,GAAwB,OAAA;AAAA,EAC5B,MAAM,OAAO,kCAAgC,CAAA,CAAE,IAAA,CAAK,QAAM,EAAE,OAAA,EAAS,CAAA,CAAE,iBAAA,EAAkB,CAAE,CAAA;AAAA,EAC3F,EAAE,KAAK,KAAA;AACT,CAAA;AACA,IAAM,gBAAA,GAAmB,OAAA;AAAA,EACvB,MAAM,OAAO,6BAAwB,CAAA,CAAE,IAAA,CAAK,QAAM,EAAE,OAAA,EAAS,CAAA,CAAE,YAAA,EAAa,CAAE,CAAA;AAAA,EAC9E,EAAE,KAAK,KAAA;AACT,CAAA;AACA,IAAM,eAAA,GAAkB,OAAA;AAAA,EACtB,MAAM,OAAO,4BAAgB,CAAA,CAAE,IAAA,CAAK,QAAM,EAAE,OAAA,EAAS,CAAA,CAAE,WAAA,EAAY,CAAE,CAAA;AAAA,EACrE,EAAE,KAAK,KAAA;AACT,CAAA;AA0CO,SAAS,sBAAA,CAAuB;AAAA,EACrC,QAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA,GAAY,IAAA;AAAA,EACZ,MAAA,GAAS,IAAA;AAAA,EACT,MAAA,GAAS,KAAA;AAAA,EACT,WAAA,GAAc,IAAA;AAAA,EACd,KAAA,GAAQ,IAAA;AAAA,EACR,KAAA,GAAQ,IAAA;AAAA,EACR,KAAA,GAAQ,KAAA;AAAA,EACR;AACF,CAAA,EAAgC;AAG9B,EAAA,MAAM,YAAA,GAAe,sBAAsB,KAAK,CAAA;AAEhD,EAAA,MAAM,eAAA,GACJ,OAAO,SAAA,KAAc,QAAA,GAAW,YAAY,EAAC;AAO/C,EAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,eAAA,CAAgB,IAAI,CAAA;AAIjD,EAAA,qBAAA,CAAsB,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAO,gBAAgB,CAAA;AAGrE,EAAA,MAAM,CAAC,SAAS,CAAA,GAAI,QAAA,CAAS,MAAM,sBAAsB,CAAA;AACzD,EAAA,MAAM,CAAC,SAAS,CAAA,GAAI,QAAA,CAAS,MAAM,sBAAsB,CAAA;AAGzD,EAAA,MAAM,eAAA,GAAkB,OAAuC,IAAI,CAAA;AACnE,EAAA,MAAM,cAAA,GAAiB,WAAA,CAAY,CAAC,QAAA,KAAsC;AACxE,IAAA,eAAA,CAAgB,OAAA,GAAU,QAAA;AAAA,EAC5B,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,WAAwB,EAAC;AAK/B,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAM,YAAA,GACJ,OAAO,MAAA,KAAW,QAAA,GAAW,SAAS,EAAC;AACzC,IAAA,QAAA,CAAS,IAAA;AAAA,sBACP,GAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UAEC,OAAA,EAAO,IAAA;AAAA,UACP,QAAA,EAAU,aAAa,QAAA,KAAa,KAAA;AAAA,UACpC,WAAA,EAAa,aAAa,WAAA,KAAgB,KAAA;AAAA,UAC1C,gBAAA,EAAkB,aAAa,gBAAA,KAAqB,KAAA;AAAA,UACpD,SAAA;AAAA,UACA,SAAA;AAAA,UACA;AAAA,SAAA;AAAA,QAPI;AAAA;AAQN,KACF;AAAA,EACF;AAaA,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,QAAA,CAAS,IAAA;AAAA,sBACP,GAAA,CAAC,MAAM,QAAA,EAAN,EACE,0CACC,GAAA,CAAC,QAAA,EAAA,EAAS,UAAU,IAAA,EAClB,QAAA,kBAAA,GAAA;AAAA,QAAC,qBAAA;AAAA,QAAA;AAAA,UACC,MAAA;AAAA,UACA,MAAA;AAAA,UACA,IAAA;AAAA,UACA,cAAA,EAAgB,gBAAgB,cAAA,KAAmB,KAAA;AAAA,UACnD,cAAA,EAAgB,gBAAgB,cAAA,KAAmB,KAAA;AAAA,UACnD,gBAAA,EAAkB,gBAAgB,gBAAA,KAAqB,KAAA;AAAA,UACvD,WAAA,EAAa,gBAAgB,WAAA,KAAgB,KAAA;AAAA,UAC7C,gBAAgB,eAAA,CAAgB,eAAA;AAAA,UAChC,cAAc,eAAA,CAAgB,YAAA;AAAA,UAC9B,KAAA;AAAA,UACA,iBAAA,EAAmB,SAAA;AAAA,UACnB,iBAAA,EAAmB,SAAA;AAAA,UACnB;AAAA;AAAA,OACF,EACF,KAlBgB,cAoBpB;AAAA,KACF;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAM,YAAA,GACJ,OAAO,MAAA,KAAW,QAAA,GAAW,SAAS,EAAC;AACzC,IAAA,QAAA,CAAS,IAAA;AAAA,sBACP,GAAA,CAAC,KAAA,CAAM,QAAA,EAAN,EACE,QAAA,EAAA,YAAA,oBACC,GAAA;AAAA,QAAC,gBAAA;AAAA,QAAA;AAAA,UACC,MAAA;AAAA,UACA,MAAA;AAAA,UACA,SAAA;AAAA,UACA,QAAA,EAAU,aAAa,QAAA,IAAY,cAAA;AAAA,UACnC,QAAQ,YAAA,CAAa,MAAA;AAAA,UACrB,WAAA,EAAa,aAAa,WAAA,KAAgB;AAAA;AAAA,WAR5B,WAWpB;AAAA,KACF;AAAA,EACF;AAGA,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,QAAA,CAAS,IAAA;AAAA,sBACP,GAAA,CAAC,MAAM,QAAA,EAAN,EACE,0CAAgB,GAAA,CAAC,eAAA,EAAA,EAAgB,KAAA,EAAc,CAAA,EAAA,EAD9B,YAEpB;AAAA,KACF;AAAA,EACF;AAOA,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,MAAM,gBAA+B,EAAC;AACtC,IAAA,IAAI,SAAA,EAAW,aAAA,CAAc,IAAA,CAAK,WAAW,CAAA;AAC7C,IAAA,IAAI,MAAA,EAAQ,aAAA,CAAc,IAAA,CAAK,QAAQ,CAAA;AACvC,IAAA,IAAI,MAAA,EAAQ,aAAA,CAAc,IAAA,CAAK,QAAQ,CAAA;AACvC,IAAA,IAAI,WAAA,EAAa,aAAA,CAAc,IAAA,CAAK,aAAa,CAAA;AACjD,IAAA,QAAA,CAAS,IAAA;AAAA,sBACP,GAAA,CAAC,KAAA,CAAM,QAAA,EAAN,EACE,QAAA,EAAA,YAAA,oBACC,GAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UACC,MAAA;AAAA,UACA,MAAA;AAAA,UACA,IAAA;AAAA,UACA,OAAA,EAAS,aAAA;AAAA,UACT,KAAA,EAAO,KAAA;AAAA,UACP;AAAA;AAAA,WARc,UAWpB;AAAA,KACF;AAAA,EACF;AAEA,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,IACA;AAAA,GAAA,EACH,CAAA;AAEJ","file":"chunk-FJ5EMPCK.mjs","sourcesContent":["'use client'\n\n/**\n * SiteKitClientProviders — Client Island\n *\n * This is the 'use client' boundary for SiteKitLayout.\n * It composes the client-only providers (Analytics, Engage, Signal, SitemapSync)\n * that require React context or browser APIs.\n *\n * All modules are lazy-loaded via next/dynamic so their JS is only downloaded\n * when the feature is enabled — keeping the initial bundle lightweight.\n *\n * All modules share a unified identity (visitor ID + session ID) read from\n * the storage-backed singleton (shared/identity), ensuring consistent\n * tracking across Analytics, Signal, and Engage.\n *\n * 4.0 INVARIANT — CHILDREN ARE NEVER WRAPPED. Every module here renders as a\n * childless sibling AFTER {children}; nothing provides context around page\n * content. That makes the prerender-bailout / remount-flash class of bug\n * structurally impossible. Do not reintroduce a wrapper.\n *\n * Props are passed down from the server-side SiteKitLayout component,\n * which reads env vars at render time.\n */\n\nimport React, { Suspense, useCallback, useRef, useState, type ReactNode } from 'react'\nimport dynamic from 'next/dynamic'\nimport {\n getOrCreateVisitorId,\n getOrCreateSessionId,\n} from '../shared/identity'\n// Defer non-critical module mounting until the page is quiet: the lazy\n// modules below are dynamic(ssr:false) and never render on the server, but\n// rendering them during hydration still kicks off their chunk downloads +\n// mount effects inside the critical startup window. useDeferredActivation\n// holds them until window.load + idle or first interaction — the same\n// strategy as the hand-rolled per-site deferrals this replaces (upforge\n// `deferred-analytics.tsx`, TPS `DeferredAnalytics.tsx`). The hook is public\n// (`@sonordev/site-kit/client`) so sites can reuse it for their own scripts.\nimport { useDeferredActivation } from '../shared/defer'\n// Single source of truth for seeding the token manager + the __SITE_KIT_*\n// globals — shared with the public `SiteKitCredential` component that\n// non-core layouts (agency-site-kit) use. Do not re-inline it here.\nimport { publishSiteCredential, resolveSiteHost } from '../shared/publishCredential'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\n// Lazy-load feature modules — JS only downloaded when feature is enabled\nconst LazyAnalyticsProvider = dynamic(\n () => import('../analytics/AnalyticsProvider').then(m => ({ default: m.AnalyticsProvider })),\n { ssr: false },\n)\nconst LazyEngageWidget = dynamic(\n () => import('../engage/EngageWidget').then(m => ({ default: m.EngageWidget })),\n { ssr: false },\n)\nconst LazySitemapSync = dynamic(\n () => import('../SitemapSync').then(m => ({ default: m.SitemapSync })),\n { ssr: false },\n)\n// SignalBridge is imported STATICALLY, not via dynamic(ssr:false): it is a\n// tiny SSR-safe context shell that renders children immediately and\n// lazy-loads its machinery (SignalCore) as a childless sibling internally.\n// Wrapping children in a dynamic(ssr:false) component was the old SSR-bailout\n// failure mode — do not reintroduce it.\nimport { SignalBridge } from '../signal/SignalBridge'\n// Fleet heartbeat: a deferred, CHILDLESS SIBLING (like Analytics/Engage) that\n// reports this site's kit version + active modules once per session, so the\n// platform can see version drift across the fleet. Tiny and SSR-safe — renders\n// null until the shared idle gate fires; never wraps page content.\nimport { FleetHeartbeat } from '../fleet/FleetHeartbeat'\nimport type { FleetModule } from '../fleet/contract'\n\nexport interface SiteKitClientProvidersProps {\n children: ReactNode\n apiKey: string\n apiUrl: string\n projectId?: string\n analytics?: boolean | AnalyticsConfig\n engage?: boolean | EngageConfig\n signal?: boolean | SignalConfig\n sitemapSync?: boolean\n /**\n * Fleet heartbeat — reports kit version + active modules to Sonor once per\n * session so the platform can track version drift and key state across every\n * site. Default true. Deferred exactly like Analytics; never in the hydration\n * path, carries no visitor data.\n */\n fleet?: boolean\n /**\n * Defer Analytics / Engage / SitemapSync until window load + idle or first\n * interaction (default true). Pass false to restore legacy eager mounting\n * on hydration. SignalBridge is never deferred — it must apply experiment\n * variants as early as possible.\n */\n defer?: boolean\n debug?: boolean\n /** Browser-safe Google Maps key, resolved server-side by SiteKitLayout. */\n mapsBrowserKey?: string\n}\n\nexport function SiteKitClientProviders({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = true,\n fleet = true,\n defer = true,\n debug = false,\n mapsBrowserKey,\n}: SiteKitClientProvidersProps) {\n // One shared activation gate for all deferred siblings, so they mount in a\n // single commit instead of staggered re-renders.\n const modulesReady = useDeferredActivation(defer)\n // Hoist analytics config so the `site` dimension is resolvable up here.\n const analyticsConfig: AnalyticsConfig =\n typeof analytics === 'object' ? analytics : {}\n\n // Resolve the sub-site identifier — the dimension that lets one Sonor project\n // host many sites (e.g. truepowersystems.com + ohiopowerstudies.com under one\n // TPS project). Precedence lives in resolveSiteHost (shared contract):\n // explicit `analytics.site` > NEXT_PUBLIC_SITE_URL host > window.location.host.\n // Needed as a local too — SignalBridge and the analytics config read it below.\n const site = resolveSiteHost(analyticsConfig.site)\n\n // Seed the token manager + publish the window globals modules read from.\n // No-op on the server; runs during render so it lands before child effects.\n publishSiteCredential({ apiKey, apiUrl, site, debug, mapsBrowserKey })\n\n // Unified identity — single source of truth for all modules\n const [visitorId] = useState(() => getOrCreateVisitorId())\n const [sessionId] = useState(() => getOrCreateSessionId())\n\n // Page metadata bridge: Analytics writes, Signal reads\n const pageMetadataRef = useRef<Record<string, unknown> | null>(null)\n const onPageMetadata = useCallback((metadata: Record<string, unknown>) => {\n pageMetadataRef.current = metadata\n }, [])\n\n // Children render FIRST and are never re-parented. Siblings accumulate after.\n const siblings: ReactNode[] = []\n\n // SignalBridge — childless sibling (4.0: useSignal reads the module store,\n // so it no longer needs to wrap anything). Not gated on modulesReady:\n // experiment variants must apply as early as possible.\n if (signal) {\n const signalConfig: SignalConfig =\n typeof signal === 'object' ? signal : {}\n siblings.push(\n <SignalBridge\n key=\"sk-signal\"\n enabled\n realtime={signalConfig.realtime !== false}\n experiments={signalConfig.experiments !== false}\n behaviorTracking={signalConfig.behaviorTracking !== false}\n visitorId={visitorId}\n sessionId={sessionId}\n pageMetadataRef={pageMetadataRef}\n />,\n )\n }\n\n // Add Analytics if enabled (renders alongside, doesn't wrap).\n //\n // CRITICAL: LazyAnalyticsProvider is dynamic(..., { ssr: false }). Wrapping\n // {content} inside an ssr:false component makes the entire page tree skip\n // server rendering — the route de-opts to 100% client rendering and the\n // hero / LCP element only paints after hydration (mobile LCP ~4s, Lighthouse\n // ~85). Analytics tracks via effects + a metadata ref, so it never needs to\n // wrap page content — mount it as a childless sibling, exactly like Engage.\n // Each deferred sibling is appended as `{modulesReady && <Module/>}` so the\n // children slot never moves in the tree — flipping ready only mounts the\n // sibling, it never remounts page content.\n if (analytics) {\n siblings.push(\n <React.Fragment key=\"sk-analytics\">\n {modulesReady && (\n <Suspense fallback={null}>\n <LazyAnalyticsProvider\n apiUrl={apiUrl}\n apiKey={apiKey}\n site={site}\n trackPageViews={analyticsConfig.trackPageViews !== false}\n trackWebVitals={analyticsConfig.trackWebVitals !== false}\n trackScrollDepth={analyticsConfig.trackScrollDepth !== false}\n trackClicks={analyticsConfig.trackClicks !== false}\n sessionTimeout={analyticsConfig.sessionDuration}\n excludePaths={analyticsConfig.excludePaths}\n debug={debug}\n externalVisitorId={visitorId}\n externalSessionId={sessionId}\n onPageMetadata={onPageMetadata}\n />\n </Suspense>\n )}\n </React.Fragment>,\n )\n }\n\n // Engage widget — childless sibling\n if (engage) {\n const engageConfig: EngageConfig =\n typeof engage === 'object' ? engage : {}\n siblings.push(\n <React.Fragment key=\"sk-engage\">\n {modulesReady && (\n <LazyEngageWidget\n apiUrl={apiUrl}\n apiKey={apiKey}\n projectId={projectId}\n position={engageConfig.position || 'bottom-right'}\n zIndex={engageConfig.zIndex}\n chatEnabled={engageConfig.chatEnabled !== false}\n />\n )}\n </React.Fragment>,\n )\n }\n\n // SitemapSync — childless sibling\n if (sitemapSync) {\n siblings.push(\n <React.Fragment key=\"sk-sitemap\">\n {modulesReady && <LazySitemapSync debug={debug} />}\n </React.Fragment>,\n )\n }\n\n // Fleet heartbeat — childless sibling on the same modulesReady idle gate.\n // Reports the modules actually enabled on THIS layout (honest client-observable\n // set) so the platform can answer \"which version / modules is each site\n // running\". defer={false}: the modulesReady gate already handled deferral, so\n // the heartbeat fires on mount (still bounded to once per session internally).\n if (fleet) {\n const activeModules: FleetModule[] = []\n if (analytics) activeModules.push('analytics')\n if (engage) activeModules.push('engage')\n if (signal) activeModules.push('signal')\n if (sitemapSync) activeModules.push('sitemapSync')\n siblings.push(\n <React.Fragment key=\"sk-fleet\">\n {modulesReady && (\n <FleetHeartbeat\n apiUrl={apiUrl}\n apiKey={apiKey}\n site={site}\n modules={activeModules}\n defer={false}\n debug={debug}\n />\n )}\n </React.Fragment>,\n )\n }\n\n return (\n <>\n {children}\n {siblings}\n </>\n )\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { useSignalExperiment, useSignalEvent } from './chunk-OIBQYBEL.mjs';
2
+ import { useSignalExperiment, useSignalEvent } from './chunk-LMKDQCU7.mjs';
3
3
  import React, { useEffect } from 'react';
4
4
  import { jsx, Fragment } from 'react/jsx-runtime';
5
5
 
@@ -71,5 +71,5 @@ function ExperimentConversion({
71
71
  }
72
72
 
73
73
  export { ExperimentConversion, SignalExperiment, useExperimentVariant };
74
- //# sourceMappingURL=chunk-6SHBMFYM.mjs.map
75
- //# sourceMappingURL=chunk-6SHBMFYM.mjs.map
74
+ //# sourceMappingURL=chunk-FNOCLT4A.mjs.map
75
+ //# sourceMappingURL=chunk-FNOCLT4A.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/signal/SignalExperiment.tsx"],"names":[],"mappings":";;;;AAgDO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,YAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA,GAAkB,IAAA;AAAA,EAClB;AACF,CAAA,EAA0B;AACxB,EAAA,MAAM,EAAE,UAAA,EAAY,OAAA,EAAS,SAAA,EAAU,GAAI,oBAAoB,YAAY,CAAA;AAC3E,EAAA,MAAM,aAAa,cAAA,EAAe;AAGlC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,mBAAmB,OAAA,EAAS;AAC9B,MAAA,UAAA,CAAW;AAAA,QACT,UAAA,EAAY,YAAA;AAAA,QACZ,UAAA,EAAY,YAAA;AAAA,QACZ,UAAA,EAAY;AAAA,UACV,aAAA,EAAe,YAAA;AAAA,UACf,WAAA,EAAa;AAAA;AACf,OACD,CAAA;AAAA,IACH;AAAA,EACF,GAAG,CAAC,YAAA,EAAc,OAAA,EAAS,eAAA,EAAiB,UAAU,CAAC,CAAA;AAGvD,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAG,mBAAS,EAAE,OAAA,EAAS,WAAW,SAAA,EAAW,SAAA,EAAW,CAAA,EAAE,CAAA;AAAA,EACnE;AAGA,EAAA,MAAM,kBAAkB,OAAA,IAAW,SAAA;AACnC,EAAA,MAAM,OAAA,GAAU,SAAS,eAAe,CAAA;AAExC,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,uCAAU,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,EACpB;AAGA,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,uCAAU,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,EACrB;AAEA,EAAA,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAA,QAAA,CAAS,OAAA,IAAW,IAAA,EAAK,CAAA;AACrC;AAYO,SAAS,qBAAqB,YAAA,EAAsB;AACzD,EAAA,OAAO,oBAAoB,YAAY,CAAA;AACzC;AAoBO,SAAS,oBAAA,CAAqB;AAAA,EACnC,YAAA;AAAA,EACA,WAAA,GAAc,OAAA;AAAA,EACd,KAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAA,MAAM,aAAa,cAAA,EAAe;AAClC,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,mBAAA,CAAoB,YAAY,CAAA;AAEpD,EAAA,MAAM,oBAAoB,MAAM;AAC9B,IAAA,UAAA,CAAW;AAAA,MACT,UAAA,EAAY,YAAA;AAAA,MACZ,UAAA,EAAY,YAAA;AAAA,MACZ,UAAA,EAAY;AAAA,QACV,aAAA,EAAe,YAAA;AAAA,QACf,WAAA,EAAa,OAAA;AAAA,QACb,YAAA,EAAc,WAAA;AAAA,QACd;AAAA;AACF,KACD,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,OAAO,KAAA,CAAM,aAAa,QAAA,EAAU;AAAA,IAClC,OAAA,EAAS,CAAC,CAAA,KAAwB;AAChC,MAAA,iBAAA,EAAkB;AAElB,MAAA,IAAK,QAAA,CAAS,MAAsD,OAAA,EAAS;AAC3E,QAAC,QAAA,CAAS,KAAA,CAAsD,OAAA,CAAS,CAAC,CAAA;AAAA,MAC5E;AAAA,IACF;AAAA,GACD,CAAA;AACH","file":"chunk-6SHBMFYM.mjs","sourcesContent":["/**\n * @sonordev/site-kit/signal - SignalExperiment\n * \n * A/B test component that renders different variants based on Signal assignment.\n * Uses Thompson Sampling (Bayesian bandit) for optimization.\n */\n\n'use client'\n\nimport React, { useMemo, useEffect } from 'react'\nimport { useSignalExperiment, useSignalEvent } from './SignalBridge'\n\ninterface SignalExperimentProps {\n /** Unique experiment ID */\n experimentId: string\n \n /** Variants to test - keys are variant names, values are React nodes */\n variants: Record<string, React.ReactNode>\n \n /** Fallback content if no assignment (defaults to 'control' variant) */\n fallback?: React.ReactNode\n \n /** Track impression automatically */\n trackImpression?: boolean\n \n /** Children function for more control */\n children?: (props: { variant: string; isControl: boolean }) => React.ReactNode\n}\n\n/**\n * Renders different content variants based on Signal's A/B assignment.\n * \n * @example\n * // Simple variant switching\n * <SignalExperiment experimentId=\"hero-cta\" variants={{\n * control: <Button>Get Started</Button>,\n * variant_a: <Button variant=\"primary\">Start Free Trial</Button>,\n * variant_b: <Button variant=\"secondary\">Book a Demo</Button>,\n * }} />\n * \n * @example\n * // With render prop for more control\n * <SignalExperiment experimentId=\"pricing-layout\">\n * {({ variant, isControl }) => (\n * <PricingSection layout={isControl ? 'cards' : 'table'} />\n * )}\n * </SignalExperiment>\n */\nexport function SignalExperiment({\n experimentId,\n variants,\n fallback,\n trackImpression = true,\n children,\n}: SignalExperimentProps) {\n const { assignment, variant, isControl } = useSignalExperiment(experimentId)\n const trackEvent = useSignalEvent()\n \n // Track impression when variant is rendered\n useEffect(() => {\n if (trackImpression && variant) {\n trackEvent({\n event_type: 'experiment',\n event_name: 'impression',\n event_data: {\n experiment_id: experimentId,\n variant_key: variant,\n },\n })\n }\n }, [experimentId, variant, trackImpression, trackEvent])\n \n // If using render prop\n if (children) {\n return <>{children({ variant: variant || 'control', isControl })}</>\n }\n \n // Determine what to render\n const selectedVariant = variant || 'control'\n const content = variants[selectedVariant]\n \n if (content !== undefined) {\n return <>{content}</>\n }\n \n // Fallback to provided fallback or control\n if (fallback) {\n return <>{fallback}</>\n }\n \n return <>{variants.control || null}</>\n}\n\n/**\n * Hook for conditional experiment logic\n * \n * @example\n * const { variant, isControl } = useExperimentVariant('pricing-test')\n * \n * return isControl \n * ? <OldPricing />\n * : <NewPricing showAnnual={variant === 'annual_first'} />\n */\nexport function useExperimentVariant(experimentId: string) {\n return useSignalExperiment(experimentId)\n}\n\n/**\n * Component for tracking experiment conversions\n * Wraps interactive elements to track when they convert\n * \n * @example\n * <SignalExperiment experimentId=\"signup-button\" variants={{\n * control: (\n * <ExperimentConversion experimentId=\"signup-button\" outcomeType=\"click\">\n * <Button>Sign Up</Button>\n * </ExperimentConversion>\n * ),\n * variant_a: (\n * <ExperimentConversion experimentId=\"signup-button\" outcomeType=\"click\">\n * <Button variant=\"large\">Join Now - It's Free!</Button>\n * </ExperimentConversion>\n * ),\n * }} />\n */\nexport function ExperimentConversion({\n experimentId,\n outcomeType = 'click',\n value,\n children,\n}: {\n experimentId: string\n outcomeType?: string\n value?: number\n children: React.ReactElement<{ onClick?: (e: React.MouseEvent) => void }>\n}) {\n const trackEvent = useSignalEvent()\n const { variant } = useSignalExperiment(experimentId)\n\n const handleInteraction = () => {\n trackEvent({\n event_type: 'experiment',\n event_name: 'conversion',\n event_data: {\n experiment_id: experimentId,\n variant_key: variant,\n outcome_type: outcomeType,\n value,\n },\n })\n }\n\n return React.cloneElement(children, {\n onClick: (e: React.MouseEvent) => {\n handleInteraction()\n // Call original onClick if exists\n if ((children.props as { onClick?: (e: React.MouseEvent) => void }).onClick) {\n (children.props as { onClick?: (e: React.MouseEvent) => void }).onClick!(e)\n }\n },\n })\n}\n"]}
1
+ {"version":3,"sources":["../src/signal/SignalExperiment.tsx"],"names":[],"mappings":";;;;AAgDO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,YAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA,GAAkB,IAAA;AAAA,EAClB;AACF,CAAA,EAA0B;AACxB,EAAA,MAAM,EAAE,UAAA,EAAY,OAAA,EAAS,SAAA,EAAU,GAAI,oBAAoB,YAAY,CAAA;AAC3E,EAAA,MAAM,aAAa,cAAA,EAAe;AAGlC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,mBAAmB,OAAA,EAAS;AAC9B,MAAA,UAAA,CAAW;AAAA,QACT,UAAA,EAAY,YAAA;AAAA,QACZ,UAAA,EAAY,YAAA;AAAA,QACZ,UAAA,EAAY;AAAA,UACV,aAAA,EAAe,YAAA;AAAA,UACf,WAAA,EAAa;AAAA;AACf,OACD,CAAA;AAAA,IACH;AAAA,EACF,GAAG,CAAC,YAAA,EAAc,OAAA,EAAS,eAAA,EAAiB,UAAU,CAAC,CAAA;AAGvD,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAG,mBAAS,EAAE,OAAA,EAAS,WAAW,SAAA,EAAW,SAAA,EAAW,CAAA,EAAE,CAAA;AAAA,EACnE;AAGA,EAAA,MAAM,kBAAkB,OAAA,IAAW,SAAA;AACnC,EAAA,MAAM,OAAA,GAAU,SAAS,eAAe,CAAA;AAExC,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,uCAAU,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,EACpB;AAGA,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,uCAAU,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,EACrB;AAEA,EAAA,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAA,QAAA,CAAS,OAAA,IAAW,IAAA,EAAK,CAAA;AACrC;AAYO,SAAS,qBAAqB,YAAA,EAAsB;AACzD,EAAA,OAAO,oBAAoB,YAAY,CAAA;AACzC;AAoBO,SAAS,oBAAA,CAAqB;AAAA,EACnC,YAAA;AAAA,EACA,WAAA,GAAc,OAAA;AAAA,EACd,KAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAA,MAAM,aAAa,cAAA,EAAe;AAClC,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,mBAAA,CAAoB,YAAY,CAAA;AAEpD,EAAA,MAAM,oBAAoB,MAAM;AAC9B,IAAA,UAAA,CAAW;AAAA,MACT,UAAA,EAAY,YAAA;AAAA,MACZ,UAAA,EAAY,YAAA;AAAA,MACZ,UAAA,EAAY;AAAA,QACV,aAAA,EAAe,YAAA;AAAA,QACf,WAAA,EAAa,OAAA;AAAA,QACb,YAAA,EAAc,WAAA;AAAA,QACd;AAAA;AACF,KACD,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,OAAO,KAAA,CAAM,aAAa,QAAA,EAAU;AAAA,IAClC,OAAA,EAAS,CAAC,CAAA,KAAwB;AAChC,MAAA,iBAAA,EAAkB;AAElB,MAAA,IAAK,QAAA,CAAS,MAAsD,OAAA,EAAS;AAC3E,QAAC,QAAA,CAAS,KAAA,CAAsD,OAAA,CAAS,CAAC,CAAA;AAAA,MAC5E;AAAA,IACF;AAAA,GACD,CAAA;AACH","file":"chunk-FNOCLT4A.mjs","sourcesContent":["/**\n * @sonordev/site-kit/signal - SignalExperiment\n * \n * A/B test component that renders different variants based on Signal assignment.\n * Uses Thompson Sampling (Bayesian bandit) for optimization.\n */\n\n'use client'\n\nimport React, { useMemo, useEffect } from 'react'\nimport { useSignalExperiment, useSignalEvent } from './SignalBridge'\n\ninterface SignalExperimentProps {\n /** Unique experiment ID */\n experimentId: string\n \n /** Variants to test - keys are variant names, values are React nodes */\n variants: Record<string, React.ReactNode>\n \n /** Fallback content if no assignment (defaults to 'control' variant) */\n fallback?: React.ReactNode\n \n /** Track impression automatically */\n trackImpression?: boolean\n \n /** Children function for more control */\n children?: (props: { variant: string; isControl: boolean }) => React.ReactNode\n}\n\n/**\n * Renders different content variants based on Signal's A/B assignment.\n * \n * @example\n * // Simple variant switching\n * <SignalExperiment experimentId=\"hero-cta\" variants={{\n * control: <Button>Get Started</Button>,\n * variant_a: <Button variant=\"primary\">Start Free Trial</Button>,\n * variant_b: <Button variant=\"secondary\">Book a Demo</Button>,\n * }} />\n * \n * @example\n * // With render prop for more control\n * <SignalExperiment experimentId=\"pricing-layout\">\n * {({ variant, isControl }) => (\n * <PricingSection layout={isControl ? 'cards' : 'table'} />\n * )}\n * </SignalExperiment>\n */\nexport function SignalExperiment({\n experimentId,\n variants,\n fallback,\n trackImpression = true,\n children,\n}: SignalExperimentProps) {\n const { assignment, variant, isControl } = useSignalExperiment(experimentId)\n const trackEvent = useSignalEvent()\n \n // Track impression when variant is rendered\n useEffect(() => {\n if (trackImpression && variant) {\n trackEvent({\n event_type: 'experiment',\n event_name: 'impression',\n event_data: {\n experiment_id: experimentId,\n variant_key: variant,\n },\n })\n }\n }, [experimentId, variant, trackImpression, trackEvent])\n \n // If using render prop\n if (children) {\n return <>{children({ variant: variant || 'control', isControl })}</>\n }\n \n // Determine what to render\n const selectedVariant = variant || 'control'\n const content = variants[selectedVariant]\n \n if (content !== undefined) {\n return <>{content}</>\n }\n \n // Fallback to provided fallback or control\n if (fallback) {\n return <>{fallback}</>\n }\n \n return <>{variants.control || null}</>\n}\n\n/**\n * Hook for conditional experiment logic\n * \n * @example\n * const { variant, isControl } = useExperimentVariant('pricing-test')\n * \n * return isControl \n * ? <OldPricing />\n * : <NewPricing showAnnual={variant === 'annual_first'} />\n */\nexport function useExperimentVariant(experimentId: string) {\n return useSignalExperiment(experimentId)\n}\n\n/**\n * Component for tracking experiment conversions\n * Wraps interactive elements to track when they convert\n * \n * @example\n * <SignalExperiment experimentId=\"signup-button\" variants={{\n * control: (\n * <ExperimentConversion experimentId=\"signup-button\" outcomeType=\"click\">\n * <Button>Sign Up</Button>\n * </ExperimentConversion>\n * ),\n * variant_a: (\n * <ExperimentConversion experimentId=\"signup-button\" outcomeType=\"click\">\n * <Button variant=\"large\">Join Now - It's Free!</Button>\n * </ExperimentConversion>\n * ),\n * }} />\n */\nexport function ExperimentConversion({\n experimentId,\n outcomeType = 'click',\n value,\n children,\n}: {\n experimentId: string\n outcomeType?: string\n value?: number\n children: React.ReactElement<{ onClick?: (e: React.MouseEvent) => void }>\n}) {\n const trackEvent = useSignalEvent()\n const { variant } = useSignalExperiment(experimentId)\n\n const handleInteraction = () => {\n trackEvent({\n event_type: 'experiment',\n event_name: 'conversion',\n event_data: {\n experiment_id: experimentId,\n variant_key: variant,\n outcome_type: outcomeType,\n value,\n },\n })\n }\n\n return React.cloneElement(children, {\n onClick: (e: React.MouseEvent) => {\n handleInteraction()\n // Call original onClick if exists\n if ((children.props as { onClick?: (e: React.MouseEvent) => void }).onClick) {\n (children.props as { onClick?: (e: React.MouseEvent) => void }).onClick!(e)\n }\n },\n })\n}\n"]}
@@ -0,0 +1,46 @@
1
+ 'use strict';
2
+
3
+ var chunkWNUUVBD7_js = require('./chunk-WNUUVBD7.js');
4
+ var chunk2ACKOMAL_js = require('./chunk-2ACKOMAL.js');
5
+ var chunkXRQ47XDA_js = require('./chunk-XRQ47XDA.js');
6
+ var chunkKHPJ3CEL_js = require('./chunk-KHPJ3CEL.js');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ function visibleStaticFields(config) {
10
+ const all = config.fields || [];
11
+ if (!config.is_multi_step) return all;
12
+ const firstStepId = config.steps?.[0]?.id;
13
+ return all.filter((f) => !f.step_id || f.step_id === firstStepId);
14
+ }
15
+ function StaticForm({ config: raw, className, nativeReturnTo }) {
16
+ if (!raw) return null;
17
+ const config = chunkXRQ47XDA_js.normalizeFormConfig(raw);
18
+ const fields = visibleStaticFields(config);
19
+ const honeypotFieldName = config.honeypot_field || chunkKHPJ3CEL_js.DEFAULT_HONEYPOT_FIELD;
20
+ return /* @__PURE__ */ jsxRuntime.jsxs(
21
+ "form",
22
+ {
23
+ "data-sk-state": "idle",
24
+ "data-sk-mount": "shell",
25
+ className: `sk-form ${className || ""}`,
26
+ ...chunkWNUUVBD7_js.nativeFormProps(config),
27
+ children: [
28
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sk-form__step", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sk-form__fields", children: fields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
29
+ "div",
30
+ {
31
+ className: `sk-form__field-wrapper sk-form__field-wrapper--${field.width || "full"}`,
32
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunk2ACKOMAL_js.FormField, { field, value: field.default_value ?? "" })
33
+ },
34
+ field.id || field.slug
35
+ )) }) }),
36
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sk-form__actions", style: { justifyContent: "flex-end" }, children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", className: "sk-form__btn sk-form__btn--submit", children: config.submit_button_text || "Submit" }) }),
37
+ config.honeypot_enabled && /* @__PURE__ */ jsxRuntime.jsx(chunkWNUUVBD7_js.HoneypotField, { name: honeypotFieldName }),
38
+ /* @__PURE__ */ jsxRuntime.jsx(chunkWNUUVBD7_js.NativeFallbackFields, { config, returnTo: nativeReturnTo })
39
+ ]
40
+ }
41
+ );
42
+ }
43
+
44
+ exports.StaticForm = StaticForm;
45
+ //# sourceMappingURL=chunk-FQ4BDJXG.js.map
46
+ //# sourceMappingURL=chunk-FQ4BDJXG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/forms/StaticForm.tsx"],"names":["normalizeFormConfig","DEFAULT_HONEYPOT_FIELD","jsxs","nativeFormProps","jsx","FormField","HoneypotField","NativeFallbackFields"],"mappings":";;;;;;;;AA6DA,SAAS,oBAAoB,MAAA,EAA2B;AACtD,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,MAAA,IAAU,EAAC;AAC9B,EAAA,IAAI,CAAC,MAAA,CAAO,aAAA,EAAe,OAAO,GAAA;AAGlC,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,KAAA,GAAQ,CAAC,CAAA,EAAG,EAAA;AACvC,EAAA,OAAO,GAAA,CAAI,OAAO,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,OAAA,KAAY,WAAW,CAAA;AAClE;AAEO,SAAS,WAAW,EAAE,MAAA,EAAQ,GAAA,EAAK,SAAA,EAAW,gBAAe,EAAoB;AACtF,EAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,EAAA,MAAM,MAAA,GAASA,qCAAoB,GAAU,CAAA;AAC7C,EAAA,MAAM,MAAA,GAAS,oBAAoB,MAAM,CAAA;AACzC,EAAA,MAAM,iBAAA,GAAoB,OAAO,cAAA,IAAkBC,uCAAA;AAEnD,EAAA,uBACEC,eAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MAGC,eAAA,EAAc,MAAA;AAAA,MACd,eAAA,EAAc,OAAA;AAAA,MACd,SAAA,EAAW,CAAA,QAAA,EAAW,SAAA,IAAa,EAAE,CAAA,CAAA;AAAA,MACpC,GAAGC,iCAAgB,MAAM,CAAA;AAAA,MAE1B,QAAA,EAAA;AAAA,wBAAAC,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EACb,QAAA,kBAAAA,cAAA,CAAC,KAAA,EAAA,EAAI,WAAU,iBAAA,EACZ,QAAA,EAAA,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,qBACXA,cAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YAEC,SAAA,EAAW,CAAA,+CAAA,EAAkD,KAAA,CAAM,KAAA,IAAS,MAAM,CAAA,CAAA;AAAA,YAGlF,yCAACC,0BAAA,EAAA,EAAU,KAAA,EAAc,KAAA,EAAO,KAAA,CAAM,iBAAiB,EAAA,EAAI;AAAA,WAAA;AAAA,UAJtD,KAAA,CAAM,MAAM,KAAA,CAAM;AAAA,SAM1B,GACH,CAAA,EACF,CAAA;AAAA,uCAEC,KAAA,EAAA,EAAI,SAAA,EAAU,oBAAmB,KAAA,EAAO,EAAE,gBAAgB,UAAA,EAAW,EACpE,QAAA,kBAAAD,cAAA,CAAC,QAAA,EAAA,EAAO,MAAK,QAAA,EAAS,SAAA,EAAU,qCAC7B,QAAA,EAAA,MAAA,CAAO,kBAAA,IAAsB,UAChC,CAAA,EACF,CAAA;AAAA,QAIC,MAAA,CAAO,gBAAA,oBAAoBA,cAAA,CAACE,8BAAA,EAAA,EAAc,MAAM,iBAAA,EAAmB,CAAA;AAAA,wBAGpEF,cAAA,CAACG,qCAAA,EAAA,EAAqB,MAAA,EAAgB,QAAA,EAAU,cAAA,EAAgB;AAAA;AAAA;AAAA,GAClE;AAEJ","file":"chunk-FQ4BDJXG.js","sourcesContent":["/**\n * StaticForm — a complete, submittable managed form with ZERO client JavaScript.\n *\n * No `'use client'`. This renders in a Server Component, and what it emits is\n * a real `<form>`: every field, the honeypot, the signed native token, and a\n * submit button. With JavaScript disabled, off, or still downloading, the\n * browser performs an ordinary form-encoded POST to\n * `/api/public/forms/submit-native`, sonor-api runs the honeypot +\n * render-timestamp + quarantine stack, and the lead lands. 4.0.1 built that\n * endpoint; this is what finally puts it under every form by default.\n *\n * ── Why this exists ─────────────────────────────────────────────────────\n *\n * ManagedForm was a client component for historical reasons that no longer\n * hold: it used to fetch its own config (getFormConfig removed that) and it\n * could only submit via JSON (the native endpoint removed that). Nobody moved\n * the boundary afterward, so every site that rendered a form paid for the\n * whole forms runtime — validation, spotlight, celebration, momentum — as an\n * INITIAL script, on the LCP-critical path.\n *\n * Measured on upforge.io's homepage: 48 KB of form code in the initial chunk\n * set cost 6 Lighthouse points (88 -> 82, LCP 3.8s -> 4.7s). Deferring the\n * client component recovered the score but deleted the form from the HTML,\n * taking the no-JS floor and crawlable fields with it. Neither half was\n * acceptable; a server-rendered form is what makes both true at once.\n *\n * Pair it with <FormEnhancer> to upgrade this markup at idle. Alone, it is\n * still a working form — that is the point. Never make this file `'use\n * client'`, and never import a hook into it.\n */\n\nimport React from 'react'\nimport { DEFAULT_HONEYPOT_FIELD } from './contract'\nimport { FormField } from './FormField'\nimport { HoneypotField } from './HoneypotField'\nimport { nativeFormProps, NativeFallbackFields } from './native-fallback'\nimport { normalizeFormConfig } from './normalize-config'\nimport type { ManagedFormConfig } from './types'\n\nexport interface StaticFormProps {\n /**\n * RAW /api/public/forms/config payload from `getFormConfig`, or an\n * already-normalized config. Normalized here through the SAME function the\n * client fetch uses, so the shell and the enhancement cannot disagree about\n * field order, step count, or success copy.\n */\n config: Record<string, unknown> | ManagedFormConfig | null | undefined\n className?: string\n /**\n * Absolute URL the no-JS 303 should return to (usually the page hosting the\n * form). Without it the API falls back to the Referer origin — right site,\n * wrong page.\n */\n nativeReturnTo?: string\n}\n\n/**\n * Fields the static shell can render meaningfully. Conditional logic is a\n * runtime concern (it depends on values the visitor has not entered yet), so\n * a conditional field renders here and the enhancement takes over hiding it.\n */\nfunction visibleStaticFields(config: ManagedFormConfig) {\n const all = config.fields || []\n if (!config.is_multi_step) return all\n // Multi-step is JS-only navigation and is excluded from native POST, so the\n // shell shows step one as a preview of what the form asks for.\n const firstStepId = config.steps?.[0]?.id\n return all.filter((f) => !f.step_id || f.step_id === firstStepId)\n}\n\nexport function StaticForm({ config: raw, className, nativeReturnTo }: StaticFormProps) {\n if (!raw) return null\n const config = normalizeFormConfig(raw as any)\n const fields = visibleStaticFields(config)\n const honeypotFieldName = config.honeypot_field || DEFAULT_HONEYPOT_FIELD\n\n return (\n <form\n // Matches FormClient's classic branch attribute-for-attribute so the\n // enhancement swap is invisible. Change one, change the other.\n data-sk-state=\"idle\"\n data-sk-mount=\"shell\"\n className={`sk-form ${className || ''}`}\n {...nativeFormProps(config)}\n >\n <div className=\"sk-form__step\">\n <div className=\"sk-form__fields\">\n {fields.map((field) => (\n <div\n key={field.id || field.slug}\n className={`sk-form__field-wrapper sk-form__field-wrapper--${field.width || 'full'}`}\n >\n {/* No onChange — FormField renders native uncontrolled controls. */}\n <FormField field={field} value={field.default_value ?? ''} />\n </div>\n ))}\n </div>\n </div>\n\n <div className=\"sk-form__actions\" style={{ justifyContent: 'flex-end' }}>\n <button type=\"submit\" className=\"sk-form__btn sk-form__btn--submit\">\n {config.submit_button_text || 'Submit'}\n </button>\n </div>\n\n {/* Same trap the hydrated form uses; no state needed because the value\n is read and stripped server-side. */}\n {config.honeypot_enabled && <HoneypotField name={honeypotFieldName} />}\n\n {/* _sk_token auth + _sk_return destination for the native POST. */}\n <NativeFallbackFields config={config} returnTo={nativeReturnTo} />\n </form>\n )\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkYGWWLTH5_js = require('./chunk-YGWWLTH5.js');
4
- var chunk34WY5XN2_js = require('./chunk-34WY5XN2.js');
3
+ var chunkZDXGB3UC_js = require('./chunk-ZDXGB3UC.js');
4
+ var chunkR35CW6MM_js = require('./chunk-R35CW6MM.js');
5
5
 
6
6
  // src/shared/fetchWithRetry.ts
7
7
  function backoffDelay(attempt, response) {
@@ -50,7 +50,7 @@ var pausedKeys = (() => {
50
50
  var warnedThisPage = false;
51
51
  function isAuthPaused(credential) {
52
52
  if (typeof window === "undefined") return false;
53
- const id = chunkYGWWLTH5_js.credentialBreakerId(credential);
53
+ const id = chunkZDXGB3UC_js.credentialBreakerId(credential);
54
54
  const until = pausedKeys.get(id);
55
55
  if (!until) return false;
56
56
  if (Date.now() >= until) {
@@ -60,7 +60,7 @@ function isAuthPaused(credential) {
60
60
  return true;
61
61
  }
62
62
  function tripBreaker(credential) {
63
- pausedKeys.set(chunkYGWWLTH5_js.credentialBreakerId(credential), Date.now() + AUTH_BREAK_MS);
63
+ pausedKeys.set(chunkZDXGB3UC_js.credentialBreakerId(credential), Date.now() + AUTH_BREAK_MS);
64
64
  if (!warnedThisPage) {
65
65
  warnedThisPage = true;
66
66
  console.info(
@@ -70,13 +70,13 @@ function tripBreaker(credential) {
70
70
  }
71
71
  async function sonorFetch(url, init = {}, options = {}) {
72
72
  let credential = options.apiKey;
73
- if (credential !== void 0 || chunkYGWWLTH5_js.isTokenMode()) {
74
- credential = await chunkYGWWLTH5_js.getFreshCredential(options.apiKey);
73
+ if (credential !== void 0 || chunkZDXGB3UC_js.isTokenMode()) {
74
+ credential = await chunkZDXGB3UC_js.getFreshCredential(options.apiKey);
75
75
  }
76
76
  const headers = new Headers(init.headers || {});
77
- headers.set("x-sitekit-version", chunk34WY5XN2_js.SITE_KIT_VERSION);
77
+ headers.set("x-sitekit-version", chunkR35CW6MM_js.SITE_KIT_VERSION);
78
78
  if (credential) {
79
- if (chunkYGWWLTH5_js.isTokenMode()) {
79
+ if (chunkZDXGB3UC_js.isTokenMode()) {
80
80
  headers.set("x-api-key", credential);
81
81
  headers.delete("authorization");
82
82
  } else if (!headers.has("x-api-key")) {
@@ -87,11 +87,11 @@ async function sonorFetch(url, init = {}, options = {}) {
87
87
  return new Response(null, { status: 401, statusText: "sonor-auth-paused" });
88
88
  }
89
89
  let response = await fetchWithRetry(url, { ...init, headers }, options);
90
- if ((response.status === 401 || response.status === 403) && typeof window !== "undefined" && chunkYGWWLTH5_js.isSiteToken(credential)) {
91
- const refreshed = await chunkYGWWLTH5_js.refreshSiteToken();
90
+ if ((response.status === 401 || response.status === 403) && typeof window !== "undefined" && chunkZDXGB3UC_js.isSiteToken(credential)) {
91
+ const refreshed = await chunkZDXGB3UC_js.refreshSiteToken();
92
92
  if (refreshed && refreshed !== credential) {
93
93
  const retryHeaders = new Headers(init.headers || {});
94
- retryHeaders.set("x-sitekit-version", chunk34WY5XN2_js.SITE_KIT_VERSION);
94
+ retryHeaders.set("x-sitekit-version", chunkR35CW6MM_js.SITE_KIT_VERSION);
95
95
  retryHeaders.set("x-api-key", refreshed);
96
96
  retryHeaders.delete("authorization");
97
97
  credential = refreshed;
@@ -104,7 +104,7 @@ async function sonorFetch(url, init = {}, options = {}) {
104
104
  return response;
105
105
  }
106
106
  function sonorBeacon(url, payload, apiKey) {
107
- const credential = chunkYGWWLTH5_js.currentCredential(apiKey);
107
+ const credential = chunkZDXGB3UC_js.currentCredential(apiKey);
108
108
  const body = typeof payload === "string" ? payload : JSON.stringify(payload);
109
109
  try {
110
110
  void fetch(url, {
@@ -112,7 +112,7 @@ function sonorBeacon(url, payload, apiKey) {
112
112
  keepalive: true,
113
113
  headers: {
114
114
  "Content-Type": "application/json",
115
- "x-sitekit-version": chunk34WY5XN2_js.SITE_KIT_VERSION,
115
+ "x-sitekit-version": chunkR35CW6MM_js.SITE_KIT_VERSION,
116
116
  ...credential ? { "x-api-key": credential } : {}
117
117
  },
118
118
  body
@@ -130,5 +130,5 @@ function sonorBeacon(url, payload, apiKey) {
130
130
 
131
131
  exports.sonorBeacon = sonorBeacon;
132
132
  exports.sonorFetch = sonorFetch;
133
- //# sourceMappingURL=chunk-EDFZ6EMM.js.map
134
- //# sourceMappingURL=chunk-EDFZ6EMM.js.map
133
+ //# sourceMappingURL=chunk-FYPA5GLS.js.map
134
+ //# sourceMappingURL=chunk-FYPA5GLS.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/fetchWithRetry.ts","../src/shared/sonorFetch.ts"],"names":["credentialBreakerId","isTokenMode","getFreshCredential","SITE_KIT_VERSION","isSiteToken","refreshSiteToken","currentCredential"],"mappings":"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","file":"chunk-EDFZ6EMM.js","sourcesContent":["/**\n * @sonordev/site-kit shared - Resilient fetch\n *\n * Single source of truth for client-side resilient fetch (forms, SitemapSync).\n * Adds a per-attempt timeout and retries transient failures (network errors,\n * request timeouts, HTTP 429, and 5xx) with exponential backoff.\n *\n * A form submission must survive a brief API blip — a deploy, a cold start, a\n * dropped packet. A single un-retried fetch turning into \"Something went wrong\"\n * is how leads get lost. The explicit abort also matters on its own: a request\n * left to hang until the browser's own network timeout logs a console error\n * (net::ERR_TIMED_OUT) that fails Lighthouse best-practices; an aborted fetch\n * logs nothing.\n */\n\nexport interface FetchRetryOptions {\n /** Number of retries AFTER the first attempt (default 2 → up to 3 tries total). */\n retries?: number\n /** Per-attempt timeout in milliseconds (default 15000). */\n timeoutMs?: number\n}\n\nfunction backoffDelay(attempt: number, response?: Response): number {\n // Honor a Retry-After header on 429 responses when present.\n if (response?.status === 429) {\n const header = response.headers.get('retry-after')\n const seconds = header ? parseInt(header, 10) : NaN\n if (!Number.isNaN(seconds) && seconds > 0) return Math.min(seconds * 1000, 10000)\n }\n // Exponential backoff: 500ms, 1s, 2s, ... capped at 8s.\n return Math.min(8000, 500 * 2 ** attempt)\n}\n\n/**\n * fetch() with a timeout and automatic retries for transient failures.\n *\n * Non-transient responses (2xx, 3xx, and 4xx other than 429) are returned to\n * the caller as-is — only 429/5xx and thrown network/timeout errors are retried.\n * If every attempt fails with a thrown error, the last error is re-thrown.\n */\nexport async function fetchWithRetry(\n url: string,\n init: RequestInit,\n options: FetchRetryOptions = {},\n): Promise<Response> {\n const retries = options.retries ?? 2\n const timeoutMs = options.timeoutMs ?? 15000\n let lastError: unknown\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n const response = await fetch(url, { ...init, signal: controller.signal })\n clearTimeout(timer)\n\n if ((response.status === 429 || response.status >= 500) && attempt < retries) {\n await new Promise((resolve) => setTimeout(resolve, backoffDelay(attempt, response)))\n continue\n }\n return response\n } catch (error) {\n clearTimeout(timer)\n lastError = error\n // Network failure or timeout (AbortController) — retry while attempts remain.\n if (attempt < retries) {\n await new Promise((resolve) => setTimeout(resolve, backoffDelay(attempt)))\n continue\n }\n }\n }\n\n throw lastError instanceof Error\n ? lastError\n : new Error('Network request failed after multiple attempts. Please try again.')\n}\n","/**\n * @sonordev/site-kit shared - Canonical client transport\n *\n * Single source of truth for how site-kit talks to Sonor from the browser.\n * Every client-side module (analytics, forms, commerce, engage, maps, images,\n * SitemapSync) routes through here instead of bare fetch(), which gives the\n * whole kit, in one place:\n *\n * - per-attempt timeout + retry with backoff (via fetchWithRetry) — a hung\n * request left to the browser's own network timeout logs a console error\n * (net::ERR_TIMED_OUT) that fails Lighthouse best-practices\n * - the x-sitekit-version header on every request, so the platform can see\n * which kit version each site actually runs from live traffic\n * - CREDENTIAL LIFECYCLE: sites on 3.2+ ship a short-lived minted token instead\n * of the raw key. This transport resolves the freshest token (refreshing a\n * stale seed transparently), and on a 401/403 for a token it refreshes once\n * and retries before giving up. A raw key (2.x kit, or the mint-failed\n * fallback) is a pure passthrough — legacy behavior is unchanged.\n * - an auth circuit breaker: after a 401/403 the credential is paused for a few\n * minutes and ONE friendly console.info is emitted — a site on a stale or\n * canceled key must not spam the API or the visitor's console. Keyed by the\n * project (from the token) so it survives token rotation.\n * - sonorBeacon for unload-time telemetry that keeps the credential in headers;\n * navigator.sendBeacon can't set headers and forced the key into the URL,\n * where server and CDN access logs capture it\n *\n * Non-idempotent endpoints (checkout, payment intents, uploads) must pass\n * { retries: 0 } — they still get the timeout, but never an automatic retry.\n */\nimport { fetchWithRetry, type FetchRetryOptions } from './fetchWithRetry'\nimport { SITE_KIT_VERSION } from './version'\nimport {\n credentialBreakerId,\n currentCredential,\n getFreshCredential,\n isSiteToken,\n isTokenMode,\n refreshSiteToken,\n} from './siteToken'\n\nexport interface SonorFetchOptions extends FetchRetryOptions {\n /** Project credential — the minted token (3.2+) or raw key. Sent as x-api-key. */\n apiKey?: string\n}\n\n/** How long a credential stays paused after an auth failure. */\nconst AUTH_BREAK_MS = 5 * 60_000\n\n// breaker id → epoch ms until which requests are paused. Shared on window for\n// the same reason as the token state (see siteToken.ts): duplicated module\n// copies must trip and observe ONE breaker, not one each. Never applies on the\n// server, so a per-module Map there is fine.\nconst BREAKER_STATE_KEY = '__SONOR_AUTH_BREAKER__'\nconst pausedKeys: Map<string, number> = (() => {\n if (typeof window === 'undefined') return new Map()\n const w = window as unknown as Record<string, Map<string, number> | undefined>\n return (w[BREAKER_STATE_KEY] ??= new Map())\n})()\nlet warnedThisPage = false\n\n/** True when a previous 401/403 has paused this credential (browser only). */\nexport function isAuthPaused(credential?: string): boolean {\n if (typeof window === 'undefined') return false\n const id = credentialBreakerId(credential)\n const until = pausedKeys.get(id)\n if (!until) return false\n if (Date.now() >= until) {\n pausedKeys.delete(id)\n return false\n }\n return true\n}\n\nfunction tripBreaker(credential?: string): void {\n pausedKeys.set(credentialBreakerId(credential), Date.now() + AUTH_BREAK_MS)\n if (!warnedThisPage) {\n warnedThisPage = true\n // info, not error: a visitor's console must stay clean (Lighthouse\n // errors-in-console), and copy never names env vars or key formats.\n console.info(\n \"[Sonor] This site couldn't authenticate with Sonor, so data features are paused for a few minutes. If this keeps happening, the site is likely running an outdated API key.\",\n )\n }\n}\n\nexport async function sonorFetch(\n url: string,\n init: RequestInit = {},\n options: SonorFetchOptions = {},\n): Promise<Response> {\n // Resolve the credential to send. In token mode this may transparently refresh\n // a stale seed before the first request; in raw-key mode it's a passthrough.\n let credential = options.apiKey\n if (credential !== undefined || isTokenMode()) {\n credential = await getFreshCredential(options.apiKey)\n }\n\n const headers = new Headers(init.headers || {})\n headers.set('x-sitekit-version', SITE_KIT_VERSION)\n if (credential) {\n if (isTokenMode()) {\n // Token mode: `credential` is the freshest token (refreshed just above if\n // the seed was stale). It MUST override any x-api-key a caller hand-set — a\n // stale build-time seed passed as a header would otherwise pin the request\n // and defeat refresh entirely. Also drop a caller-set Authorization:\n // extractApiKey() server-side prefers `Authorization: Bearer` over\n // x-api-key, so a stale Bearer seed would win even once we set a fresh\n // x-api-key. This is the single place the client credential is chosen — do\n // not re-attach it as a header at call sites.\n headers.set('x-api-key', credential)\n headers.delete('authorization')\n } else if (!headers.has('x-api-key')) {\n // Raw-key mode: legacy passthrough — respect a caller-supplied header.\n headers.set('x-api-key', credential)\n }\n }\n\n if (isAuthPaused(credential)) {\n // Synthetic response keeps every caller's !response.ok path working\n // without a network round trip while the breaker is open.\n return new Response(null, { status: 401, statusText: 'sonor-auth-paused' })\n }\n\n let response = await fetchWithRetry(url, { ...init, headers }, options)\n\n // A token can rotate or expire mid-session. On the first auth failure, try ONE\n // refresh + retry before tripping the breaker — only for token credentials\n // (raw keys have nothing to refresh).\n if (\n (response.status === 401 || response.status === 403) &&\n typeof window !== 'undefined' &&\n isSiteToken(credential)\n ) {\n const refreshed = await refreshSiteToken()\n if (refreshed && refreshed !== credential) {\n const retryHeaders = new Headers(init.headers || {})\n retryHeaders.set('x-sitekit-version', SITE_KIT_VERSION)\n retryHeaders.set('x-api-key', refreshed)\n // Same reason as the initial request: a caller-set stale Bearer would win\n // over our fresh x-api-key server-side, so strip it on the retry too.\n retryHeaders.delete('authorization')\n credential = refreshed\n response = await fetchWithRetry(url, { ...init, headers: retryHeaders }, options)\n }\n }\n\n if (\n (response.status === 401 || response.status === 403) &&\n typeof window !== 'undefined' &&\n credential\n ) {\n tripBreaker(credential)\n }\n\n return response\n}\n\n/**\n * Fire-and-forget telemetry that survives page unload.\n *\n * Uses fetch({ keepalive: true }) so auth travels in headers. Falls back to\n * navigator.sendBeacon (no auth headers possible — the server may reject it,\n * but we never put the key in the URL) only when keepalive fetch is missing.\n *\n * Cannot await a refresh at unload time, so it sends the freshest token already\n * held (currentCredential) rather than the possibly-stale seed the caller passed.\n */\nexport function sonorBeacon(url: string, payload: unknown, apiKey?: string): void {\n const credential = currentCredential(apiKey)\n const body = typeof payload === 'string' ? payload : JSON.stringify(payload)\n try {\n void fetch(url, {\n method: 'POST',\n keepalive: true,\n headers: {\n 'Content-Type': 'application/json',\n 'x-sitekit-version': SITE_KIT_VERSION,\n ...(credential ? { 'x-api-key': credential } : {}),\n },\n body,\n }).catch(() => {\n /* page is closing — best effort */\n })\n } catch {\n try {\n if (typeof navigator !== 'undefined' && navigator.sendBeacon) {\n navigator.sendBeacon(url, new Blob([body], { type: 'application/json' }))\n }\n } catch {\n /* nothing left to try */\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/shared/fetchWithRetry.ts","../src/shared/sonorFetch.ts"],"names":["credentialBreakerId","isTokenMode","getFreshCredential","SITE_KIT_VERSION","isSiteToken","refreshSiteToken","currentCredential"],"mappings":";;;;;;AAsBA,SAAS,YAAA,CAAa,SAAiB,QAAA,EAA6B;AAElE,EAAA,IAAI,QAAA,EAAU,WAAW,GAAA,EAAK;AAC5B,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AACjD,IAAA,MAAM,OAAA,GAAU,MAAA,GAAS,QAAA,CAAS,MAAA,EAAQ,EAAE,CAAA,GAAI,GAAA;AAChD,IAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,OAAO,CAAA,IAAK,OAAA,GAAU,CAAA,EAAG,OAAO,IAAA,CAAK,GAAA,CAAI,OAAA,GAAU,GAAA,EAAM,GAAK,CAAA;AAAA,EAClF;AAEA,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAA,EAAM,GAAA,GAAM,KAAK,OAAO,CAAA;AAC1C;AASA,eAAsB,cAAA,CACpB,GAAA,EACA,IAAA,EACA,OAAA,GAA6B,EAAC,EACX;AACnB,EAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,IAAW,CAAA;AACnC,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,IAAA;AACvC,EAAA,IAAI,SAAA;AAEJ,EAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,OAAA,EAAS,OAAA,EAAA,EAAW;AACnD,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,SAAS,CAAA;AAC5D,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,CAAA;AACxE,MAAA,YAAA,CAAa,KAAK,CAAA;AAElB,MAAA,IAAA,CAAK,SAAS,MAAA,KAAW,GAAA,IAAO,SAAS,MAAA,IAAU,GAAA,KAAQ,UAAU,OAAA,EAAS;AAC5E,QAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY,UAAA,CAAW,SAAS,YAAA,CAAa,OAAA,EAAS,QAAQ,CAAC,CAAC,CAAA;AACnF,QAAA;AAAA,MACF;AACA,MAAA,OAAO,QAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,SAAA,GAAY,KAAA;AAEZ,MAAA,IAAI,UAAU,OAAA,EAAS;AACrB,QAAA,MAAM,IAAI,QAAQ,CAAC,OAAA,KAAY,WAAW,OAAA,EAAS,YAAA,CAAa,OAAO,CAAC,CAAC,CAAA;AACzE,QAAA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,SAAA,YAAqB,KAAA,GACvB,SAAA,GACA,IAAI,MAAM,mEAAmE,CAAA;AACnF;;;AC7BA,IAAM,gBAAgB,CAAA,GAAI,GAAA;AAM1B,IAAM,iBAAA,GAAoB,wBAAA;AAC1B,IAAM,cAAmC,MAAM;AAC7C,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,2BAAW,GAAA,EAAI;AAClD,EAAA,MAAM,CAAA,GAAI,MAAA;AACV,EAAA,OAAQ,CAAA,CAAA,iBAAA,CAAA,KAAA,CAAA,CAAA,iBAAA,CAAA,uBAA6B,GAAA,EAAI,CAAA;AAC3C,CAAA,GAAG;AACH,IAAI,cAAA,GAAiB,KAAA;AAGd,SAAS,aAAa,UAAA,EAA8B;AACzD,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,KAAA;AAC1C,EAAA,MAAM,EAAA,GAAKA,qCAAoB,UAAU,CAAA;AACzC,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA;AAC/B,EAAA,IAAI,CAAC,OAAO,OAAO,KAAA;AACnB,EAAA,IAAI,IAAA,CAAK,GAAA,EAAI,IAAK,KAAA,EAAO;AACvB,IAAA,UAAA,CAAW,OAAO,EAAE,CAAA;AACpB,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,YAAY,UAAA,EAA2B;AAC9C,EAAA,UAAA,CAAW,IAAIA,oCAAA,CAAoB,UAAU,GAAG,IAAA,CAAK,GAAA,KAAQ,aAAa,CAAA;AAC1E,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,cAAA,GAAiB,IAAA;AAGjB,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KACF;AAAA,EACF;AACF;AAEA,eAAsB,WACpB,GAAA,EACA,IAAA,GAAoB,EAAC,EACrB,OAAA,GAA6B,EAAC,EACX;AAGnB,EAAA,IAAI,aAAa,OAAA,CAAQ,MAAA;AACzB,EAAA,IAAI,UAAA,KAAe,MAAA,IAAaC,4BAAA,EAAY,EAAG;AAC7C,IAAA,UAAA,GAAa,MAAMC,mCAAA,CAAmB,OAAA,CAAQ,MAAM,CAAA;AAAA,EACtD;AAEA,EAAA,MAAM,UAAU,IAAI,OAAA,CAAQ,IAAA,CAAK,OAAA,IAAW,EAAE,CAAA;AAC9C,EAAA,OAAA,CAAQ,GAAA,CAAI,qBAAqBC,iCAAgB,CAAA;AACjD,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,IAAIF,8BAAY,EAAG;AASjB,MAAA,OAAA,CAAQ,GAAA,CAAI,aAAa,UAAU,CAAA;AACnC,MAAA,OAAA,CAAQ,OAAO,eAAe,CAAA;AAAA,IAChC,CAAA,MAAA,IAAW,CAAC,OAAA,CAAQ,GAAA,CAAI,WAAW,CAAA,EAAG;AAEpC,MAAA,OAAA,CAAQ,GAAA,CAAI,aAAa,UAAU,CAAA;AAAA,IACrC;AAAA,EACF;AAEA,EAAA,IAAI,YAAA,CAAa,UAAU,CAAA,EAAG;AAG5B,IAAA,OAAO,IAAI,SAAS,IAAA,EAAM,EAAE,QAAQ,GAAA,EAAK,UAAA,EAAY,qBAAqB,CAAA;AAAA,EAC5E;AAEA,EAAA,IAAI,QAAA,GAAW,MAAM,cAAA,CAAe,GAAA,EAAK,EAAE,GAAG,IAAA,EAAM,OAAA,EAAQ,EAAG,OAAO,CAAA;AAKtE,EAAA,IAAA,CACG,QAAA,CAAS,MAAA,KAAW,GAAA,IAAO,QAAA,CAAS,MAAA,KAAW,GAAA,KAChD,OAAO,MAAA,KAAW,WAAA,IAClBG,4BAAA,CAAY,UAAU,CAAA,EACtB;AACA,IAAA,MAAM,SAAA,GAAY,MAAMC,iCAAA,EAAiB;AACzC,IAAA,IAAI,SAAA,IAAa,cAAc,UAAA,EAAY;AACzC,MAAA,MAAM,eAAe,IAAI,OAAA,CAAQ,IAAA,CAAK,OAAA,IAAW,EAAE,CAAA;AACnD,MAAA,YAAA,CAAa,GAAA,CAAI,qBAAqBF,iCAAgB,CAAA;AACtD,MAAA,YAAA,CAAa,GAAA,CAAI,aAAa,SAAS,CAAA;AAGvC,MAAA,YAAA,CAAa,OAAO,eAAe,CAAA;AACnC,MAAA,UAAA,GAAa,SAAA;AACb,MAAA,QAAA,GAAW,MAAM,eAAe,GAAA,EAAK,EAAE,GAAG,IAAA,EAAM,OAAA,EAAS,YAAA,EAAa,EAAG,OAAO,CAAA;AAAA,IAClF;AAAA,EACF;AAEA,EAAA,IAAA,CACG,QAAA,CAAS,WAAW,GAAA,IAAO,QAAA,CAAS,WAAW,GAAA,KAChD,OAAO,MAAA,KAAW,WAAA,IAClB,UAAA,EACA;AACA,IAAA,WAAA,CAAY,UAAU,CAAA;AAAA,EACxB;AAEA,EAAA,OAAO,QAAA;AACT;AAYO,SAAS,WAAA,CAAY,GAAA,EAAa,OAAA,EAAkB,MAAA,EAAuB;AAChF,EAAA,MAAM,UAAA,GAAaG,mCAAkB,MAAM,CAAA;AAC3C,EAAA,MAAM,OAAO,OAAO,OAAA,KAAY,WAAW,OAAA,GAAU,IAAA,CAAK,UAAU,OAAO,CAAA;AAC3E,EAAA,IAAI;AACF,IAAA,KAAK,MAAM,GAAA,EAAK;AAAA,MACd,MAAA,EAAQ,MAAA;AAAA,MACR,SAAA,EAAW,IAAA;AAAA,MACX,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,mBAAA,EAAqBH,iCAAA;AAAA,QACrB,GAAI,UAAA,GAAa,EAAE,WAAA,EAAa,UAAA,KAAe;AAAC,OAClD;AAAA,MACA;AAAA,KACD,CAAA,CAAE,KAAA,CAAM,MAAM;AAAA,IAEf,CAAC,CAAA;AAAA,EACH,CAAA,CAAA,MAAQ;AACN,IAAA,IAAI;AACF,MAAA,IAAI,OAAO,SAAA,KAAc,WAAA,IAAe,SAAA,CAAU,UAAA,EAAY;AAC5D,QAAA,SAAA,CAAU,UAAA,CAAW,GAAA,EAAK,IAAI,IAAA,CAAK,CAAC,IAAI,CAAA,EAAG,EAAE,IAAA,EAAM,kBAAA,EAAoB,CAAC,CAAA;AAAA,MAC1E;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACF","file":"chunk-FYPA5GLS.js","sourcesContent":["/**\n * @sonordev/site-kit shared - Resilient fetch\n *\n * Single source of truth for client-side resilient fetch (forms, SitemapSync).\n * Adds a per-attempt timeout and retries transient failures (network errors,\n * request timeouts, HTTP 429, and 5xx) with exponential backoff.\n *\n * A form submission must survive a brief API blip — a deploy, a cold start, a\n * dropped packet. A single un-retried fetch turning into \"Something went wrong\"\n * is how leads get lost. The explicit abort also matters on its own: a request\n * left to hang until the browser's own network timeout logs a console error\n * (net::ERR_TIMED_OUT) that fails Lighthouse best-practices; an aborted fetch\n * logs nothing.\n */\n\nexport interface FetchRetryOptions {\n /** Number of retries AFTER the first attempt (default 2 → up to 3 tries total). */\n retries?: number\n /** Per-attempt timeout in milliseconds (default 15000). */\n timeoutMs?: number\n}\n\nfunction backoffDelay(attempt: number, response?: Response): number {\n // Honor a Retry-After header on 429 responses when present.\n if (response?.status === 429) {\n const header = response.headers.get('retry-after')\n const seconds = header ? parseInt(header, 10) : NaN\n if (!Number.isNaN(seconds) && seconds > 0) return Math.min(seconds * 1000, 10000)\n }\n // Exponential backoff: 500ms, 1s, 2s, ... capped at 8s.\n return Math.min(8000, 500 * 2 ** attempt)\n}\n\n/**\n * fetch() with a timeout and automatic retries for transient failures.\n *\n * Non-transient responses (2xx, 3xx, and 4xx other than 429) are returned to\n * the caller as-is — only 429/5xx and thrown network/timeout errors are retried.\n * If every attempt fails with a thrown error, the last error is re-thrown.\n */\nexport async function fetchWithRetry(\n url: string,\n init: RequestInit,\n options: FetchRetryOptions = {},\n): Promise<Response> {\n const retries = options.retries ?? 2\n const timeoutMs = options.timeoutMs ?? 15000\n let lastError: unknown\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n const response = await fetch(url, { ...init, signal: controller.signal })\n clearTimeout(timer)\n\n if ((response.status === 429 || response.status >= 500) && attempt < retries) {\n await new Promise((resolve) => setTimeout(resolve, backoffDelay(attempt, response)))\n continue\n }\n return response\n } catch (error) {\n clearTimeout(timer)\n lastError = error\n // Network failure or timeout (AbortController) — retry while attempts remain.\n if (attempt < retries) {\n await new Promise((resolve) => setTimeout(resolve, backoffDelay(attempt)))\n continue\n }\n }\n }\n\n throw lastError instanceof Error\n ? lastError\n : new Error('Network request failed after multiple attempts. Please try again.')\n}\n","/**\n * @sonordev/site-kit shared - Canonical client transport\n *\n * Single source of truth for how site-kit talks to Sonor from the browser.\n * Every client-side module (analytics, forms, commerce, engage, maps, images,\n * SitemapSync) routes through here instead of bare fetch(), which gives the\n * whole kit, in one place:\n *\n * - per-attempt timeout + retry with backoff (via fetchWithRetry) — a hung\n * request left to the browser's own network timeout logs a console error\n * (net::ERR_TIMED_OUT) that fails Lighthouse best-practices\n * - the x-sitekit-version header on every request, so the platform can see\n * which kit version each site actually runs from live traffic\n * - CREDENTIAL LIFECYCLE: sites on 3.2+ ship a short-lived minted token instead\n * of the raw key. This transport resolves the freshest token (refreshing a\n * stale seed transparently), and on a 401/403 for a token it refreshes once\n * and retries before giving up. A raw key (2.x kit, or the mint-failed\n * fallback) is a pure passthrough — legacy behavior is unchanged.\n * - an auth circuit breaker: after a 401/403 the credential is paused for a few\n * minutes and ONE friendly console.info is emitted — a site on a stale or\n * canceled key must not spam the API or the visitor's console. Keyed by the\n * project (from the token) so it survives token rotation.\n * - sonorBeacon for unload-time telemetry that keeps the credential in headers;\n * navigator.sendBeacon can't set headers and forced the key into the URL,\n * where server and CDN access logs capture it\n *\n * Non-idempotent endpoints (checkout, payment intents, uploads) must pass\n * { retries: 0 } — they still get the timeout, but never an automatic retry.\n */\nimport { fetchWithRetry, type FetchRetryOptions } from './fetchWithRetry'\nimport { SITE_KIT_VERSION } from './version'\nimport {\n credentialBreakerId,\n currentCredential,\n getFreshCredential,\n isSiteToken,\n isTokenMode,\n refreshSiteToken,\n} from './siteToken'\n\nexport interface SonorFetchOptions extends FetchRetryOptions {\n /** Project credential — the minted token (3.2+) or raw key. Sent as x-api-key. */\n apiKey?: string\n}\n\n/** How long a credential stays paused after an auth failure. */\nconst AUTH_BREAK_MS = 5 * 60_000\n\n// breaker id → epoch ms until which requests are paused. Shared on window for\n// the same reason as the token state (see siteToken.ts): duplicated module\n// copies must trip and observe ONE breaker, not one each. Never applies on the\n// server, so a per-module Map there is fine.\nconst BREAKER_STATE_KEY = '__SONOR_AUTH_BREAKER__'\nconst pausedKeys: Map<string, number> = (() => {\n if (typeof window === 'undefined') return new Map()\n const w = window as unknown as Record<string, Map<string, number> | undefined>\n return (w[BREAKER_STATE_KEY] ??= new Map())\n})()\nlet warnedThisPage = false\n\n/** True when a previous 401/403 has paused this credential (browser only). */\nexport function isAuthPaused(credential?: string): boolean {\n if (typeof window === 'undefined') return false\n const id = credentialBreakerId(credential)\n const until = pausedKeys.get(id)\n if (!until) return false\n if (Date.now() >= until) {\n pausedKeys.delete(id)\n return false\n }\n return true\n}\n\nfunction tripBreaker(credential?: string): void {\n pausedKeys.set(credentialBreakerId(credential), Date.now() + AUTH_BREAK_MS)\n if (!warnedThisPage) {\n warnedThisPage = true\n // info, not error: a visitor's console must stay clean (Lighthouse\n // errors-in-console), and copy never names env vars or key formats.\n console.info(\n \"[Sonor] This site couldn't authenticate with Sonor, so data features are paused for a few minutes. If this keeps happening, the site is likely running an outdated API key.\",\n )\n }\n}\n\nexport async function sonorFetch(\n url: string,\n init: RequestInit = {},\n options: SonorFetchOptions = {},\n): Promise<Response> {\n // Resolve the credential to send. In token mode this may transparently refresh\n // a stale seed before the first request; in raw-key mode it's a passthrough.\n let credential = options.apiKey\n if (credential !== undefined || isTokenMode()) {\n credential = await getFreshCredential(options.apiKey)\n }\n\n const headers = new Headers(init.headers || {})\n headers.set('x-sitekit-version', SITE_KIT_VERSION)\n if (credential) {\n if (isTokenMode()) {\n // Token mode: `credential` is the freshest token (refreshed just above if\n // the seed was stale). It MUST override any x-api-key a caller hand-set — a\n // stale build-time seed passed as a header would otherwise pin the request\n // and defeat refresh entirely. Also drop a caller-set Authorization:\n // extractApiKey() server-side prefers `Authorization: Bearer` over\n // x-api-key, so a stale Bearer seed would win even once we set a fresh\n // x-api-key. This is the single place the client credential is chosen — do\n // not re-attach it as a header at call sites.\n headers.set('x-api-key', credential)\n headers.delete('authorization')\n } else if (!headers.has('x-api-key')) {\n // Raw-key mode: legacy passthrough — respect a caller-supplied header.\n headers.set('x-api-key', credential)\n }\n }\n\n if (isAuthPaused(credential)) {\n // Synthetic response keeps every caller's !response.ok path working\n // without a network round trip while the breaker is open.\n return new Response(null, { status: 401, statusText: 'sonor-auth-paused' })\n }\n\n let response = await fetchWithRetry(url, { ...init, headers }, options)\n\n // A token can rotate or expire mid-session. On the first auth failure, try ONE\n // refresh + retry before tripping the breaker — only for token credentials\n // (raw keys have nothing to refresh).\n if (\n (response.status === 401 || response.status === 403) &&\n typeof window !== 'undefined' &&\n isSiteToken(credential)\n ) {\n const refreshed = await refreshSiteToken()\n if (refreshed && refreshed !== credential) {\n const retryHeaders = new Headers(init.headers || {})\n retryHeaders.set('x-sitekit-version', SITE_KIT_VERSION)\n retryHeaders.set('x-api-key', refreshed)\n // Same reason as the initial request: a caller-set stale Bearer would win\n // over our fresh x-api-key server-side, so strip it on the retry too.\n retryHeaders.delete('authorization')\n credential = refreshed\n response = await fetchWithRetry(url, { ...init, headers: retryHeaders }, options)\n }\n }\n\n if (\n (response.status === 401 || response.status === 403) &&\n typeof window !== 'undefined' &&\n credential\n ) {\n tripBreaker(credential)\n }\n\n return response\n}\n\n/**\n * Fire-and-forget telemetry that survives page unload.\n *\n * Uses fetch({ keepalive: true }) so auth travels in headers. Falls back to\n * navigator.sendBeacon (no auth headers possible — the server may reject it,\n * but we never put the key in the URL) only when keepalive fetch is missing.\n *\n * Cannot await a refresh at unload time, so it sends the freshest token already\n * held (currentCredential) rather than the possibly-stale seed the caller passed.\n */\nexport function sonorBeacon(url: string, payload: unknown, apiKey?: string): void {\n const credential = currentCredential(apiKey)\n const body = typeof payload === 'string' ? payload : JSON.stringify(payload)\n try {\n void fetch(url, {\n method: 'POST',\n keepalive: true,\n headers: {\n 'Content-Type': 'application/json',\n 'x-sitekit-version': SITE_KIT_VERSION,\n ...(credential ? { 'x-api-key': credential } : {}),\n },\n body,\n }).catch(() => {\n /* page is closing — best effort */\n })\n } catch {\n try {\n if (typeof navigator !== 'undefined' && navigator.sendBeacon) {\n navigator.sendBeacon(url, new Blob([body], { type: 'application/json' }))\n }\n } catch {\n /* nothing left to try */\n }\n }\n}\n"]}
@@ -0,0 +1,44 @@
1
+ import { HoneypotField, NativeFallbackFields, nativeFormProps } from './chunk-4ROQDPUE.mjs';
2
+ import { FormField } from './chunk-LB7LHVWI.mjs';
3
+ import { normalizeFormConfig } from './chunk-ANTVZSQI.mjs';
4
+ import { DEFAULT_HONEYPOT_FIELD } from './chunk-TMVKRQGJ.mjs';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ function visibleStaticFields(config) {
8
+ const all = config.fields || [];
9
+ if (!config.is_multi_step) return all;
10
+ const firstStepId = config.steps?.[0]?.id;
11
+ return all.filter((f) => !f.step_id || f.step_id === firstStepId);
12
+ }
13
+ function StaticForm({ config: raw, className, nativeReturnTo }) {
14
+ if (!raw) return null;
15
+ const config = normalizeFormConfig(raw);
16
+ const fields = visibleStaticFields(config);
17
+ const honeypotFieldName = config.honeypot_field || DEFAULT_HONEYPOT_FIELD;
18
+ return /* @__PURE__ */ jsxs(
19
+ "form",
20
+ {
21
+ "data-sk-state": "idle",
22
+ "data-sk-mount": "shell",
23
+ className: `sk-form ${className || ""}`,
24
+ ...nativeFormProps(config),
25
+ children: [
26
+ /* @__PURE__ */ jsx("div", { className: "sk-form__step", children: /* @__PURE__ */ jsx("div", { className: "sk-form__fields", children: fields.map((field) => /* @__PURE__ */ jsx(
27
+ "div",
28
+ {
29
+ className: `sk-form__field-wrapper sk-form__field-wrapper--${field.width || "full"}`,
30
+ children: /* @__PURE__ */ jsx(FormField, { field, value: field.default_value ?? "" })
31
+ },
32
+ field.id || field.slug
33
+ )) }) }),
34
+ /* @__PURE__ */ jsx("div", { className: "sk-form__actions", style: { justifyContent: "flex-end" }, children: /* @__PURE__ */ jsx("button", { type: "submit", className: "sk-form__btn sk-form__btn--submit", children: config.submit_button_text || "Submit" }) }),
35
+ config.honeypot_enabled && /* @__PURE__ */ jsx(HoneypotField, { name: honeypotFieldName }),
36
+ /* @__PURE__ */ jsx(NativeFallbackFields, { config, returnTo: nativeReturnTo })
37
+ ]
38
+ }
39
+ );
40
+ }
41
+
42
+ export { StaticForm };
43
+ //# sourceMappingURL=chunk-G7IMEY5T.mjs.map
44
+ //# sourceMappingURL=chunk-G7IMEY5T.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/forms/StaticForm.tsx"],"names":[],"mappings":";;;;;;AA6DA,SAAS,oBAAoB,MAAA,EAA2B;AACtD,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,MAAA,IAAU,EAAC;AAC9B,EAAA,IAAI,CAAC,MAAA,CAAO,aAAA,EAAe,OAAO,GAAA;AAGlC,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,KAAA,GAAQ,CAAC,CAAA,EAAG,EAAA;AACvC,EAAA,OAAO,GAAA,CAAI,OAAO,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,OAAA,KAAY,WAAW,CAAA;AAClE;AAEO,SAAS,WAAW,EAAE,MAAA,EAAQ,GAAA,EAAK,SAAA,EAAW,gBAAe,EAAoB;AACtF,EAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,EAAA,MAAM,MAAA,GAAS,oBAAoB,GAAU,CAAA;AAC7C,EAAA,MAAM,MAAA,GAAS,oBAAoB,MAAM,CAAA;AACzC,EAAA,MAAM,iBAAA,GAAoB,OAAO,cAAA,IAAkB,sBAAA;AAEnD,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MAGC,eAAA,EAAc,MAAA;AAAA,MACd,eAAA,EAAc,OAAA;AAAA,MACd,SAAA,EAAW,CAAA,QAAA,EAAW,SAAA,IAAa,EAAE,CAAA,CAAA;AAAA,MACpC,GAAG,gBAAgB,MAAM,CAAA;AAAA,MAE1B,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EACb,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,WAAU,iBAAA,EACZ,QAAA,EAAA,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,qBACX,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YAEC,SAAA,EAAW,CAAA,+CAAA,EAAkD,KAAA,CAAM,KAAA,IAAS,MAAM,CAAA,CAAA;AAAA,YAGlF,8BAAC,SAAA,EAAA,EAAU,KAAA,EAAc,KAAA,EAAO,KAAA,CAAM,iBAAiB,EAAA,EAAI;AAAA,WAAA;AAAA,UAJtD,KAAA,CAAM,MAAM,KAAA,CAAM;AAAA,SAM1B,GACH,CAAA,EACF,CAAA;AAAA,4BAEC,KAAA,EAAA,EAAI,SAAA,EAAU,oBAAmB,KAAA,EAAO,EAAE,gBAAgB,UAAA,EAAW,EACpE,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAO,MAAK,QAAA,EAAS,SAAA,EAAU,qCAC7B,QAAA,EAAA,MAAA,CAAO,kBAAA,IAAsB,UAChC,CAAA,EACF,CAAA;AAAA,QAIC,MAAA,CAAO,gBAAA,oBAAoB,GAAA,CAAC,aAAA,EAAA,EAAc,MAAM,iBAAA,EAAmB,CAAA;AAAA,wBAGpE,GAAA,CAAC,oBAAA,EAAA,EAAqB,MAAA,EAAgB,QAAA,EAAU,cAAA,EAAgB;AAAA;AAAA;AAAA,GAClE;AAEJ","file":"chunk-G7IMEY5T.mjs","sourcesContent":["/**\n * StaticForm — a complete, submittable managed form with ZERO client JavaScript.\n *\n * No `'use client'`. This renders in a Server Component, and what it emits is\n * a real `<form>`: every field, the honeypot, the signed native token, and a\n * submit button. With JavaScript disabled, off, or still downloading, the\n * browser performs an ordinary form-encoded POST to\n * `/api/public/forms/submit-native`, sonor-api runs the honeypot +\n * render-timestamp + quarantine stack, and the lead lands. 4.0.1 built that\n * endpoint; this is what finally puts it under every form by default.\n *\n * ── Why this exists ─────────────────────────────────────────────────────\n *\n * ManagedForm was a client component for historical reasons that no longer\n * hold: it used to fetch its own config (getFormConfig removed that) and it\n * could only submit via JSON (the native endpoint removed that). Nobody moved\n * the boundary afterward, so every site that rendered a form paid for the\n * whole forms runtime — validation, spotlight, celebration, momentum — as an\n * INITIAL script, on the LCP-critical path.\n *\n * Measured on upforge.io's homepage: 48 KB of form code in the initial chunk\n * set cost 6 Lighthouse points (88 -> 82, LCP 3.8s -> 4.7s). Deferring the\n * client component recovered the score but deleted the form from the HTML,\n * taking the no-JS floor and crawlable fields with it. Neither half was\n * acceptable; a server-rendered form is what makes both true at once.\n *\n * Pair it with <FormEnhancer> to upgrade this markup at idle. Alone, it is\n * still a working form — that is the point. Never make this file `'use\n * client'`, and never import a hook into it.\n */\n\nimport React from 'react'\nimport { DEFAULT_HONEYPOT_FIELD } from './contract'\nimport { FormField } from './FormField'\nimport { HoneypotField } from './HoneypotField'\nimport { nativeFormProps, NativeFallbackFields } from './native-fallback'\nimport { normalizeFormConfig } from './normalize-config'\nimport type { ManagedFormConfig } from './types'\n\nexport interface StaticFormProps {\n /**\n * RAW /api/public/forms/config payload from `getFormConfig`, or an\n * already-normalized config. Normalized here through the SAME function the\n * client fetch uses, so the shell and the enhancement cannot disagree about\n * field order, step count, or success copy.\n */\n config: Record<string, unknown> | ManagedFormConfig | null | undefined\n className?: string\n /**\n * Absolute URL the no-JS 303 should return to (usually the page hosting the\n * form). Without it the API falls back to the Referer origin — right site,\n * wrong page.\n */\n nativeReturnTo?: string\n}\n\n/**\n * Fields the static shell can render meaningfully. Conditional logic is a\n * runtime concern (it depends on values the visitor has not entered yet), so\n * a conditional field renders here and the enhancement takes over hiding it.\n */\nfunction visibleStaticFields(config: ManagedFormConfig) {\n const all = config.fields || []\n if (!config.is_multi_step) return all\n // Multi-step is JS-only navigation and is excluded from native POST, so the\n // shell shows step one as a preview of what the form asks for.\n const firstStepId = config.steps?.[0]?.id\n return all.filter((f) => !f.step_id || f.step_id === firstStepId)\n}\n\nexport function StaticForm({ config: raw, className, nativeReturnTo }: StaticFormProps) {\n if (!raw) return null\n const config = normalizeFormConfig(raw as any)\n const fields = visibleStaticFields(config)\n const honeypotFieldName = config.honeypot_field || DEFAULT_HONEYPOT_FIELD\n\n return (\n <form\n // Matches FormClient's classic branch attribute-for-attribute so the\n // enhancement swap is invisible. Change one, change the other.\n data-sk-state=\"idle\"\n data-sk-mount=\"shell\"\n className={`sk-form ${className || ''}`}\n {...nativeFormProps(config)}\n >\n <div className=\"sk-form__step\">\n <div className=\"sk-form__fields\">\n {fields.map((field) => (\n <div\n key={field.id || field.slug}\n className={`sk-form__field-wrapper sk-form__field-wrapper--${field.width || 'full'}`}\n >\n {/* No onChange — FormField renders native uncontrolled controls. */}\n <FormField field={field} value={field.default_value ?? ''} />\n </div>\n ))}\n </div>\n </div>\n\n <div className=\"sk-form__actions\" style={{ justifyContent: 'flex-end' }}>\n <button type=\"submit\" className=\"sk-form__btn sk-form__btn--submit\">\n {config.submit_button_text || 'Submit'}\n </button>\n </div>\n\n {/* Same trap the hydrated form uses; no state needed because the value\n is read and stripped server-side. */}\n {config.honeypot_enabled && <HoneypotField name={honeypotFieldName} />}\n\n {/* _sk_token auth + _sk_return destination for the native POST. */}\n <NativeFallbackFields config={config} returnTo={nativeReturnTo} />\n </form>\n )\n}\n"]}