@sonordev/site-kit 5.0.0 → 5.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 (224) hide show
  1. package/agent-manifest.json +8 -5
  2. package/dist/AnalyticsProvider-2LCSA6G3.mjs +10 -0
  3. package/dist/{AnalyticsProvider-KCLRFOX6.mjs.map → AnalyticsProvider-2LCSA6G3.mjs.map} +1 -1
  4. package/dist/AnalyticsProvider-V2U3TQMH.js +31 -0
  5. package/dist/{AnalyticsProvider-TXM3DRLI.js.map → AnalyticsProvider-V2U3TQMH.js.map} +1 -1
  6. package/dist/{BlogViewTracker-J6LRGUHU.js → BlogViewTracker-COTPD7WL.js} +6 -6
  7. package/dist/{BlogViewTracker-J6LRGUHU.js.map → BlogViewTracker-COTPD7WL.js.map} +1 -1
  8. package/dist/{BlogViewTracker-PZWAWB3O.mjs → BlogViewTracker-HG25ONRP.mjs} +5 -5
  9. package/dist/{BlogViewTracker-PZWAWB3O.mjs.map → BlogViewTracker-HG25ONRP.mjs.map} +1 -1
  10. package/dist/ChatWidget-4QUJYFXU.js +20 -0
  11. package/dist/{ChatWidget-LD54Z2PQ.js.map → ChatWidget-4QUJYFXU.js.map} +1 -1
  12. package/dist/ChatWidget-RWO7R7EJ.mjs +11 -0
  13. package/dist/{ChatWidget-PMDPSZXG.mjs.map → ChatWidget-RWO7R7EJ.mjs.map} +1 -1
  14. package/dist/EngageWidget-LF4AC4QN.mjs +9 -0
  15. package/dist/{EngageWidget-4CBFRN4Y.mjs.map → EngageWidget-LF4AC4QN.mjs.map} +1 -1
  16. package/dist/EngageWidget-RSOXB3YM.js +18 -0
  17. package/dist/{EngageWidget-BF5NMQ5A.js.map → EngageWidget-RSOXB3YM.js.map} +1 -1
  18. package/dist/{FileField-VXADIOMN.js → FileField-S2GUM3QB.js} +6 -6
  19. package/dist/{FileField-VXADIOMN.js.map → FileField-S2GUM3QB.js.map} +1 -1
  20. package/dist/{FileField-FFRHS3XP.mjs → FileField-YJ7DZXC3.mjs} +5 -5
  21. package/dist/{FileField-FFRHS3XP.mjs.map → FileField-YJ7DZXC3.mjs.map} +1 -1
  22. package/dist/{FormSpotlight-JG4ZHS56.js → FormSpotlight-7WAXLXZA.js} +15 -15
  23. package/dist/{FormSpotlight-JG4ZHS56.js.map → FormSpotlight-7WAXLXZA.js.map} +1 -1
  24. package/dist/{FormSpotlight-KE46EDP5.mjs → FormSpotlight-HLH5LQKI.mjs} +3 -3
  25. package/dist/{FormSpotlight-KE46EDP5.mjs.map → FormSpotlight-HLH5LQKI.mjs.map} +1 -1
  26. package/dist/{FormStage-5Z53Z2WY.js → FormStage-LEZYERJB.js} +13 -13
  27. package/dist/{FormStage-5Z53Z2WY.js.map → FormStage-LEZYERJB.js.map} +1 -1
  28. package/dist/{FormStage-PZKWEXZE.mjs → FormStage-Q5JW75AF.mjs} +3 -3
  29. package/dist/{FormStage-PZKWEXZE.mjs.map → FormStage-Q5JW75AF.mjs.map} +1 -1
  30. package/dist/ManagedForm-H4SEFSAF.js +23 -0
  31. package/dist/{ManagedForm-E4WHMARH.js.map → ManagedForm-H4SEFSAF.js.map} +1 -1
  32. package/dist/ManagedForm-U3NFIVEC.mjs +14 -0
  33. package/dist/{ManagedForm-VU2TKV6J.mjs.map → ManagedForm-U3NFIVEC.mjs.map} +1 -1
  34. package/dist/{ManagedNewsletterForm-PG4EX3W6.js → ManagedNewsletterForm-KT2NGUNW.js} +8 -8
  35. package/dist/{ManagedNewsletterForm-PG4EX3W6.js.map → ManagedNewsletterForm-KT2NGUNW.js.map} +1 -1
  36. package/dist/{ManagedNewsletterForm-6DET3VGZ.mjs → ManagedNewsletterForm-YKYW7B6P.mjs} +7 -7
  37. package/dist/{ManagedNewsletterForm-6DET3VGZ.mjs.map → ManagedNewsletterForm-YKYW7B6P.mjs.map} +1 -1
  38. package/dist/{SignalCore-RZVTLUC2.mjs → SignalCore-2BH5PUGS.mjs} +5 -5
  39. package/dist/{SignalCore-RZVTLUC2.mjs.map → SignalCore-2BH5PUGS.mjs.map} +1 -1
  40. package/dist/{SignalCore-TCUVXVMN.js → SignalCore-JM4ODFL2.js} +11 -11
  41. package/dist/{SignalCore-TCUVXVMN.js.map → SignalCore-JM4ODFL2.js.map} +1 -1
  42. package/dist/SitemapSync-5CXS2JGB.mjs +8 -0
  43. package/dist/{SitemapSync-T75NAFB3.mjs.map → SitemapSync-5CXS2JGB.mjs.map} +1 -1
  44. package/dist/SitemapSync-J4UMJRTO.js +17 -0
  45. package/dist/{SitemapSync-AJU4DM3G.js.map → SitemapSync-J4UMJRTO.js.map} +1 -1
  46. package/dist/analytics/index.js +9 -9
  47. package/dist/analytics/index.mjs +4 -4
  48. package/dist/blog/index.d.ts +9 -5
  49. package/dist/blog/index.d.ts.map +1 -1
  50. package/dist/blog/index.js +20 -20
  51. package/dist/blog/index.mjs +3 -3
  52. package/dist/blog/server-ui.js +14 -14
  53. package/dist/blog/server-ui.mjs +2 -2
  54. package/dist/{chunk-6QQFEJIP.js → chunk-2EJX56YJ.js} +8 -8
  55. package/dist/{chunk-6QQFEJIP.js.map → chunk-2EJX56YJ.js.map} +1 -1
  56. package/dist/{chunk-SXPINIJG.mjs → chunk-2XHEUWHV.mjs} +4 -4
  57. package/dist/{chunk-SXPINIJG.mjs.map → chunk-2XHEUWHV.mjs.map} +1 -1
  58. package/dist/{chunk-7T4VMXKD.js → chunk-44ZTBQH4.js} +3 -3
  59. package/dist/{chunk-7T4VMXKD.js.map → chunk-44ZTBQH4.js.map} +1 -1
  60. package/dist/chunk-4SQ6PROR.mjs +6 -0
  61. package/dist/{chunk-JPTJGLKS.mjs.map → chunk-4SQ6PROR.mjs.map} +1 -1
  62. package/dist/{chunk-PPCTL4B5.mjs → chunk-4TU246Q4.mjs} +10 -3
  63. package/dist/chunk-4TU246Q4.mjs.map +1 -0
  64. package/dist/{chunk-YSZB2DRX.mjs → chunk-5G2ZRQMO.mjs} +3 -3
  65. package/dist/{chunk-YSZB2DRX.mjs.map → chunk-5G2ZRQMO.mjs.map} +1 -1
  66. package/dist/{chunk-FTBABL3T.mjs → chunk-5W56B52Z.mjs} +3 -3
  67. package/dist/{chunk-FTBABL3T.mjs.map → chunk-5W56B52Z.mjs.map} +1 -1
  68. package/dist/{chunk-XPAHKYX7.mjs → chunk-6YKNDQYJ.mjs} +3 -3
  69. package/dist/{chunk-XPAHKYX7.mjs.map → chunk-6YKNDQYJ.mjs.map} +1 -1
  70. package/dist/{chunk-UV6KQUSL.mjs → chunk-A3VGZAZQ.mjs} +3 -3
  71. package/dist/{chunk-UV6KQUSL.mjs.map → chunk-A3VGZAZQ.mjs.map} +1 -1
  72. package/dist/{chunk-JY3KZDEM.js → chunk-ACLBRIYD.js} +3 -3
  73. package/dist/{chunk-JY3KZDEM.js.map → chunk-ACLBRIYD.js.map} +1 -1
  74. package/dist/{chunk-MGPHBVOK.js → chunk-ACWGG4VW.js} +9 -9
  75. package/dist/{chunk-MGPHBVOK.js.map → chunk-ACWGG4VW.js.map} +1 -1
  76. package/dist/{chunk-J4JXAFSW.mjs → chunk-ADBLBGCQ.mjs} +3 -3
  77. package/dist/{chunk-J4JXAFSW.mjs.map → chunk-ADBLBGCQ.mjs.map} +1 -1
  78. package/dist/{chunk-4UHO6DPJ.mjs → chunk-ADOGOLYO.mjs} +4 -4
  79. package/dist/{chunk-4UHO6DPJ.mjs.map → chunk-ADOGOLYO.mjs.map} +1 -1
  80. package/dist/{chunk-IX5RAZWX.js → chunk-BGBJSMXT.js} +6 -6
  81. package/dist/{chunk-IX5RAZWX.js.map → chunk-BGBJSMXT.js.map} +1 -1
  82. package/dist/{chunk-YVE65W47.mjs → chunk-BUDV7QHH.mjs} +4 -4
  83. package/dist/{chunk-YVE65W47.mjs.map → chunk-BUDV7QHH.mjs.map} +1 -1
  84. package/dist/{chunk-3SMG4EXR.mjs → chunk-BVLGJ2CZ.mjs} +3 -3
  85. package/dist/{chunk-3SMG4EXR.mjs.map → chunk-BVLGJ2CZ.mjs.map} +1 -1
  86. package/dist/{chunk-OGPS3DKE.js → chunk-CBMHJPR7.js} +5 -5
  87. package/dist/{chunk-OGPS3DKE.js.map → chunk-CBMHJPR7.js.map} +1 -1
  88. package/dist/{chunk-VACFVPNF.js → chunk-CGQO7MFO.js} +14 -14
  89. package/dist/{chunk-VACFVPNF.js.map → chunk-CGQO7MFO.js.map} +1 -1
  90. package/dist/{chunk-FQ3JQV3M.js → chunk-CKPFETIO.js} +4 -4
  91. package/dist/{chunk-FQ3JQV3M.js.map → chunk-CKPFETIO.js.map} +1 -1
  92. package/dist/{chunk-MVJQ4ZA2.mjs → chunk-CYQB5GLU.mjs} +4 -4
  93. package/dist/{chunk-MVJQ4ZA2.mjs.map → chunk-CYQB5GLU.mjs.map} +1 -1
  94. package/dist/{chunk-GCZMDY2T.js → chunk-DKRXPXOR.js} +3 -3
  95. package/dist/{chunk-GCZMDY2T.js.map → chunk-DKRXPXOR.js.map} +1 -1
  96. package/dist/{chunk-PZE5L2FK.mjs → chunk-DTNNZJYM.mjs} +4 -4
  97. package/dist/{chunk-PZE5L2FK.mjs.map → chunk-DTNNZJYM.mjs.map} +1 -1
  98. package/dist/{chunk-HCN2US4M.js → chunk-E3GHVAMK.js} +18 -18
  99. package/dist/{chunk-HCN2US4M.js.map → chunk-E3GHVAMK.js.map} +1 -1
  100. package/dist/{chunk-5JNLZRLX.mjs → chunk-EKTMXHBI.mjs} +3 -3
  101. package/dist/{chunk-5JNLZRLX.mjs.map → chunk-EKTMXHBI.mjs.map} +1 -1
  102. package/dist/{chunk-LLKXPJSE.js → chunk-EZLK2OQL.js} +7 -7
  103. package/dist/{chunk-LLKXPJSE.js.map → chunk-EZLK2OQL.js.map} +1 -1
  104. package/dist/{chunk-BQY3FJ3R.js → chunk-FMOOQKZU.js} +8 -8
  105. package/dist/{chunk-BQY3FJ3R.js.map → chunk-FMOOQKZU.js.map} +1 -1
  106. package/dist/{chunk-QI2H5KK6.mjs → chunk-FZISCIJV.mjs} +4 -4
  107. package/dist/{chunk-QI2H5KK6.mjs.map → chunk-FZISCIJV.mjs.map} +1 -1
  108. package/dist/{chunk-62ODUWUX.js → chunk-GYAH4KFC.js} +4 -4
  109. package/dist/{chunk-62ODUWUX.js.map → chunk-GYAH4KFC.js.map} +1 -1
  110. package/dist/{chunk-JIUVBSQZ.js → chunk-GZVSGQKT.js} +3 -3
  111. package/dist/{chunk-JIUVBSQZ.js.map → chunk-GZVSGQKT.js.map} +1 -1
  112. package/dist/{chunk-3FZ76VI5.js → chunk-HPIY7AR3.js} +14 -14
  113. package/dist/{chunk-3FZ76VI5.js.map → chunk-HPIY7AR3.js.map} +1 -1
  114. package/dist/{chunk-5OHHYGD6.js → chunk-IQLYFQKZ.js} +15 -15
  115. package/dist/{chunk-5OHHYGD6.js.map → chunk-IQLYFQKZ.js.map} +1 -1
  116. package/dist/{chunk-DX6D7HDI.js → chunk-JEI3CSY4.js} +4 -4
  117. package/dist/{chunk-DX6D7HDI.js.map → chunk-JEI3CSY4.js.map} +1 -1
  118. package/dist/{chunk-LZY374FB.js → chunk-MCXHQHIX.js} +4 -4
  119. package/dist/{chunk-LZY374FB.js.map → chunk-MCXHQHIX.js.map} +1 -1
  120. package/dist/{chunk-FCKL5CF3.mjs → chunk-NIJVVW4G.mjs} +3 -3
  121. package/dist/{chunk-FCKL5CF3.mjs.map → chunk-NIJVVW4G.mjs.map} +1 -1
  122. package/dist/{chunk-YGRHEEPX.mjs → chunk-NSTY7ZZA.mjs} +7 -7
  123. package/dist/{chunk-YGRHEEPX.mjs.map → chunk-NSTY7ZZA.mjs.map} +1 -1
  124. package/dist/{chunk-HEUCDF3O.mjs → chunk-OAJVITNO.mjs} +3 -3
  125. package/dist/{chunk-HEUCDF3O.mjs.map → chunk-OAJVITNO.mjs.map} +1 -1
  126. package/dist/{chunk-SW6KWUNI.mjs → chunk-OTHKWMDB.mjs} +3 -3
  127. package/dist/{chunk-SW6KWUNI.mjs.map → chunk-OTHKWMDB.mjs.map} +1 -1
  128. package/dist/{chunk-EISVUD75.mjs → chunk-ROJ25QM3.mjs} +3 -3
  129. package/dist/{chunk-EISVUD75.mjs.map → chunk-ROJ25QM3.mjs.map} +1 -1
  130. package/dist/{chunk-FDWDXMJL.mjs → chunk-SXNKLHOX.mjs} +3 -3
  131. package/dist/{chunk-FDWDXMJL.mjs.map → chunk-SXNKLHOX.mjs.map} +1 -1
  132. package/dist/{chunk-MPO6TRLS.js → chunk-TAM2D54C.js} +14 -14
  133. package/dist/{chunk-MPO6TRLS.js.map → chunk-TAM2D54C.js.map} +1 -1
  134. package/dist/{chunk-MWXBRCM2.mjs → chunk-TECD4AP7.mjs} +3 -3
  135. package/dist/{chunk-MWXBRCM2.mjs.map → chunk-TECD4AP7.mjs.map} +1 -1
  136. package/dist/{chunk-AXYKBQVI.mjs → chunk-UMWVTIIZ.mjs} +8 -8
  137. package/dist/{chunk-AXYKBQVI.mjs.map → chunk-UMWVTIIZ.mjs.map} +1 -1
  138. package/dist/{chunk-5JQLLF2T.js → chunk-VCNPTLK2.js} +12 -12
  139. package/dist/{chunk-5JQLLF2T.js.map → chunk-VCNPTLK2.js.map} +1 -1
  140. package/dist/{chunk-4D2G5ZNP.js → chunk-VIIGOCX4.js} +15 -15
  141. package/dist/{chunk-4D2G5ZNP.js.map → chunk-VIIGOCX4.js.map} +1 -1
  142. package/dist/{chunk-QH3WVTEK.mjs → chunk-VWVUYL5J.mjs} +4 -4
  143. package/dist/{chunk-QH3WVTEK.mjs.map → chunk-VWVUYL5J.mjs.map} +1 -1
  144. package/dist/{chunk-KWH6RAVY.js → chunk-WMNRTCYY.js} +11 -11
  145. package/dist/{chunk-KWH6RAVY.js.map → chunk-WMNRTCYY.js.map} +1 -1
  146. package/dist/{chunk-N3RWPAR5.js → chunk-WZMM57R2.js} +5 -5
  147. package/dist/{chunk-N3RWPAR5.js.map → chunk-WZMM57R2.js.map} +1 -1
  148. package/dist/chunk-YPEX4RDE.js +8 -0
  149. package/dist/{chunk-S65JSRWW.js.map → chunk-YPEX4RDE.js.map} +1 -1
  150. package/dist/{chunk-UABMMR7U.js → chunk-Z33JXJTJ.js} +10 -3
  151. package/dist/chunk-Z33JXJTJ.js.map +1 -0
  152. package/dist/{chunk-UFURXSAI.mjs → chunk-ZFZMN4LT.mjs} +3 -3
  153. package/dist/{chunk-UFURXSAI.mjs.map → chunk-ZFZMN4LT.mjs.map} +1 -1
  154. package/dist/cli/index.js +3 -3
  155. package/dist/cli/index.mjs +1 -1
  156. package/dist/client/index.js +4 -4
  157. package/dist/client/index.mjs +3 -3
  158. package/dist/commerce/index.js +56 -56
  159. package/dist/commerce/index.mjs +5 -5
  160. package/dist/commerce/server-result.test.d.ts +2 -0
  161. package/dist/commerce/server-result.test.d.ts.map +1 -0
  162. package/dist/commerce/server.d.ts +51 -0
  163. package/dist/commerce/server.d.ts.map +1 -1
  164. package/dist/commerce/server.js +57 -24
  165. package/dist/commerce/server.js.map +1 -1
  166. package/dist/commerce/server.mjs +54 -25
  167. package/dist/commerce/server.mjs.map +1 -1
  168. package/dist/engage/index.js +10 -10
  169. package/dist/engage/index.mjs +7 -7
  170. package/dist/fleet/index.js +8 -8
  171. package/dist/fleet/index.mjs +4 -4
  172. package/dist/forms/index.js +16 -16
  173. package/dist/forms/index.mjs +9 -9
  174. package/dist/forms/server.js +10 -10
  175. package/dist/forms/server.mjs +8 -8
  176. package/dist/forms/static.js +7 -7
  177. package/dist/forms/static.mjs +6 -6
  178. package/dist/images/index.js +11 -11
  179. package/dist/images/index.mjs +4 -4
  180. package/dist/index.js +63 -63
  181. package/dist/index.mjs +9 -9
  182. package/dist/layout/client.js +8 -8
  183. package/dist/layout/client.mjs +7 -7
  184. package/dist/layout/index.js +10 -10
  185. package/dist/layout/index.mjs +8 -8
  186. package/dist/llms/generateLLMsTxt.d.ts.map +1 -1
  187. package/dist/llms/humanize-industry.d.ts +9 -0
  188. package/dist/llms/humanize-industry.d.ts.map +1 -0
  189. package/dist/llms/humanize-industry.test.d.ts +2 -0
  190. package/dist/llms/humanize-industry.test.d.ts.map +1 -0
  191. package/dist/llms/index.js +12 -12
  192. package/dist/llms/index.mjs +2 -2
  193. package/dist/maps/index.js +5 -5
  194. package/dist/maps/index.mjs +3 -3
  195. package/dist/search/index.js +4 -4
  196. package/dist/search/index.mjs +3 -3
  197. package/dist/seo/client.js +5 -5
  198. package/dist/seo/client.mjs +4 -4
  199. package/dist/seo/index.js +5 -5
  200. package/dist/seo/index.mjs +4 -4
  201. package/dist/server/index.js +3 -3
  202. package/dist/server/index.mjs +2 -2
  203. package/dist/shared/version.d.ts +1 -1
  204. package/dist/signal/index.js +11 -11
  205. package/dist/signal/index.mjs +2 -2
  206. package/dist/sitemap/index.js +2 -2
  207. package/dist/sitemap/index.mjs +1 -1
  208. package/dist/sync/index.js +16 -16
  209. package/dist/sync/index.mjs +4 -4
  210. package/package.json +1 -1
  211. package/dist/AnalyticsProvider-KCLRFOX6.mjs +0 -10
  212. package/dist/AnalyticsProvider-TXM3DRLI.js +0 -31
  213. package/dist/ChatWidget-LD54Z2PQ.js +0 -20
  214. package/dist/ChatWidget-PMDPSZXG.mjs +0 -11
  215. package/dist/EngageWidget-4CBFRN4Y.mjs +0 -9
  216. package/dist/EngageWidget-BF5NMQ5A.js +0 -18
  217. package/dist/ManagedForm-E4WHMARH.js +0 -23
  218. package/dist/ManagedForm-VU2TKV6J.mjs +0 -14
  219. package/dist/SitemapSync-AJU4DM3G.js +0 -17
  220. package/dist/SitemapSync-T75NAFB3.mjs +0 -8
  221. package/dist/chunk-JPTJGLKS.mjs +0 -6
  222. package/dist/chunk-PPCTL4B5.mjs.map +0 -1
  223. package/dist/chunk-S65JSRWW.js +0 -8
  224. package/dist/chunk-UABMMR7U.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "package": "@sonordev/site-kit",
4
- "version": "5.0.0",
4
+ "version": "5.1.0",
5
5
  "description": "Machine-readable manifest for coding agents integrating a site with Sonor. See AGENTS.md (shipped) and docs/SITE-KIT-AGENT-NATIVE.md.",
6
6
  "env": {
7
7
  "required": [
@@ -153,18 +153,21 @@
153
153
  {
154
154
  "name": "blog",
155
155
  "import": "@sonordev/site-kit/blog",
156
- "side": "server",
157
- "purpose": "Sonor-managed blog with SSG helpers (generateStaticParams, getBlogPost)."
156
+ "side": "client",
157
+ "purpose": "Client-only blog pieces: TableOfContents, BlogFAQ, AuthorCard, ServiceCallout, NewsletterWidget, ClusterNavigation.",
158
+ "caution": "Stamped 'use client' at build time. BlogLayout, BlogList, BlogPost, BlogSidebar, RelatedPosts, ClusterLandingPage and the *Page helpers are async server components — import them from @sonordev/site-kit/blog/server-ui. Importing them from this barrel hands Next an async component across a client boundary and the route 500s in production."
158
159
  },
159
160
  {
160
161
  "name": "blog/server",
161
162
  "import": "@sonordev/site-kit/blog/server",
162
- "side": "unknown"
163
+ "side": "server",
164
+ "purpose": "server-only data + SSG helpers: getBlogPost, getAllBlogSlugs, generateBlogStaticParams, metadata, schema, RSS."
163
165
  },
164
166
  {
165
167
  "name": "blog/server-ui",
166
168
  "import": "@sonordev/site-kit/blog/server-ui",
167
- "side": "unknown"
169
+ "side": "server",
170
+ "purpose": "RSC-safe blog UI: BlogPost, BlogList, BlogLayout, BlogSidebar, RelatedPosts, ClusterLandingPage, ClusterNavigation, and the BlogPage/BlogPostPage/CategoryPage helpers. Import blog UI from here, not from the blog barrel."
168
171
  },
169
172
  {
170
173
  "name": "commerce",
@@ -0,0 +1,10 @@
1
+ export { AnalyticsProvider, useAnalytics, useAnalyticsOptional, useTrackEvent } from './chunk-OAJVITNO.mjs';
2
+ import './chunk-3DPXOZAU.mjs';
3
+ import './chunk-ZZQAGCSI.mjs';
4
+ import './chunk-6EDVCUAG.mjs';
5
+ import './chunk-ADOGOLYO.mjs';
6
+ import './chunk-SXNKLHOX.mjs';
7
+ import './chunk-4SQ6PROR.mjs';
8
+ import './chunk-BEXTDHO4.mjs';
9
+ //# sourceMappingURL=AnalyticsProvider-2LCSA6G3.mjs.map
10
+ //# sourceMappingURL=AnalyticsProvider-2LCSA6G3.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"AnalyticsProvider-KCLRFOX6.mjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"AnalyticsProvider-2LCSA6G3.mjs"}
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ var chunkHPIY7AR3_js = require('./chunk-HPIY7AR3.js');
4
+ require('./chunk-HMFFAUCD.js');
5
+ require('./chunk-RC4WWQXR.js');
6
+ require('./chunk-VJMPIRSD.js');
7
+ require('./chunk-VIIGOCX4.js');
8
+ require('./chunk-CKPFETIO.js');
9
+ require('./chunk-YPEX4RDE.js');
10
+ require('./chunk-SNAQBZPT.js');
11
+
12
+
13
+
14
+ Object.defineProperty(exports, "AnalyticsProvider", {
15
+ enumerable: true,
16
+ get: function () { return chunkHPIY7AR3_js.AnalyticsProvider; }
17
+ });
18
+ Object.defineProperty(exports, "useAnalytics", {
19
+ enumerable: true,
20
+ get: function () { return chunkHPIY7AR3_js.useAnalytics; }
21
+ });
22
+ Object.defineProperty(exports, "useAnalyticsOptional", {
23
+ enumerable: true,
24
+ get: function () { return chunkHPIY7AR3_js.useAnalyticsOptional; }
25
+ });
26
+ Object.defineProperty(exports, "useTrackEvent", {
27
+ enumerable: true,
28
+ get: function () { return chunkHPIY7AR3_js.useTrackEvent; }
29
+ });
30
+ //# sourceMappingURL=AnalyticsProvider-V2U3TQMH.js.map
31
+ //# sourceMappingURL=AnalyticsProvider-V2U3TQMH.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"AnalyticsProvider-TXM3DRLI.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"AnalyticsProvider-V2U3TQMH.js"}
@@ -2,9 +2,9 @@
2
2
  'use strict';
3
3
 
4
4
  var chunkHGNSJXWT_js = require('./chunk-HGNSJXWT.js');
5
- var chunk4D2G5ZNP_js = require('./chunk-4D2G5ZNP.js');
6
- require('./chunk-FQ3JQV3M.js');
7
- require('./chunk-S65JSRWW.js');
5
+ var chunkVIIGOCX4_js = require('./chunk-VIIGOCX4.js');
6
+ require('./chunk-CKPFETIO.js');
7
+ require('./chunk-YPEX4RDE.js');
8
8
  require('./chunk-SNAQBZPT.js');
9
9
  var react = require('react');
10
10
 
@@ -19,7 +19,7 @@ function trackBlogView(slug) {
19
19
  if (sessionStorage.getItem(key)) return;
20
20
  } catch {
21
21
  }
22
- void chunk4D2G5ZNP_js.sonorFetch(
22
+ void chunkVIIGOCX4_js.sonorFetch(
23
23
  `${baseUrl}/public/blog/view`,
24
24
  {
25
25
  method: "POST",
@@ -47,5 +47,5 @@ function BlogViewTracker({ slug }) {
47
47
 
48
48
  exports.BlogViewTracker = BlogViewTracker;
49
49
  exports.trackBlogView = trackBlogView;
50
- //# sourceMappingURL=BlogViewTracker-J6LRGUHU.js.map
51
- //# sourceMappingURL=BlogViewTracker-J6LRGUHU.js.map
50
+ //# sourceMappingURL=BlogViewTracker-COTPD7WL.js.map
51
+ //# sourceMappingURL=BlogViewTracker-COTPD7WL.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/blog/BlogViewTracker.tsx"],"names":["sonorFetch","useDeferredActivation","useEffect"],"mappings":";;;;;;;;;AAmBA,IAAM,kBAAA,GAAqB,wBAAA;AAUpB,SAAS,cAAc,IAAA,EAAoB;AAChD,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,MAAA,KAAW,WAAA,EAAa;AAI5C,EAAA,MAAM,CAAA,GAAI,MAAA;AAIV,EAAA,MAAM,UAAU,CAAA,CAAE,oBAAA;AAClB,EAAA,IAAI,CAAC,OAAA,IAAW,CAAC,CAAA,CAAE,oBAAA,EAAsB;AAKzC,EAAA,MAAM,GAAA,GAAM,CAAA,EAAG,kBAAkB,CAAA,EAAG,IAAI,CAAA,CAAA;AACxC,EAAA,IAAI;AACF,IAAA,IAAI,cAAA,CAAe,OAAA,CAAQ,GAAG,CAAA,EAAG;AAAA,EACnC,CAAA,CAAA,MAAQ;AAAA,EAER;AAIA,EAAA,KAAKA,2BAAA;AAAA,IACH,GAAG,OAAO,CAAA,iBAAA,CAAA;AAAA,IACV;AAAA,MACE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,MAC9C,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,MAAM;AAAA,KAC/B;AAAA,IACA,EAAE,SAAS,CAAA;AAAE,GACf,CACG,IAAA,CAAK,CAAC,GAAA,KAAQ;AACb,IAAA,IAAI,IAAI,EAAA,EAAI;AACV,MAAA,IAAI;AACF,QAAA,cAAA,CAAe,OAAA,CAAQ,KAAK,GAAG,CAAA;AAAA,MACjC,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AAAA,EAEb,CAAC,CAAA;AACL;AAEO,SAAS,eAAA,CAAgB,EAAE,IAAA,EAAK,EAAyB;AAC9D,EAAA,MAAM,KAAA,GAAQC,uCAAsB,IAAI,CAAA;AAExC,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,KAAA,gBAAqB,IAAI,CAAA;AAAA,EAC/B,CAAA,EAAG,CAAC,KAAA,EAAO,IAAI,CAAC,CAAA;AAEhB,EAAA,OAAO,IAAA;AACT","file":"BlogViewTracker-J6LRGUHU.js","sourcesContent":["'use client'\n\n/**\n * @sonordev/site-kit blog — reader-side view tracking\n *\n * Counts actual readers by POSTing to /public/blog/view once per post per\n * browser session. This replaces the server-side increment that rode\n * GET posts/:slug — under ISR that GET fires on REVALIDATION, not on reads,\n * so view_count was measuring cache churn instead of people.\n *\n * Childless by design (renders null, never wraps children) and gated behind\n * the same idle deferral SiteKitLayout uses, so it stays out of the critical\n * hydration window.\n */\n\nimport { useEffect } from 'react'\nimport { useDeferredActivation } from '../shared/defer'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nconst SESSION_KEY_PREFIX = '__sonor_blog_viewed__:'\n\nexport interface BlogViewTrackerProps {\n slug: string\n}\n\n/**\n * The effect body, exported for tests (the package's vitest runs in node, so\n * the component's mount path can't be exercised directly).\n */\nexport function trackBlogView(slug: string): void {\n if (!slug || typeof window === 'undefined') return\n\n // SiteKitLayout globals; the credential is the minted st1. token, never\n // the raw key. Without SiteKitLayout the globals are absent — no-op.\n const w = window as Window & {\n __SITE_KIT_API_URL__?: string\n __SITE_KIT_API_KEY__?: string\n }\n const baseUrl = w.__SITE_KIT_API_URL__\n if (!baseUrl || !w.__SITE_KIT_API_KEY__) return\n\n // One view per post per session. sessionStorage can throw (private\n // windows, storage-blocked browsers) — treat a throw as \"not yet viewed\"\n // and skip writing rather than skip counting.\n const key = `${SESSION_KEY_PREFIX}${slug}`\n try {\n if (sessionStorage.getItem(key)) return\n } catch {\n /* unreadable storage — count the view, skip dedupe */\n }\n\n // retries: 0 — the increment is not idempotent, so a retried request\n // would double-count.\n void sonorFetch(\n `${baseUrl}/public/blog/view`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ slug }),\n },\n { retries: 0 }\n )\n .then((res) => {\n if (res.ok) {\n try {\n sessionStorage.setItem(key, '1')\n } catch {\n /* storage write blocked — worst case is a re-count next mount */\n }\n }\n })\n .catch(() => {\n /* view tracking is best-effort; never surface errors */\n })\n}\n\nexport function BlogViewTracker({ slug }: BlogViewTrackerProps) {\n const ready = useDeferredActivation(true)\n\n useEffect(() => {\n if (ready) trackBlogView(slug)\n }, [ready, slug])\n\n return null\n}\n"]}
1
+ {"version":3,"sources":["../src/blog/BlogViewTracker.tsx"],"names":["sonorFetch","useDeferredActivation","useEffect"],"mappings":";;;;;;;;;AAmBA,IAAM,kBAAA,GAAqB,wBAAA;AAUpB,SAAS,cAAc,IAAA,EAAoB;AAChD,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,MAAA,KAAW,WAAA,EAAa;AAI5C,EAAA,MAAM,CAAA,GAAI,MAAA;AAIV,EAAA,MAAM,UAAU,CAAA,CAAE,oBAAA;AAClB,EAAA,IAAI,CAAC,OAAA,IAAW,CAAC,CAAA,CAAE,oBAAA,EAAsB;AAKzC,EAAA,MAAM,GAAA,GAAM,CAAA,EAAG,kBAAkB,CAAA,EAAG,IAAI,CAAA,CAAA;AACxC,EAAA,IAAI;AACF,IAAA,IAAI,cAAA,CAAe,OAAA,CAAQ,GAAG,CAAA,EAAG;AAAA,EACnC,CAAA,CAAA,MAAQ;AAAA,EAER;AAIA,EAAA,KAAKA,2BAAA;AAAA,IACH,GAAG,OAAO,CAAA,iBAAA,CAAA;AAAA,IACV;AAAA,MACE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,MAC9C,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,MAAM;AAAA,KAC/B;AAAA,IACA,EAAE,SAAS,CAAA;AAAE,GACf,CACG,IAAA,CAAK,CAAC,GAAA,KAAQ;AACb,IAAA,IAAI,IAAI,EAAA,EAAI;AACV,MAAA,IAAI;AACF,QAAA,cAAA,CAAe,OAAA,CAAQ,KAAK,GAAG,CAAA;AAAA,MACjC,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AAAA,EAEb,CAAC,CAAA;AACL;AAEO,SAAS,eAAA,CAAgB,EAAE,IAAA,EAAK,EAAyB;AAC9D,EAAA,MAAM,KAAA,GAAQC,uCAAsB,IAAI,CAAA;AAExC,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,KAAA,gBAAqB,IAAI,CAAA;AAAA,EAC/B,CAAA,EAAG,CAAC,KAAA,EAAO,IAAI,CAAC,CAAA;AAEhB,EAAA,OAAO,IAAA;AACT","file":"BlogViewTracker-COTPD7WL.js","sourcesContent":["'use client'\n\n/**\n * @sonordev/site-kit blog — reader-side view tracking\n *\n * Counts actual readers by POSTing to /public/blog/view once per post per\n * browser session. This replaces the server-side increment that rode\n * GET posts/:slug — under ISR that GET fires on REVALIDATION, not on reads,\n * so view_count was measuring cache churn instead of people.\n *\n * Childless by design (renders null, never wraps children) and gated behind\n * the same idle deferral SiteKitLayout uses, so it stays out of the critical\n * hydration window.\n */\n\nimport { useEffect } from 'react'\nimport { useDeferredActivation } from '../shared/defer'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nconst SESSION_KEY_PREFIX = '__sonor_blog_viewed__:'\n\nexport interface BlogViewTrackerProps {\n slug: string\n}\n\n/**\n * The effect body, exported for tests (the package's vitest runs in node, so\n * the component's mount path can't be exercised directly).\n */\nexport function trackBlogView(slug: string): void {\n if (!slug || typeof window === 'undefined') return\n\n // SiteKitLayout globals; the credential is the minted st1. token, never\n // the raw key. Without SiteKitLayout the globals are absent — no-op.\n const w = window as Window & {\n __SITE_KIT_API_URL__?: string\n __SITE_KIT_API_KEY__?: string\n }\n const baseUrl = w.__SITE_KIT_API_URL__\n if (!baseUrl || !w.__SITE_KIT_API_KEY__) return\n\n // One view per post per session. sessionStorage can throw (private\n // windows, storage-blocked browsers) — treat a throw as \"not yet viewed\"\n // and skip writing rather than skip counting.\n const key = `${SESSION_KEY_PREFIX}${slug}`\n try {\n if (sessionStorage.getItem(key)) return\n } catch {\n /* unreadable storage — count the view, skip dedupe */\n }\n\n // retries: 0 — the increment is not idempotent, so a retried request\n // would double-count.\n void sonorFetch(\n `${baseUrl}/public/blog/view`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ slug }),\n },\n { retries: 0 }\n )\n .then((res) => {\n if (res.ok) {\n try {\n sessionStorage.setItem(key, '1')\n } catch {\n /* storage write blocked — worst case is a re-count next mount */\n }\n }\n })\n .catch(() => {\n /* view tracking is best-effort; never surface errors */\n })\n}\n\nexport function BlogViewTracker({ slug }: BlogViewTrackerProps) {\n const ready = useDeferredActivation(true)\n\n useEffect(() => {\n if (ready) trackBlogView(slug)\n }, [ready, slug])\n\n return null\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
  import { useDeferredActivation } from './chunk-ZVBLXXNJ.mjs';
3
- import { sonorFetch } from './chunk-4UHO6DPJ.mjs';
4
- import './chunk-FDWDXMJL.mjs';
5
- import './chunk-JPTJGLKS.mjs';
3
+ import { sonorFetch } from './chunk-ADOGOLYO.mjs';
4
+ import './chunk-SXNKLHOX.mjs';
5
+ import './chunk-4SQ6PROR.mjs';
6
6
  import './chunk-BEXTDHO4.mjs';
7
7
  import { useEffect } from 'react';
8
8
 
@@ -44,5 +44,5 @@ function BlogViewTracker({ slug }) {
44
44
  }
45
45
 
46
46
  export { BlogViewTracker, trackBlogView };
47
- //# sourceMappingURL=BlogViewTracker-PZWAWB3O.mjs.map
48
- //# sourceMappingURL=BlogViewTracker-PZWAWB3O.mjs.map
47
+ //# sourceMappingURL=BlogViewTracker-HG25ONRP.mjs.map
48
+ //# sourceMappingURL=BlogViewTracker-HG25ONRP.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/blog/BlogViewTracker.tsx"],"names":[],"mappings":";;;;;;;AAmBA,IAAM,kBAAA,GAAqB,wBAAA;AAUpB,SAAS,cAAc,IAAA,EAAoB;AAChD,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,MAAA,KAAW,WAAA,EAAa;AAI5C,EAAA,MAAM,CAAA,GAAI,MAAA;AAIV,EAAA,MAAM,UAAU,CAAA,CAAE,oBAAA;AAClB,EAAA,IAAI,CAAC,OAAA,IAAW,CAAC,CAAA,CAAE,oBAAA,EAAsB;AAKzC,EAAA,MAAM,GAAA,GAAM,CAAA,EAAG,kBAAkB,CAAA,EAAG,IAAI,CAAA,CAAA;AACxC,EAAA,IAAI;AACF,IAAA,IAAI,cAAA,CAAe,OAAA,CAAQ,GAAG,CAAA,EAAG;AAAA,EACnC,CAAA,CAAA,MAAQ;AAAA,EAER;AAIA,EAAA,KAAK,UAAA;AAAA,IACH,GAAG,OAAO,CAAA,iBAAA,CAAA;AAAA,IACV;AAAA,MACE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,MAC9C,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,MAAM;AAAA,KAC/B;AAAA,IACA,EAAE,SAAS,CAAA;AAAE,GACf,CACG,IAAA,CAAK,CAAC,GAAA,KAAQ;AACb,IAAA,IAAI,IAAI,EAAA,EAAI;AACV,MAAA,IAAI;AACF,QAAA,cAAA,CAAe,OAAA,CAAQ,KAAK,GAAG,CAAA;AAAA,MACjC,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AAAA,EAEb,CAAC,CAAA;AACL;AAEO,SAAS,eAAA,CAAgB,EAAE,IAAA,EAAK,EAAyB;AAC9D,EAAA,MAAM,KAAA,GAAQ,sBAAsB,IAAI,CAAA;AAExC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,KAAA,gBAAqB,IAAI,CAAA;AAAA,EAC/B,CAAA,EAAG,CAAC,KAAA,EAAO,IAAI,CAAC,CAAA;AAEhB,EAAA,OAAO,IAAA;AACT","file":"BlogViewTracker-PZWAWB3O.mjs","sourcesContent":["'use client'\n\n/**\n * @sonordev/site-kit blog — reader-side view tracking\n *\n * Counts actual readers by POSTing to /public/blog/view once per post per\n * browser session. This replaces the server-side increment that rode\n * GET posts/:slug — under ISR that GET fires on REVALIDATION, not on reads,\n * so view_count was measuring cache churn instead of people.\n *\n * Childless by design (renders null, never wraps children) and gated behind\n * the same idle deferral SiteKitLayout uses, so it stays out of the critical\n * hydration window.\n */\n\nimport { useEffect } from 'react'\nimport { useDeferredActivation } from '../shared/defer'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nconst SESSION_KEY_PREFIX = '__sonor_blog_viewed__:'\n\nexport interface BlogViewTrackerProps {\n slug: string\n}\n\n/**\n * The effect body, exported for tests (the package's vitest runs in node, so\n * the component's mount path can't be exercised directly).\n */\nexport function trackBlogView(slug: string): void {\n if (!slug || typeof window === 'undefined') return\n\n // SiteKitLayout globals; the credential is the minted st1. token, never\n // the raw key. Without SiteKitLayout the globals are absent — no-op.\n const w = window as Window & {\n __SITE_KIT_API_URL__?: string\n __SITE_KIT_API_KEY__?: string\n }\n const baseUrl = w.__SITE_KIT_API_URL__\n if (!baseUrl || !w.__SITE_KIT_API_KEY__) return\n\n // One view per post per session. sessionStorage can throw (private\n // windows, storage-blocked browsers) — treat a throw as \"not yet viewed\"\n // and skip writing rather than skip counting.\n const key = `${SESSION_KEY_PREFIX}${slug}`\n try {\n if (sessionStorage.getItem(key)) return\n } catch {\n /* unreadable storage — count the view, skip dedupe */\n }\n\n // retries: 0 — the increment is not idempotent, so a retried request\n // would double-count.\n void sonorFetch(\n `${baseUrl}/public/blog/view`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ slug }),\n },\n { retries: 0 }\n )\n .then((res) => {\n if (res.ok) {\n try {\n sessionStorage.setItem(key, '1')\n } catch {\n /* storage write blocked — worst case is a re-count next mount */\n }\n }\n })\n .catch(() => {\n /* view tracking is best-effort; never surface errors */\n })\n}\n\nexport function BlogViewTracker({ slug }: BlogViewTrackerProps) {\n const ready = useDeferredActivation(true)\n\n useEffect(() => {\n if (ready) trackBlogView(slug)\n }, [ready, slug])\n\n return null\n}\n"]}
1
+ {"version":3,"sources":["../src/blog/BlogViewTracker.tsx"],"names":[],"mappings":";;;;;;;AAmBA,IAAM,kBAAA,GAAqB,wBAAA;AAUpB,SAAS,cAAc,IAAA,EAAoB;AAChD,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,MAAA,KAAW,WAAA,EAAa;AAI5C,EAAA,MAAM,CAAA,GAAI,MAAA;AAIV,EAAA,MAAM,UAAU,CAAA,CAAE,oBAAA;AAClB,EAAA,IAAI,CAAC,OAAA,IAAW,CAAC,CAAA,CAAE,oBAAA,EAAsB;AAKzC,EAAA,MAAM,GAAA,GAAM,CAAA,EAAG,kBAAkB,CAAA,EAAG,IAAI,CAAA,CAAA;AACxC,EAAA,IAAI;AACF,IAAA,IAAI,cAAA,CAAe,OAAA,CAAQ,GAAG,CAAA,EAAG;AAAA,EACnC,CAAA,CAAA,MAAQ;AAAA,EAER;AAIA,EAAA,KAAK,UAAA;AAAA,IACH,GAAG,OAAO,CAAA,iBAAA,CAAA;AAAA,IACV;AAAA,MACE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,MAC9C,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,MAAM;AAAA,KAC/B;AAAA,IACA,EAAE,SAAS,CAAA;AAAE,GACf,CACG,IAAA,CAAK,CAAC,GAAA,KAAQ;AACb,IAAA,IAAI,IAAI,EAAA,EAAI;AACV,MAAA,IAAI;AACF,QAAA,cAAA,CAAe,OAAA,CAAQ,KAAK,GAAG,CAAA;AAAA,MACjC,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AAAA,EAEb,CAAC,CAAA;AACL;AAEO,SAAS,eAAA,CAAgB,EAAE,IAAA,EAAK,EAAyB;AAC9D,EAAA,MAAM,KAAA,GAAQ,sBAAsB,IAAI,CAAA;AAExC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,KAAA,gBAAqB,IAAI,CAAA;AAAA,EAC/B,CAAA,EAAG,CAAC,KAAA,EAAO,IAAI,CAAC,CAAA;AAEhB,EAAA,OAAO,IAAA;AACT","file":"BlogViewTracker-HG25ONRP.mjs","sourcesContent":["'use client'\n\n/**\n * @sonordev/site-kit blog — reader-side view tracking\n *\n * Counts actual readers by POSTing to /public/blog/view once per post per\n * browser session. This replaces the server-side increment that rode\n * GET posts/:slug — under ISR that GET fires on REVALIDATION, not on reads,\n * so view_count was measuring cache churn instead of people.\n *\n * Childless by design (renders null, never wraps children) and gated behind\n * the same idle deferral SiteKitLayout uses, so it stays out of the critical\n * hydration window.\n */\n\nimport { useEffect } from 'react'\nimport { useDeferredActivation } from '../shared/defer'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nconst SESSION_KEY_PREFIX = '__sonor_blog_viewed__:'\n\nexport interface BlogViewTrackerProps {\n slug: string\n}\n\n/**\n * The effect body, exported for tests (the package's vitest runs in node, so\n * the component's mount path can't be exercised directly).\n */\nexport function trackBlogView(slug: string): void {\n if (!slug || typeof window === 'undefined') return\n\n // SiteKitLayout globals; the credential is the minted st1. token, never\n // the raw key. Without SiteKitLayout the globals are absent — no-op.\n const w = window as Window & {\n __SITE_KIT_API_URL__?: string\n __SITE_KIT_API_KEY__?: string\n }\n const baseUrl = w.__SITE_KIT_API_URL__\n if (!baseUrl || !w.__SITE_KIT_API_KEY__) return\n\n // One view per post per session. sessionStorage can throw (private\n // windows, storage-blocked browsers) — treat a throw as \"not yet viewed\"\n // and skip writing rather than skip counting.\n const key = `${SESSION_KEY_PREFIX}${slug}`\n try {\n if (sessionStorage.getItem(key)) return\n } catch {\n /* unreadable storage — count the view, skip dedupe */\n }\n\n // retries: 0 — the increment is not idempotent, so a retried request\n // would double-count.\n void sonorFetch(\n `${baseUrl}/public/blog/view`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ slug }),\n },\n { retries: 0 }\n )\n .then((res) => {\n if (res.ok) {\n try {\n sessionStorage.setItem(key, '1')\n } catch {\n /* storage write blocked — worst case is a re-count next mount */\n }\n }\n })\n .catch(() => {\n /* view tracking is best-effort; never surface errors */\n })\n}\n\nexport function BlogViewTracker({ slug }: BlogViewTrackerProps) {\n const ready = useDeferredActivation(true)\n\n useEffect(() => {\n if (ready) trackBlogView(slug)\n }, [ready, slug])\n\n return null\n}\n"]}
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ var chunkIQLYFQKZ_js = require('./chunk-IQLYFQKZ.js');
4
+ require('./chunk-VCNPTLK2.js');
5
+ require('./chunk-GYAH4KFC.js');
6
+ require('./chunk-KHPJ3CEL.js');
7
+ require('./chunk-VJMPIRSD.js');
8
+ require('./chunk-VIIGOCX4.js');
9
+ require('./chunk-CKPFETIO.js');
10
+ require('./chunk-YPEX4RDE.js');
11
+ require('./chunk-SNAQBZPT.js');
12
+
13
+
14
+
15
+ Object.defineProperty(exports, "ChatWidget", {
16
+ enumerable: true,
17
+ get: function () { return chunkIQLYFQKZ_js.ChatWidget; }
18
+ });
19
+ //# sourceMappingURL=ChatWidget-4QUJYFXU.js.map
20
+ //# sourceMappingURL=ChatWidget-4QUJYFXU.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"ChatWidget-LD54Z2PQ.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"ChatWidget-4QUJYFXU.js"}
@@ -0,0 +1,11 @@
1
+ export { ChatWidget } from './chunk-2XHEUWHV.mjs';
2
+ import './chunk-BUDV7QHH.mjs';
3
+ import './chunk-ZFZMN4LT.mjs';
4
+ import './chunk-TMVKRQGJ.mjs';
5
+ import './chunk-6EDVCUAG.mjs';
6
+ import './chunk-ADOGOLYO.mjs';
7
+ import './chunk-SXNKLHOX.mjs';
8
+ import './chunk-4SQ6PROR.mjs';
9
+ import './chunk-BEXTDHO4.mjs';
10
+ //# sourceMappingURL=ChatWidget-RWO7R7EJ.mjs.map
11
+ //# sourceMappingURL=ChatWidget-RWO7R7EJ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"ChatWidget-PMDPSZXG.mjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"ChatWidget-RWO7R7EJ.mjs"}
@@ -0,0 +1,9 @@
1
+ export { EngageWidget } from './chunk-FZISCIJV.mjs';
2
+ import './chunk-ZZQAGCSI.mjs';
3
+ import './chunk-6EDVCUAG.mjs';
4
+ import './chunk-ADOGOLYO.mjs';
5
+ import './chunk-SXNKLHOX.mjs';
6
+ import './chunk-4SQ6PROR.mjs';
7
+ import './chunk-BEXTDHO4.mjs';
8
+ //# sourceMappingURL=EngageWidget-LF4AC4QN.mjs.map
9
+ //# sourceMappingURL=EngageWidget-LF4AC4QN.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"EngageWidget-4CBFRN4Y.mjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"EngageWidget-LF4AC4QN.mjs"}
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var chunkBGBJSMXT_js = require('./chunk-BGBJSMXT.js');
4
+ require('./chunk-RC4WWQXR.js');
5
+ require('./chunk-VJMPIRSD.js');
6
+ require('./chunk-VIIGOCX4.js');
7
+ require('./chunk-CKPFETIO.js');
8
+ require('./chunk-YPEX4RDE.js');
9
+ require('./chunk-SNAQBZPT.js');
10
+
11
+
12
+
13
+ Object.defineProperty(exports, "EngageWidget", {
14
+ enumerable: true,
15
+ get: function () { return chunkBGBJSMXT_js.EngageWidget; }
16
+ });
17
+ //# sourceMappingURL=EngageWidget-RSOXB3YM.js.map
18
+ //# sourceMappingURL=EngageWidget-RSOXB3YM.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"EngageWidget-BF5NMQ5A.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"EngageWidget-RSOXB3YM.js"}
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunk4D2G5ZNP_js = require('./chunk-4D2G5ZNP.js');
5
- require('./chunk-FQ3JQV3M.js');
6
- require('./chunk-S65JSRWW.js');
4
+ var chunkVIIGOCX4_js = require('./chunk-VIIGOCX4.js');
5
+ require('./chunk-CKPFETIO.js');
6
+ require('./chunk-YPEX4RDE.js');
7
7
  require('./chunk-SNAQBZPT.js');
8
8
  var React = require('react');
9
9
  var jsxRuntime = require('react/jsx-runtime');
@@ -67,7 +67,7 @@ async function uploadFormFile(file) {
67
67
  }
68
68
  const body = new FormData();
69
69
  body.append("file", file);
70
- const response = await chunk4D2G5ZNP_js.sonorFetch(
70
+ const response = await chunkVIIGOCX4_js.sonorFetch(
71
71
  `${apiUrl}/api/public/forms/upload`,
72
72
  {
73
73
  method: "POST",
@@ -87,5 +87,5 @@ async function uploadFormFile(file) {
87
87
  }
88
88
 
89
89
  exports.FileField = FileField;
90
- //# sourceMappingURL=FileField-VXADIOMN.js.map
91
- //# sourceMappingURL=FileField-VXADIOMN.js.map
90
+ //# sourceMappingURL=FileField-S2GUM3QB.js.map
91
+ //# sourceMappingURL=FileField-S2GUM3QB.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/forms/FileField.tsx"],"names":["React","jsxs","Fragment","jsx","sonorFetch"],"mappings":"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","file":"FileField-VXADIOMN.js","sourcesContent":["'use client'\n\n/**\n * File upload field — the one field type that cannot render on the server.\n *\n * It holds upload state and reads the browser-published credential globals, so\n * it lives here rather than in FormField.tsx. Pulling it out is what lets\n * FormField drop its `'use client'` directive and render inside a Server\n * Component (see StaticForm.tsx); a form WITHOUT a file field now ships no\n * field-rendering JavaScript at all.\n *\n * Uploads the chosen file to the Sonor API, which stores it and returns a\n * public URL — that URL becomes the field value, so large files never touch\n * the JSON submission body. The value stays empty until the upload succeeds,\n * so a required file field correctly blocks submission until the upload\n * completes (rather than submitting a useless bare filename).\n *\n * Note: forms containing a file field are NOT native-POST eligible (see\n * native-fallback.tsx) — a form-encoded POST cannot run this upload — so the\n * server shell renders a plain disabled-looking file input and the real\n * control arrives with the enhancement.\n */\n\nimport React from 'react'\nimport type { FormField as FormFieldType } from './types'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface FileFieldProps {\n field: FormFieldType\n inputId: string\n classPrefix: string\n baseInputStyle: React.CSSProperties\n onChange: (value: unknown) => void\n}\n\nexport function FileField({\n field,\n inputId,\n classPrefix,\n baseInputStyle,\n onChange,\n}: FileFieldProps) {\n const [status, setStatus] = React.useState<'idle' | 'uploading' | 'error'>('idle')\n const [fileName, setFileName] = React.useState('')\n\n const handleFile = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file) return\n setFileName(file.name)\n setStatus('uploading')\n onChange('') // clear any prior URL until this upload completes\n try {\n const url = await uploadFormFile(file)\n onChange(url)\n setStatus('idle')\n } catch (err) {\n console.error('[Forms] File upload failed:', err)\n onChange('')\n setStatus('error')\n }\n }\n\n return (\n <>\n <input\n id={inputId}\n className={`${classPrefix}__input ${classPrefix}__input--file`}\n type=\"file\"\n name={field.slug}\n required={field.is_required}\n disabled={status === 'uploading'}\n onChange={handleFile}\n style={baseInputStyle}\n />\n {status === 'uploading' && (\n <p style={{ color: 'var(--sk-text-tertiary, #6b7280)', fontSize: 14, marginTop: 4 }}>\n Uploading {fileName}…\n </p>\n )}\n {status === 'error' && (\n <p role=\"alert\" style={{ color: 'var(--sk-error, #dc2626)', fontSize: 14, marginTop: 4 }}>\n Upload failed. Please choose the file again.\n </p>\n )}\n </>\n )\n}\n\n/** Upload a single file to the Sonor API and return its stored public URL. */\nasync function uploadFormFile(file: File): Promise<string> {\n const apiUrl =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey =\n typeof window !== 'undefined' ? (window as any).__SITE_KIT_API_KEY__ : undefined\n if (!apiKey) {\n throw new Error('API key is required to upload files.')\n }\n\n const body = new FormData()\n body.append('file', file)\n\n // No Content-Type header — the browser sets the multipart boundary itself.\n const response = await sonorFetch(\n `${apiUrl}/api/public/forms/upload`,\n {\n method: 'POST',\n headers: { Authorization: `Bearer ${apiKey}` },\n body,\n },\n { retries: 1, timeoutMs: 60000 },\n )\n\n if (!response.ok) {\n throw new Error(`Upload failed (${response.status})`)\n }\n const data = (await response.json().catch(() => null)) as { url?: string } | null\n if (!data?.url) {\n throw new Error('Upload did not return a URL.')\n }\n return data.url\n}\n"]}
1
+ {"version":3,"sources":["../src/forms/FileField.tsx"],"names":["React","jsxs","Fragment","jsx","sonorFetch"],"mappings":"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","file":"FileField-S2GUM3QB.js","sourcesContent":["'use client'\n\n/**\n * File upload field — the one field type that cannot render on the server.\n *\n * It holds upload state and reads the browser-published credential globals, so\n * it lives here rather than in FormField.tsx. Pulling it out is what lets\n * FormField drop its `'use client'` directive and render inside a Server\n * Component (see StaticForm.tsx); a form WITHOUT a file field now ships no\n * field-rendering JavaScript at all.\n *\n * Uploads the chosen file to the Sonor API, which stores it and returns a\n * public URL — that URL becomes the field value, so large files never touch\n * the JSON submission body. The value stays empty until the upload succeeds,\n * so a required file field correctly blocks submission until the upload\n * completes (rather than submitting a useless bare filename).\n *\n * Note: forms containing a file field are NOT native-POST eligible (see\n * native-fallback.tsx) — a form-encoded POST cannot run this upload — so the\n * server shell renders a plain disabled-looking file input and the real\n * control arrives with the enhancement.\n */\n\nimport React from 'react'\nimport type { FormField as FormFieldType } from './types'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface FileFieldProps {\n field: FormFieldType\n inputId: string\n classPrefix: string\n baseInputStyle: React.CSSProperties\n onChange: (value: unknown) => void\n}\n\nexport function FileField({\n field,\n inputId,\n classPrefix,\n baseInputStyle,\n onChange,\n}: FileFieldProps) {\n const [status, setStatus] = React.useState<'idle' | 'uploading' | 'error'>('idle')\n const [fileName, setFileName] = React.useState('')\n\n const handleFile = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file) return\n setFileName(file.name)\n setStatus('uploading')\n onChange('') // clear any prior URL until this upload completes\n try {\n const url = await uploadFormFile(file)\n onChange(url)\n setStatus('idle')\n } catch (err) {\n console.error('[Forms] File upload failed:', err)\n onChange('')\n setStatus('error')\n }\n }\n\n return (\n <>\n <input\n id={inputId}\n className={`${classPrefix}__input ${classPrefix}__input--file`}\n type=\"file\"\n name={field.slug}\n required={field.is_required}\n disabled={status === 'uploading'}\n onChange={handleFile}\n style={baseInputStyle}\n />\n {status === 'uploading' && (\n <p style={{ color: 'var(--sk-text-tertiary, #6b7280)', fontSize: 14, marginTop: 4 }}>\n Uploading {fileName}…\n </p>\n )}\n {status === 'error' && (\n <p role=\"alert\" style={{ color: 'var(--sk-error, #dc2626)', fontSize: 14, marginTop: 4 }}>\n Upload failed. Please choose the file again.\n </p>\n )}\n </>\n )\n}\n\n/** Upload a single file to the Sonor API and return its stored public URL. */\nasync function uploadFormFile(file: File): Promise<string> {\n const apiUrl =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey =\n typeof window !== 'undefined' ? (window as any).__SITE_KIT_API_KEY__ : undefined\n if (!apiKey) {\n throw new Error('API key is required to upload files.')\n }\n\n const body = new FormData()\n body.append('file', file)\n\n // No Content-Type header — the browser sets the multipart boundary itself.\n const response = await sonorFetch(\n `${apiUrl}/api/public/forms/upload`,\n {\n method: 'POST',\n headers: { Authorization: `Bearer ${apiKey}` },\n body,\n },\n { retries: 1, timeoutMs: 60000 },\n )\n\n if (!response.ok) {\n throw new Error(`Upload failed (${response.status})`)\n }\n const data = (await response.json().catch(() => null)) as { url?: string } | null\n if (!data?.url) {\n throw new Error('Upload did not return a URL.')\n }\n return data.url\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
- import { sonorFetch } from './chunk-4UHO6DPJ.mjs';
3
- import './chunk-FDWDXMJL.mjs';
4
- import './chunk-JPTJGLKS.mjs';
2
+ import { sonorFetch } from './chunk-ADOGOLYO.mjs';
3
+ import './chunk-SXNKLHOX.mjs';
4
+ import './chunk-4SQ6PROR.mjs';
5
5
  import './chunk-BEXTDHO4.mjs';
6
6
  import React from 'react';
7
7
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
@@ -81,5 +81,5 @@ async function uploadFormFile(file) {
81
81
  }
82
82
 
83
83
  export { FileField };
84
- //# sourceMappingURL=FileField-FFRHS3XP.mjs.map
85
- //# sourceMappingURL=FileField-FFRHS3XP.mjs.map
84
+ //# sourceMappingURL=FileField-YJ7DZXC3.mjs.map
85
+ //# sourceMappingURL=FileField-YJ7DZXC3.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/forms/FileField.tsx"],"names":[],"mappings":"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","file":"FileField-FFRHS3XP.mjs","sourcesContent":["'use client'\n\n/**\n * File upload field — the one field type that cannot render on the server.\n *\n * It holds upload state and reads the browser-published credential globals, so\n * it lives here rather than in FormField.tsx. Pulling it out is what lets\n * FormField drop its `'use client'` directive and render inside a Server\n * Component (see StaticForm.tsx); a form WITHOUT a file field now ships no\n * field-rendering JavaScript at all.\n *\n * Uploads the chosen file to the Sonor API, which stores it and returns a\n * public URL — that URL becomes the field value, so large files never touch\n * the JSON submission body. The value stays empty until the upload succeeds,\n * so a required file field correctly blocks submission until the upload\n * completes (rather than submitting a useless bare filename).\n *\n * Note: forms containing a file field are NOT native-POST eligible (see\n * native-fallback.tsx) — a form-encoded POST cannot run this upload — so the\n * server shell renders a plain disabled-looking file input and the real\n * control arrives with the enhancement.\n */\n\nimport React from 'react'\nimport type { FormField as FormFieldType } from './types'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface FileFieldProps {\n field: FormFieldType\n inputId: string\n classPrefix: string\n baseInputStyle: React.CSSProperties\n onChange: (value: unknown) => void\n}\n\nexport function FileField({\n field,\n inputId,\n classPrefix,\n baseInputStyle,\n onChange,\n}: FileFieldProps) {\n const [status, setStatus] = React.useState<'idle' | 'uploading' | 'error'>('idle')\n const [fileName, setFileName] = React.useState('')\n\n const handleFile = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file) return\n setFileName(file.name)\n setStatus('uploading')\n onChange('') // clear any prior URL until this upload completes\n try {\n const url = await uploadFormFile(file)\n onChange(url)\n setStatus('idle')\n } catch (err) {\n console.error('[Forms] File upload failed:', err)\n onChange('')\n setStatus('error')\n }\n }\n\n return (\n <>\n <input\n id={inputId}\n className={`${classPrefix}__input ${classPrefix}__input--file`}\n type=\"file\"\n name={field.slug}\n required={field.is_required}\n disabled={status === 'uploading'}\n onChange={handleFile}\n style={baseInputStyle}\n />\n {status === 'uploading' && (\n <p style={{ color: 'var(--sk-text-tertiary, #6b7280)', fontSize: 14, marginTop: 4 }}>\n Uploading {fileName}…\n </p>\n )}\n {status === 'error' && (\n <p role=\"alert\" style={{ color: 'var(--sk-error, #dc2626)', fontSize: 14, marginTop: 4 }}>\n Upload failed. Please choose the file again.\n </p>\n )}\n </>\n )\n}\n\n/** Upload a single file to the Sonor API and return its stored public URL. */\nasync function uploadFormFile(file: File): Promise<string> {\n const apiUrl =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey =\n typeof window !== 'undefined' ? (window as any).__SITE_KIT_API_KEY__ : undefined\n if (!apiKey) {\n throw new Error('API key is required to upload files.')\n }\n\n const body = new FormData()\n body.append('file', file)\n\n // No Content-Type header — the browser sets the multipart boundary itself.\n const response = await sonorFetch(\n `${apiUrl}/api/public/forms/upload`,\n {\n method: 'POST',\n headers: { Authorization: `Bearer ${apiKey}` },\n body,\n },\n { retries: 1, timeoutMs: 60000 },\n )\n\n if (!response.ok) {\n throw new Error(`Upload failed (${response.status})`)\n }\n const data = (await response.json().catch(() => null)) as { url?: string } | null\n if (!data?.url) {\n throw new Error('Upload did not return a URL.')\n }\n return data.url\n}\n"]}
1
+ {"version":3,"sources":["../src/forms/FileField.tsx"],"names":[],"mappings":"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","file":"FileField-YJ7DZXC3.mjs","sourcesContent":["'use client'\n\n/**\n * File upload field — the one field type that cannot render on the server.\n *\n * It holds upload state and reads the browser-published credential globals, so\n * it lives here rather than in FormField.tsx. Pulling it out is what lets\n * FormField drop its `'use client'` directive and render inside a Server\n * Component (see StaticForm.tsx); a form WITHOUT a file field now ships no\n * field-rendering JavaScript at all.\n *\n * Uploads the chosen file to the Sonor API, which stores it and returns a\n * public URL — that URL becomes the field value, so large files never touch\n * the JSON submission body. The value stays empty until the upload succeeds,\n * so a required file field correctly blocks submission until the upload\n * completes (rather than submitting a useless bare filename).\n *\n * Note: forms containing a file field are NOT native-POST eligible (see\n * native-fallback.tsx) — a form-encoded POST cannot run this upload — so the\n * server shell renders a plain disabled-looking file input and the real\n * control arrives with the enhancement.\n */\n\nimport React from 'react'\nimport type { FormField as FormFieldType } from './types'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface FileFieldProps {\n field: FormFieldType\n inputId: string\n classPrefix: string\n baseInputStyle: React.CSSProperties\n onChange: (value: unknown) => void\n}\n\nexport function FileField({\n field,\n inputId,\n classPrefix,\n baseInputStyle,\n onChange,\n}: FileFieldProps) {\n const [status, setStatus] = React.useState<'idle' | 'uploading' | 'error'>('idle')\n const [fileName, setFileName] = React.useState('')\n\n const handleFile = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file) return\n setFileName(file.name)\n setStatus('uploading')\n onChange('') // clear any prior URL until this upload completes\n try {\n const url = await uploadFormFile(file)\n onChange(url)\n setStatus('idle')\n } catch (err) {\n console.error('[Forms] File upload failed:', err)\n onChange('')\n setStatus('error')\n }\n }\n\n return (\n <>\n <input\n id={inputId}\n className={`${classPrefix}__input ${classPrefix}__input--file`}\n type=\"file\"\n name={field.slug}\n required={field.is_required}\n disabled={status === 'uploading'}\n onChange={handleFile}\n style={baseInputStyle}\n />\n {status === 'uploading' && (\n <p style={{ color: 'var(--sk-text-tertiary, #6b7280)', fontSize: 14, marginTop: 4 }}>\n Uploading {fileName}…\n </p>\n )}\n {status === 'error' && (\n <p role=\"alert\" style={{ color: 'var(--sk-error, #dc2626)', fontSize: 14, marginTop: 4 }}>\n Upload failed. Please choose the file again.\n </p>\n )}\n </>\n )\n}\n\n/** Upload a single file to the Sonor API and return its stored public URL. */\nasync function uploadFormFile(file: File): Promise<string> {\n const apiUrl =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey =\n typeof window !== 'undefined' ? (window as any).__SITE_KIT_API_KEY__ : undefined\n if (!apiKey) {\n throw new Error('API key is required to upload files.')\n }\n\n const body = new FormData()\n body.append('file', file)\n\n // No Content-Type header — the browser sets the multipart boundary itself.\n const response = await sonorFetch(\n `${apiUrl}/api/public/forms/upload`,\n {\n method: 'POST',\n headers: { Authorization: `Bearer ${apiKey}` },\n body,\n },\n { retries: 1, timeoutMs: 60000 },\n )\n\n if (!response.ok) {\n throw new Error(`Upload failed (${response.status})`)\n }\n const data = (await response.json().catch(() => null)) as { url?: string } | null\n if (!data?.url) {\n throw new Error('Upload did not return a URL.')\n }\n return data.url\n}\n"]}
@@ -2,7 +2,7 @@
2
2
  'use strict';
3
3
 
4
4
  var chunkMVHR77V4_js = require('./chunk-MVHR77V4.js');
5
- var chunkJY3KZDEM_js = require('./chunk-JY3KZDEM.js');
5
+ var chunkACLBRIYD_js = require('./chunk-ACLBRIYD.js');
6
6
  var chunk2ACKOMAL_js = require('./chunk-2ACKOMAL.js');
7
7
  require('./chunk-SNAQBZPT.js');
8
8
  var react = require('react');
@@ -46,14 +46,14 @@ function renderCompletionTemplate(template, field, values) {
46
46
  if (token === "label") return field.label;
47
47
  if (token === "first_name") {
48
48
  const key = Object.keys(values).find((k) => /^first[_-]?name$/i.test(k));
49
- return (key ? chunkJY3KZDEM_js.stageFirstName(values[key]) : null) || "";
49
+ return (key ? chunkACLBRIYD_js.stageFirstName(values[key]) : null) || "";
50
50
  }
51
51
  return stringify(values[token]);
52
52
  }).replace(/\s{2,}/g, " ").trim();
53
53
  }
54
54
  function groupSentence(fields, values) {
55
55
  const val = (f) => values[f.slug];
56
- const answered = fields.filter((f) => !chunkJY3KZDEM_js.isEmptyValue(val(f)));
56
+ const answered = fields.filter((f) => !chunkACLBRIYD_js.isEmptyValue(val(f)));
57
57
  if (answered.length === 0) return null;
58
58
  for (const f of answered) {
59
59
  const template = f.completion_message?.trim();
@@ -68,14 +68,14 @@ function groupSentence(fields, values) {
68
68
  );
69
69
  if (firstNameField || anyNameField) {
70
70
  const source = firstNameField ?? anyNameField;
71
- const name = chunkJY3KZDEM_js.stageFirstName(val(source));
71
+ const name = chunkACLBRIYD_js.stageFirstName(val(source));
72
72
  if (name) return `Nice to meet you, ${name}.`;
73
73
  }
74
74
  const email = fields.find(
75
- (f) => f.field_type === "email" && !chunkJY3KZDEM_js.isEmptyValue(val(f))
75
+ (f) => f.field_type === "email" && !chunkACLBRIYD_js.isEmptyValue(val(f))
76
76
  );
77
77
  const phone = fields.find(
78
- (f) => (f.field_type === "phone" || f.field_type === "tel") && !chunkJY3KZDEM_js.isEmptyValue(val(f))
78
+ (f) => (f.field_type === "phone" || f.field_type === "tel") && !chunkACLBRIYD_js.isEmptyValue(val(f))
79
79
  );
80
80
  if (email && phone) return `We'll follow up at ${val(email)} or ${val(phone)}.`;
81
81
  if (email) return `We'll follow up at ${val(email)}.`;
@@ -253,9 +253,9 @@ function FormSpotlight({
253
253
  trackStepChange,
254
254
  honeypot
255
255
  }) {
256
- const fieldControls = chunkJY3KZDEM_js.useFieldControls(config.fields);
256
+ const fieldControls = chunkACLBRIYD_js.useFieldControls(config.fields);
257
257
  const views = react.useMemo(() => {
258
- return chunkJY3KZDEM_js.stageViews(config).map((v) => ({ ...v, fields: v.fields.filter(isFieldVisible) })).filter((v) => v.fields.length > 0);
258
+ return chunkACLBRIYD_js.stageViews(config).map((v) => ({ ...v, fields: v.fields.filter(isFieldVisible) })).filter((v) => v.fields.length > 0);
259
259
  }, [config, isFieldVisible]);
260
260
  const questions = react.useMemo(() => views.flatMap((v) => v.fields), [views]);
261
261
  const questionCount = questions.length;
@@ -277,8 +277,8 @@ function FormSpotlight({
277
277
  const activeGroup = activeSlug ? groupOf(activeSlug) : -1;
278
278
  const groupComplete = react.useCallback(
279
279
  (view) => view.fields.every(
280
- (f) => fieldIsComplete(f) || !f.is_required && chunkJY3KZDEM_js.isEmptyValue(values[f.slug])
281
- ) && view.fields.some((f) => !chunkJY3KZDEM_js.isEmptyValue(values[f.slug])),
280
+ (f) => fieldIsComplete(f) || !f.is_required && chunkACLBRIYD_js.isEmptyValue(values[f.slug])
281
+ ) && view.fields.some((f) => !chunkACLBRIYD_js.isEmptyValue(values[f.slug])),
282
282
  [fieldIsComplete, values]
283
283
  );
284
284
  const completeCount = questions.reduce((n, q) => n + (fieldIsComplete(q) ? 1 : 0), 0);
@@ -476,7 +476,7 @@ function FormSpotlight({
476
476
  (field, soloAutoAdvance) => (value) => {
477
477
  setLive(true);
478
478
  setFieldValue(field.slug, value);
479
- if (soloAutoAdvance && !chunkJY3KZDEM_js.isEmptyValue(value)) {
479
+ if (soloAutoAdvance && !chunkACLBRIYD_js.isEmptyValue(value)) {
480
480
  clearAutoTimer();
481
481
  autoTimer.current = window.setTimeout(() => {
482
482
  autoTimer.current = null;
@@ -591,7 +591,7 @@ function FormSpotlight({
591
591
  ),
592
592
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "sk-stage__head", "data-sk-part": "stage-head", children: [
593
593
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sk-stage__head-name", children: config.name }),
594
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sk-stage__head-meta", "data-sk-part": "stage-estimate", children: `Takes ${chunkJY3KZDEM_js.stageEstimate(questionCount)}` })
594
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sk-stage__head-meta", "data-sk-part": "stage-estimate", children: `Takes ${chunkACLBRIYD_js.stageEstimate(questionCount)}` })
595
595
  ] }),
596
596
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sk-stage__hud", "data-sk-part": "stage-hud", children: [
597
597
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -687,7 +687,7 @@ function FormSpotlight({
687
687
  showValid: !!touched[f.slug] && !errors[f.slug] && fieldIsComplete(f),
688
688
  onChange: handleFieldChange(
689
689
  f,
690
- view.fields.length === 1 && chunkJY3KZDEM_js.AUTO_ADVANCE_TYPES.includes(f.field_type)
690
+ view.fields.length === 1 && chunkACLBRIYD_js.AUTO_ADVANCE_TYPES.includes(f.field_type)
691
691
  )
692
692
  }
693
693
  )
@@ -753,5 +753,5 @@ exports.FormSpotlight = FormSpotlight;
753
753
  exports.SpotStyles = SpotStyles;
754
754
  exports.groupSentence = groupSentence;
755
755
  exports.renderCompletionTemplate = renderCompletionTemplate;
756
- //# sourceMappingURL=FormSpotlight-JG4ZHS56.js.map
757
- //# sourceMappingURL=FormSpotlight-JG4ZHS56.js.map
756
+ //# sourceMappingURL=FormSpotlight-7WAXLXZA.js.map
757
+ //# sourceMappingURL=FormSpotlight-7WAXLXZA.js.map