@sonordev/site-kit 3.2.0 → 3.2.1

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 (140) hide show
  1. package/agent-manifest.json +1 -1
  2. package/dist/AnalyticsProvider-A3STXJ65.js +29 -0
  3. package/dist/{AnalyticsProvider-WK2Z6AIN.js.map → AnalyticsProvider-A3STXJ65.js.map} +1 -1
  4. package/dist/AnalyticsProvider-LEXGFM2K.mjs +8 -0
  5. package/dist/{AnalyticsProvider-CD635CHQ.mjs.map → AnalyticsProvider-LEXGFM2K.mjs.map} +1 -1
  6. package/dist/ChatWidget-4QR2ZDRE.mjs +8 -0
  7. package/dist/{ChatWidget-UAAWDBNS.mjs.map → ChatWidget-4QR2ZDRE.mjs.map} +1 -1
  8. package/dist/ChatWidget-U3K2VHVN.js +17 -0
  9. package/dist/{ChatWidget-AIOOZY6H.js.map → ChatWidget-U3K2VHVN.js.map} +1 -1
  10. package/dist/EngageWidget-2FMKYJJT.mjs +7 -0
  11. package/dist/{EngageWidget-EZ5T6H3K.mjs.map → EngageWidget-2FMKYJJT.mjs.map} +1 -1
  12. package/dist/EngageWidget-TOGMQ2G6.js +16 -0
  13. package/dist/{EngageWidget-RWVWW56C.js.map → EngageWidget-TOGMQ2G6.js.map} +1 -1
  14. package/dist/{SignalCore-4B4RNYLV.mjs → SignalCore-5QJG3IJB.mjs} +4 -4
  15. package/dist/{SignalCore-4B4RNYLV.mjs.map → SignalCore-5QJG3IJB.mjs.map} +1 -1
  16. package/dist/{SignalCore-AECW2JFP.js → SignalCore-JB3VHHTG.js} +8 -8
  17. package/dist/{SignalCore-AECW2JFP.js.map → SignalCore-JB3VHHTG.js.map} +1 -1
  18. package/dist/SitemapSync-BJWSTERT.js +15 -0
  19. package/dist/{SitemapSync-AICU4SSV.js.map → SitemapSync-BJWSTERT.js.map} +1 -1
  20. package/dist/SitemapSync-T6PIDW64.mjs +6 -0
  21. package/dist/{SitemapSync-CIZCAZXK.mjs.map → SitemapSync-T6PIDW64.mjs.map} +1 -1
  22. package/dist/analytics/index.js +11 -11
  23. package/dist/analytics/index.mjs +4 -4
  24. package/dist/brand.css +13 -3
  25. package/dist/{chunk-GCDVKOSM.js → chunk-52VXHSVT.js} +3 -3
  26. package/dist/{chunk-GCDVKOSM.js.map → chunk-52VXHSVT.js.map} +1 -1
  27. package/dist/{chunk-I2GTT2DG.js → chunk-5RX4CUR2.js} +19 -21
  28. package/dist/chunk-5RX4CUR2.js.map +1 -0
  29. package/dist/{chunk-OTY7EWET.mjs → chunk-5ZNKNNJ4.mjs} +4 -4
  30. package/dist/{chunk-OTY7EWET.mjs.map → chunk-5ZNKNNJ4.mjs.map} +1 -1
  31. package/dist/{chunk-RFIWVH3D.mjs → chunk-7OK6BI3A.mjs} +3 -3
  32. package/dist/{chunk-RFIWVH3D.mjs.map → chunk-7OK6BI3A.mjs.map} +1 -1
  33. package/dist/{chunk-N2HR2E4Z.mjs → chunk-7R7SGJG3.mjs} +15 -21
  34. package/dist/chunk-7R7SGJG3.mjs.map +1 -0
  35. package/dist/{chunk-FMZOZQBV.mjs → chunk-AMBTOIYM.mjs} +19 -21
  36. package/dist/chunk-AMBTOIYM.mjs.map +1 -0
  37. package/dist/{chunk-5OWZUNNE.js → chunk-B5YNHSRA.js} +7 -7
  38. package/dist/{chunk-5OWZUNNE.js.map → chunk-B5YNHSRA.js.map} +1 -1
  39. package/dist/{chunk-S3YQGTBF.js → chunk-BNBCSHTK.js} +12 -12
  40. package/dist/{chunk-S3YQGTBF.js.map → chunk-BNBCSHTK.js.map} +1 -1
  41. package/dist/{chunk-45QHDA7Q.mjs → chunk-BUCF5FUY.mjs} +3 -3
  42. package/dist/{chunk-45QHDA7Q.mjs.map → chunk-BUCF5FUY.mjs.map} +1 -1
  43. package/dist/{chunk-TE3W5REY.js → chunk-DCZUMCEC.js} +14 -14
  44. package/dist/{chunk-TE3W5REY.js.map → chunk-DCZUMCEC.js.map} +1 -1
  45. package/dist/{chunk-6HPNFWSC.mjs → chunk-DYCEEU67.mjs} +3 -3
  46. package/dist/{chunk-6HPNFWSC.mjs.map → chunk-DYCEEU67.mjs.map} +1 -1
  47. package/dist/{chunk-NDHFU4HV.mjs → chunk-E4TWVVSW.mjs} +4 -4
  48. package/dist/{chunk-NDHFU4HV.mjs.map → chunk-E4TWVVSW.mjs.map} +1 -1
  49. package/dist/{chunk-NAVDN4AE.js → chunk-E7M5MDGC.js} +29 -40
  50. package/dist/chunk-E7M5MDGC.js.map +1 -0
  51. package/dist/{chunk-2WYEJOGA.mjs → chunk-GMO6POZ2.mjs} +3 -3
  52. package/dist/{chunk-2WYEJOGA.mjs.map → chunk-GMO6POZ2.mjs.map} +1 -1
  53. package/dist/{chunk-EAASMIWX.js → chunk-GMSPDTEV.js} +15 -9
  54. package/dist/chunk-GMSPDTEV.js.map +1 -0
  55. package/dist/{chunk-T2DEEKVQ.mjs → chunk-IR5UC236.mjs} +3 -3
  56. package/dist/{chunk-T2DEEKVQ.mjs.map → chunk-IR5UC236.mjs.map} +1 -1
  57. package/dist/{chunk-HAZN43I6.js → chunk-LF3ID6WN.js} +20 -26
  58. package/dist/chunk-LF3ID6WN.js.map +1 -0
  59. package/dist/{chunk-57QV6NIY.mjs → chunk-MKZHVSKL.mjs} +3 -3
  60. package/dist/{chunk-57QV6NIY.mjs.map → chunk-MKZHVSKL.mjs.map} +1 -1
  61. package/dist/{chunk-SLWTG2LJ.js → chunk-MX6DK246.js} +13 -13
  62. package/dist/{chunk-SLWTG2LJ.js.map → chunk-MX6DK246.js.map} +1 -1
  63. package/dist/{chunk-R5A64DCX.js → chunk-MYAXI33P.js} +8 -8
  64. package/dist/{chunk-R5A64DCX.js.map → chunk-MYAXI33P.js.map} +1 -1
  65. package/dist/{chunk-4NTMIU6V.js → chunk-NDROQRDB.js} +6 -6
  66. package/dist/{chunk-4NTMIU6V.js.map → chunk-NDROQRDB.js.map} +1 -1
  67. package/dist/{chunk-4FBV5BJW.js → chunk-NJIHMZPC.js} +5 -5
  68. package/dist/{chunk-4FBV5BJW.js.map → chunk-NJIHMZPC.js.map} +1 -1
  69. package/dist/{chunk-DSRPKUQI.mjs → chunk-NQ2P7AB3.mjs} +28 -39
  70. package/dist/chunk-NQ2P7AB3.mjs.map +1 -0
  71. package/dist/chunk-QLM7RNQI.mjs +6 -0
  72. package/dist/{chunk-SN2O72UF.mjs.map → chunk-QLM7RNQI.mjs.map} +1 -1
  73. package/dist/{chunk-LZSCCJ4O.mjs → chunk-SBT4J733.mjs} +11 -5
  74. package/dist/chunk-SBT4J733.mjs.map +1 -0
  75. package/dist/{chunk-UT2CF4FC.js → chunk-SGPIGHMN.js} +4 -4
  76. package/dist/{chunk-UT2CF4FC.js.map → chunk-SGPIGHMN.js.map} +1 -1
  77. package/dist/{chunk-GN62H6EG.mjs → chunk-VTHCUHMK.mjs} +8 -8
  78. package/dist/{chunk-GN62H6EG.mjs.map → chunk-VTHCUHMK.mjs.map} +1 -1
  79. package/dist/chunk-WAAFJPNR.js +8 -0
  80. package/dist/{chunk-WRZQS7O4.js.map → chunk-WAAFJPNR.js.map} +1 -1
  81. package/dist/{chunk-EIWRPGOK.mjs → chunk-XHEXIYKY.mjs} +4 -4
  82. package/dist/{chunk-EIWRPGOK.mjs.map → chunk-XHEXIYKY.mjs.map} +1 -1
  83. package/dist/{chunk-TVCCZ7NR.js → chunk-XM67L4HL.js} +14 -14
  84. package/dist/{chunk-TVCCZ7NR.js.map → chunk-XM67L4HL.js.map} +1 -1
  85. package/dist/cli/index.js +2 -2
  86. package/dist/cli/index.mjs +1 -1
  87. package/dist/commerce/index.js +50 -50
  88. package/dist/commerce/index.mjs +5 -5
  89. package/dist/engage/index.js +8 -8
  90. package/dist/engage/index.mjs +5 -5
  91. package/dist/fleet/index.js +7 -7
  92. package/dist/fleet/index.mjs +3 -3
  93. package/dist/forms/index.js +18 -18
  94. package/dist/forms/index.js.map +1 -1
  95. package/dist/forms/index.mjs +10 -10
  96. package/dist/forms/index.mjs.map +1 -1
  97. package/dist/forms/styles.css +4 -2
  98. package/dist/images/index.js +10 -10
  99. package/dist/images/index.mjs +3 -3
  100. package/dist/index.js +67 -68
  101. package/dist/index.js.map +1 -1
  102. package/dist/index.mjs +14 -15
  103. package/dist/index.mjs.map +1 -1
  104. package/dist/layout/client.js +6 -6
  105. package/dist/layout/client.mjs +5 -5
  106. package/dist/layout/index.js +7 -7
  107. package/dist/layout/index.mjs +5 -5
  108. package/dist/maps/index.d.mts +4 -2
  109. package/dist/maps/index.d.ts +4 -2
  110. package/dist/maps/index.js +4 -4
  111. package/dist/maps/index.js.map +1 -1
  112. package/dist/maps/index.mjs +2 -2
  113. package/dist/maps/index.mjs.map +1 -1
  114. package/dist/seo/client.js +4 -4
  115. package/dist/seo/client.mjs +3 -3
  116. package/dist/seo/index.js +4 -4
  117. package/dist/seo/index.mjs +3 -3
  118. package/dist/signal/index.js +11 -11
  119. package/dist/signal/index.mjs +2 -2
  120. package/dist/sync/index.js +15 -13
  121. package/dist/sync/index.mjs +3 -1
  122. package/package.json +1 -1
  123. package/dist/AnalyticsProvider-CD635CHQ.mjs +0 -8
  124. package/dist/AnalyticsProvider-WK2Z6AIN.js +0 -29
  125. package/dist/ChatWidget-AIOOZY6H.js +0 -17
  126. package/dist/ChatWidget-UAAWDBNS.mjs +0 -8
  127. package/dist/EngageWidget-EZ5T6H3K.mjs +0 -7
  128. package/dist/EngageWidget-RWVWW56C.js +0 -16
  129. package/dist/SitemapSync-AICU4SSV.js +0 -15
  130. package/dist/SitemapSync-CIZCAZXK.mjs +0 -6
  131. package/dist/chunk-DSRPKUQI.mjs.map +0 -1
  132. package/dist/chunk-EAASMIWX.js.map +0 -1
  133. package/dist/chunk-FMZOZQBV.mjs.map +0 -1
  134. package/dist/chunk-HAZN43I6.js.map +0 -1
  135. package/dist/chunk-I2GTT2DG.js.map +0 -1
  136. package/dist/chunk-LZSCCJ4O.mjs.map +0 -1
  137. package/dist/chunk-N2HR2E4Z.mjs.map +0 -1
  138. package/dist/chunk-NAVDN4AE.js.map +0 -1
  139. package/dist/chunk-SN2O72UF.mjs +0 -6
  140. package/dist/chunk-WRZQS7O4.js +0 -8
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { useSignalExperiment, useSignalEvent } from './chunk-57QV6NIY.mjs';
2
+ import { useSignalExperiment, useSignalEvent } from './chunk-MKZHVSKL.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-6HPNFWSC.mjs.map
75
- //# sourceMappingURL=chunk-6HPNFWSC.mjs.map
74
+ //# sourceMappingURL=chunk-DYCEEU67.mjs.map
75
+ //# sourceMappingURL=chunk-DYCEEU67.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-6HPNFWSC.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-DYCEEU67.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,8 +1,8 @@
1
1
  'use client';
2
2
  import { useDeferredActivation } from './chunk-ZVBLXXNJ.mjs';
3
3
  import { sanitizeFleetVersion, buildFleetHeartbeatPayload } from './chunk-ZPLN537Q.mjs';
4
- import { sonorFetch } from './chunk-LZSCCJ4O.mjs';
5
- import { SITE_KIT_VERSION } from './chunk-SN2O72UF.mjs';
4
+ import { sonorFetch } from './chunk-SBT4J733.mjs';
5
+ import { SITE_KIT_VERSION } from './chunk-QLM7RNQI.mjs';
6
6
  import { useRef, useEffect } from 'react';
7
7
 
8
8
  // src/fleet/heartbeat.ts
@@ -93,5 +93,5 @@ function FleetHeartbeat({
93
93
  }
94
94
 
95
95
  export { FLEET_HEARTBEAT_PATH, FleetHeartbeat, detectNextVersion, sendFleetHeartbeat };
96
- //# sourceMappingURL=chunk-NDHFU4HV.mjs.map
97
- //# sourceMappingURL=chunk-NDHFU4HV.mjs.map
96
+ //# sourceMappingURL=chunk-E4TWVVSW.mjs.map
97
+ //# sourceMappingURL=chunk-E4TWVVSW.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/fleet/heartbeat.ts","../src/fleet/FleetHeartbeat.tsx"],"names":[],"mappings":"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","file":"chunk-NDHFU4HV.mjs","sourcesContent":["/**\n * @sonordev/site-kit/fleet — heartbeat sender (single source of truth for the POST)\n *\n * One place that turns fleet inputs into a validated payload and ships it to\n * `/api/public/fleet/heartbeat`. Used by BOTH the client component\n * (FleetHeartbeat) and any build-time caller, so the send path never forks.\n *\n * It routes through the canonical `sonorFetch` transport, which already stamps\n * the x-sitekit-version header, attaches x-api-key, and honors the auth\n * circuit breaker — a site on a stale/canceled key will not spam the API.\n */\n\nimport { sonorFetch } from '../shared/sonorFetch'\nimport { SITE_KIT_VERSION } from '../shared/version'\nimport {\n buildFleetHeartbeatPayload,\n sanitizeFleetVersion,\n type FleetHeartbeatPayload,\n type FleetHeartbeatSource,\n type FleetModule,\n} from './contract'\n\n/** Canonical ingest path — resolved against the site's Sonor API origin. */\nexport const FLEET_HEARTBEAT_PATH = '/api/public/fleet/heartbeat'\n\nexport interface SendFleetHeartbeatOptions {\n /** Sonor API origin (e.g. https://api.sonor.io). Trailing slash tolerated. */\n apiUrl: string\n /** Project API key — scopes the request; the project is resolved server-side. */\n apiKey: string\n /** Client-observable active modules (validated/deduped by the contract). */\n modules?: FleetModule[] | string[]\n /** Normalized host for the multi-site sub-dimension (server re-normalizes). */\n site?: string | null\n /** Installed Next.js version, if the caller can resolve it. */\n nextVersion?: string | null\n /** 'client' (runtime boot) or 'build' (CI). Default 'client'. */\n source?: FleetHeartbeatSource\n /** Override the reported kit version. Defaults to the runtime SITE_KIT_VERSION. */\n kitVersion?: string\n /** Log one info line with the result. Never logs at error level. */\n debug?: boolean\n}\n\n/**\n * Best-effort runtime detection of the host Next.js version. Unreliable by\n * design — Next does not expose its version consistently across app/pages\n * router — so it returns null unless a site injects `__SITE_KIT_NEXT_VERSION__`\n * or `window.next.version` is present. Build-time callers should pass\n * `nextVersion` explicitly (resolvable from `next/package.json`).\n */\nexport function detectNextVersion(): string | null {\n if (typeof window === 'undefined') return null\n const w = window as unknown as {\n __SITE_KIT_NEXT_VERSION__?: string\n next?: { version?: string }\n }\n return sanitizeFleetVersion(w.__SITE_KIT_NEXT_VERSION__ ?? w.next?.version ?? null)\n}\n\n/**\n * Fire one heartbeat. Fire-and-forget by contract: it never throws — a\n * telemetry POST must never break a visitor's page or a site's build. Returns\n * true only when the POST was accepted (2xx).\n */\nexport async function sendFleetHeartbeat(opts: SendFleetHeartbeatOptions): Promise<boolean> {\n const { apiUrl, apiKey } = opts\n if (!apiUrl || !apiKey) return false\n\n const payload: FleetHeartbeatPayload = buildFleetHeartbeatPayload({\n kitVersion: opts.kitVersion || SITE_KIT_VERSION,\n nextVersion: opts.nextVersion,\n modules: opts.modules,\n site: opts.site,\n source: opts.source,\n })\n\n try {\n const res = await sonorFetch(\n `${apiUrl.replace(/\\/$/, '')}${FLEET_HEARTBEAT_PATH}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n },\n // retries: 0 — the once-per-session guard already bounds volume, and a\n // missed heartbeat is harmless (the next page load or passive\n // x-sitekit-version capture re-registers the site).\n { apiKey, retries: 0 },\n )\n if (opts.debug) {\n // info, never error: a visitor's console must stay clean (Lighthouse).\n console.info(\n `[Sonor fleet] heartbeat ${res.status} v${payload.kit_version} [${payload.modules.join(',') || 'none'}]`,\n )\n }\n return res.ok\n } catch (err) {\n if (opts.debug) console.info('[Sonor fleet] heartbeat skipped (network)', err)\n return false\n }\n}\n","/**\n * @sonordev/site-kit/fleet — FleetHeartbeat\n *\n * A childless, effect-only client component that reports this site's build\n * fingerprint (kit version, Next.js version, active modules, host) to Sonor\n * exactly once per browser session. It exists so the platform can answer\n * \"which version / modules / key state is each site running\" without shelling\n * into every client repo.\n *\n * It is mounted as a deferred, CHILDLESS SIBLING — never a wrapper — by\n * SiteKitClientProviders, behind the same idle/first-interaction gate as\n * Analytics and Engage, so it never enters the critical hydration path (see\n * CLAUDE.md \"the page must server-render\"). It renders null and carries no\n * visitor data.\n */\n\n'use client'\n\nimport { useEffect, useRef } from 'react'\nimport { useDeferredActivation } from '../shared/defer'\nimport { SITE_KIT_VERSION } from '../shared/version'\nimport { detectNextVersion, sendFleetHeartbeat } from './heartbeat'\nimport type { FleetModule } from './contract'\n\n/** Session guard key — one heartbeat per session, re-sent when version/host changes. */\nconst SESSION_GUARD_KEY = '_sk_fleet_hb'\n\nexport interface FleetHeartbeatProps {\n /** Sonor API origin. Falls back to `window.__SITE_KIT_API_URL__` then api.sonor.io. */\n apiUrl?: string\n /** Project API key. Falls back to `window.__SITE_KIT_API_KEY__`. */\n apiKey?: string\n /** Host for the multi-site sub-dimension. Falls back to `__SITE_KIT_SITE__` then location.host. */\n site?: string | null\n /** Client-observable active modules (SiteKitClientProviders passes the enabled set). */\n modules?: FleetModule[]\n /** Installed Next.js version if known; otherwise best-effort runtime detection. */\n nextVersion?: string | null\n /**\n * Self-defer to idle / first interaction. Default true so standalone use is\n * safe. SiteKitClientProviders already gates the mount and passes false.\n */\n defer?: boolean\n /** Send at most once per browser session per (version, host). Default true. */\n oncePerSession?: boolean\n debug?: boolean\n}\n\nexport function FleetHeartbeat({\n apiUrl,\n apiKey,\n site,\n modules,\n nextVersion,\n defer = true,\n oncePerSession = true,\n debug = false,\n}: FleetHeartbeatProps) {\n const ready = useDeferredActivation(defer)\n const sentRef = useRef(false)\n\n useEffect(() => {\n if (!ready || sentRef.current) return\n if (typeof window === 'undefined') return\n\n const w = window as unknown as {\n __SITE_KIT_API_URL__?: string\n __SITE_KIT_API_KEY__?: string\n __SITE_KIT_SITE__?: string\n }\n const url = apiUrl || w.__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n const key = apiKey || w.__SITE_KIT_API_KEY__\n if (!key) return // no key resolvable — nothing to authenticate the heartbeat\n\n const resolvedSite = site ?? w.__SITE_KIT_SITE__ ?? window.location.host ?? ''\n\n // Once-per-session-per-(version,host): keeps heartbeat volume to one POST\n // per visitor session while still re-reporting after an upgrade or on a\n // different sub-site. Storage-disabled browsers simply send once per load.\n if (oncePerSession) {\n const stamp = `${SITE_KIT_VERSION}:${resolvedSite}`\n try {\n if (sessionStorage.getItem(SESSION_GUARD_KEY) === stamp) {\n sentRef.current = true\n return\n }\n sessionStorage.setItem(SESSION_GUARD_KEY, stamp)\n } catch {\n /* storage unavailable — fall through and send this load */\n }\n }\n\n sentRef.current = true\n void sendFleetHeartbeat({\n apiUrl: url,\n apiKey: key,\n site: resolvedSite,\n modules,\n nextVersion: nextVersion ?? detectNextVersion(),\n source: 'client',\n debug,\n })\n }, [ready, apiUrl, apiKey, site, modules, nextVersion, oncePerSession, debug])\n\n return null\n}\n"]}
1
+ {"version":3,"sources":["../src/fleet/heartbeat.ts","../src/fleet/FleetHeartbeat.tsx"],"names":[],"mappings":";;;;;;;AAuBO,IAAM,oBAAA,GAAuB;AA4B7B,SAAS,iBAAA,GAAmC;AACjD,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,IAAA;AAC1C,EAAA,MAAM,CAAA,GAAI,MAAA;AAIV,EAAA,OAAO,qBAAqB,CAAA,CAAE,yBAAA,IAA6B,CAAA,CAAE,IAAA,EAAM,WAAW,IAAI,CAAA;AACpF;AAOA,eAAsB,mBAAmB,IAAA,EAAmD;AAC1F,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAO,GAAI,IAAA;AAC3B,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ,OAAO,KAAA;AAE/B,EAAA,MAAM,UAAiC,0BAAA,CAA2B;AAAA,IAChE,UAAA,EAAY,KAAK,UAAA,IAAc,gBAAA;AAAA,IAC/B,aAAa,IAAA,CAAK,WAAA;AAAA,IAClB,SAAS,IAAA,CAAK,OAAA;AAAA,IACd,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,QAAQ,IAAA,CAAK;AAAA,GACd,CAAA;AAED,EAAA,IAAI;AACF,IAAA,MAAM,MAAM,MAAM,UAAA;AAAA,MAChB,GAAG,MAAA,CAAO,OAAA,CAAQ,OAAO,EAAE,CAAC,GAAG,oBAAoB,CAAA,CAAA;AAAA,MACnD;AAAA,QACE,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,QAC9C,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,OAAO;AAAA,OAC9B;AAAA;AAAA;AAAA;AAAA,MAIA,EAAE,MAAA,EAAQ,OAAA,EAAS,CAAA;AAAE,KACvB;AACA,IAAA,IAAI,KAAK,KAAA,EAAO;AAEd,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,CAAA,wBAAA,EAA2B,GAAA,CAAI,MAAM,CAAA,EAAA,EAAK,OAAA,CAAQ,WAAW,CAAA,EAAA,EAAK,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA,IAAK,MAAM,CAAA,CAAA;AAAA,OACvG;AAAA,IACF;AACA,IAAA,OAAO,GAAA,CAAI,EAAA;AAAA,EACb,SAAS,GAAA,EAAK;AACZ,IAAA,IAAI,IAAA,CAAK,KAAA,EAAO,OAAA,CAAQ,IAAA,CAAK,6CAA6C,GAAG,CAAA;AAC7E,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AC5EA,IAAM,iBAAA,GAAoB,cAAA;AAuBnB,SAAS,cAAA,CAAe;AAAA,EAC7B,MAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA,GAAQ,IAAA;AAAA,EACR,cAAA,GAAiB,IAAA;AAAA,EACjB,KAAA,GAAQ;AACV,CAAA,EAAwB;AACtB,EAAA,MAAM,KAAA,GAAQ,sBAAsB,KAAK,CAAA;AACzC,EAAA,MAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAE5B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,KAAA,IAAS,OAAA,CAAQ,OAAA,EAAS;AAC/B,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAEnC,IAAA,MAAM,CAAA,GAAI,MAAA;AAKV,IAAA,MAAM,GAAA,GAAM,MAAA,IAAU,CAAA,CAAE,oBAAA,IAAwB,sBAAA;AAChD,IAAA,MAAM,GAAA,GAAM,UAAU,CAAA,CAAE,oBAAA;AACxB,IAAA,IAAI,CAAC,GAAA,EAAK;AAEV,IAAA,MAAM,eAAe,IAAA,IAAQ,CAAA,CAAE,iBAAA,IAAqB,MAAA,CAAO,SAAS,IAAA,IAAQ,EAAA;AAK5E,IAAA,IAAI,cAAA,EAAgB;AAClB,MAAA,MAAM,KAAA,GAAQ,CAAA,EAAG,gBAAgB,CAAA,CAAA,EAAI,YAAY,CAAA,CAAA;AACjD,MAAA,IAAI;AACF,QAAA,IAAI,cAAA,CAAe,OAAA,CAAQ,iBAAiB,CAAA,KAAM,KAAA,EAAO;AACvD,UAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,UAAA;AAAA,QACF;AACA,QAAA,cAAA,CAAe,OAAA,CAAQ,mBAAmB,KAAK,CAAA;AAAA,MACjD,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,IAAA,KAAK,kBAAA,CAAmB;AAAA,MACtB,MAAA,EAAQ,GAAA;AAAA,MACR,MAAA,EAAQ,GAAA;AAAA,MACR,IAAA,EAAM,YAAA;AAAA,MACN,OAAA;AAAA,MACA,WAAA,EAAa,eAAe,iBAAA,EAAkB;AAAA,MAC9C,MAAA,EAAQ,QAAA;AAAA,MACR;AAAA,KACD,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,KAAA,EAAO,MAAA,EAAQ,MAAA,EAAQ,MAAM,OAAA,EAAS,WAAA,EAAa,cAAA,EAAgB,KAAK,CAAC,CAAA;AAE7E,EAAA,OAAO,IAAA;AACT","file":"chunk-E4TWVVSW.mjs","sourcesContent":["/**\n * @sonordev/site-kit/fleet — heartbeat sender (single source of truth for the POST)\n *\n * One place that turns fleet inputs into a validated payload and ships it to\n * `/api/public/fleet/heartbeat`. Used by BOTH the client component\n * (FleetHeartbeat) and any build-time caller, so the send path never forks.\n *\n * It routes through the canonical `sonorFetch` transport, which already stamps\n * the x-sitekit-version header, attaches x-api-key, and honors the auth\n * circuit breaker — a site on a stale/canceled key will not spam the API.\n */\n\nimport { sonorFetch } from '../shared/sonorFetch'\nimport { SITE_KIT_VERSION } from '../shared/version'\nimport {\n buildFleetHeartbeatPayload,\n sanitizeFleetVersion,\n type FleetHeartbeatPayload,\n type FleetHeartbeatSource,\n type FleetModule,\n} from './contract'\n\n/** Canonical ingest path — resolved against the site's Sonor API origin. */\nexport const FLEET_HEARTBEAT_PATH = '/api/public/fleet/heartbeat'\n\nexport interface SendFleetHeartbeatOptions {\n /** Sonor API origin (e.g. https://api.sonor.io). Trailing slash tolerated. */\n apiUrl: string\n /** Project API key — scopes the request; the project is resolved server-side. */\n apiKey: string\n /** Client-observable active modules (validated/deduped by the contract). */\n modules?: FleetModule[] | string[]\n /** Normalized host for the multi-site sub-dimension (server re-normalizes). */\n site?: string | null\n /** Installed Next.js version, if the caller can resolve it. */\n nextVersion?: string | null\n /** 'client' (runtime boot) or 'build' (CI). Default 'client'. */\n source?: FleetHeartbeatSource\n /** Override the reported kit version. Defaults to the runtime SITE_KIT_VERSION. */\n kitVersion?: string\n /** Log one info line with the result. Never logs at error level. */\n debug?: boolean\n}\n\n/**\n * Best-effort runtime detection of the host Next.js version. Unreliable by\n * design — Next does not expose its version consistently across app/pages\n * router — so it returns null unless a site injects `__SITE_KIT_NEXT_VERSION__`\n * or `window.next.version` is present. Build-time callers should pass\n * `nextVersion` explicitly (resolvable from `next/package.json`).\n */\nexport function detectNextVersion(): string | null {\n if (typeof window === 'undefined') return null\n const w = window as unknown as {\n __SITE_KIT_NEXT_VERSION__?: string\n next?: { version?: string }\n }\n return sanitizeFleetVersion(w.__SITE_KIT_NEXT_VERSION__ ?? w.next?.version ?? null)\n}\n\n/**\n * Fire one heartbeat. Fire-and-forget by contract: it never throws — a\n * telemetry POST must never break a visitor's page or a site's build. Returns\n * true only when the POST was accepted (2xx).\n */\nexport async function sendFleetHeartbeat(opts: SendFleetHeartbeatOptions): Promise<boolean> {\n const { apiUrl, apiKey } = opts\n if (!apiUrl || !apiKey) return false\n\n const payload: FleetHeartbeatPayload = buildFleetHeartbeatPayload({\n kitVersion: opts.kitVersion || SITE_KIT_VERSION,\n nextVersion: opts.nextVersion,\n modules: opts.modules,\n site: opts.site,\n source: opts.source,\n })\n\n try {\n const res = await sonorFetch(\n `${apiUrl.replace(/\\/$/, '')}${FLEET_HEARTBEAT_PATH}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n },\n // retries: 0 — the once-per-session guard already bounds volume, and a\n // missed heartbeat is harmless (the next page load or passive\n // x-sitekit-version capture re-registers the site).\n { apiKey, retries: 0 },\n )\n if (opts.debug) {\n // info, never error: a visitor's console must stay clean (Lighthouse).\n console.info(\n `[Sonor fleet] heartbeat ${res.status} v${payload.kit_version} [${payload.modules.join(',') || 'none'}]`,\n )\n }\n return res.ok\n } catch (err) {\n if (opts.debug) console.info('[Sonor fleet] heartbeat skipped (network)', err)\n return false\n }\n}\n","/**\n * @sonordev/site-kit/fleet — FleetHeartbeat\n *\n * A childless, effect-only client component that reports this site's build\n * fingerprint (kit version, Next.js version, active modules, host) to Sonor\n * exactly once per browser session. It exists so the platform can answer\n * \"which version / modules / key state is each site running\" without shelling\n * into every client repo.\n *\n * It is mounted as a deferred, CHILDLESS SIBLING — never a wrapper — by\n * SiteKitClientProviders, behind the same idle/first-interaction gate as\n * Analytics and Engage, so it never enters the critical hydration path (see\n * CLAUDE.md \"the page must server-render\"). It renders null and carries no\n * visitor data.\n */\n\n'use client'\n\nimport { useEffect, useRef } from 'react'\nimport { useDeferredActivation } from '../shared/defer'\nimport { SITE_KIT_VERSION } from '../shared/version'\nimport { detectNextVersion, sendFleetHeartbeat } from './heartbeat'\nimport type { FleetModule } from './contract'\n\n/** Session guard key — one heartbeat per session, re-sent when version/host changes. */\nconst SESSION_GUARD_KEY = '_sk_fleet_hb'\n\nexport interface FleetHeartbeatProps {\n /** Sonor API origin. Falls back to `window.__SITE_KIT_API_URL__` then api.sonor.io. */\n apiUrl?: string\n /** Project API key. Falls back to `window.__SITE_KIT_API_KEY__`. */\n apiKey?: string\n /** Host for the multi-site sub-dimension. Falls back to `__SITE_KIT_SITE__` then location.host. */\n site?: string | null\n /** Client-observable active modules (SiteKitClientProviders passes the enabled set). */\n modules?: FleetModule[]\n /** Installed Next.js version if known; otherwise best-effort runtime detection. */\n nextVersion?: string | null\n /**\n * Self-defer to idle / first interaction. Default true so standalone use is\n * safe. SiteKitClientProviders already gates the mount and passes false.\n */\n defer?: boolean\n /** Send at most once per browser session per (version, host). Default true. */\n oncePerSession?: boolean\n debug?: boolean\n}\n\nexport function FleetHeartbeat({\n apiUrl,\n apiKey,\n site,\n modules,\n nextVersion,\n defer = true,\n oncePerSession = true,\n debug = false,\n}: FleetHeartbeatProps) {\n const ready = useDeferredActivation(defer)\n const sentRef = useRef(false)\n\n useEffect(() => {\n if (!ready || sentRef.current) return\n if (typeof window === 'undefined') return\n\n const w = window as unknown as {\n __SITE_KIT_API_URL__?: string\n __SITE_KIT_API_KEY__?: string\n __SITE_KIT_SITE__?: string\n }\n const url = apiUrl || w.__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n const key = apiKey || w.__SITE_KIT_API_KEY__\n if (!key) return // no key resolvable — nothing to authenticate the heartbeat\n\n const resolvedSite = site ?? w.__SITE_KIT_SITE__ ?? window.location.host ?? ''\n\n // Once-per-session-per-(version,host): keeps heartbeat volume to one POST\n // per visitor session while still re-reporting after an upgrade or on a\n // different sub-site. Storage-disabled browsers simply send once per load.\n if (oncePerSession) {\n const stamp = `${SITE_KIT_VERSION}:${resolvedSite}`\n try {\n if (sessionStorage.getItem(SESSION_GUARD_KEY) === stamp) {\n sentRef.current = true\n return\n }\n sessionStorage.setItem(SESSION_GUARD_KEY, stamp)\n } catch {\n /* storage unavailable — fall through and send this load */\n }\n }\n\n sentRef.current = true\n void sendFleetHeartbeat({\n apiUrl: url,\n apiKey: key,\n site: resolvedSite,\n modules,\n nextVersion: nextVersion ?? detectNextVersion(),\n source: 'client',\n debug,\n })\n }, [ready, apiUrl, apiKey, site, modules, nextVersion, oncePerSession, debug])\n\n return null\n}\n"]}
@@ -1,7 +1,8 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunkHAZN43I6_js = require('./chunk-HAZN43I6.js');
4
+ var chunkLF3ID6WN_js = require('./chunk-LF3ID6WN.js');
5
+ var chunkGMSPDTEV_js = require('./chunk-GMSPDTEV.js');
5
6
  var react = require('react');
6
7
  var ReactMarkdown = require('react-markdown');
7
8
  var jsxRuntime = require('react/jsx-runtime');
@@ -36,7 +37,7 @@ function InlineManagedForm({ slug, prefill, primaryColor, primaryRgb }) {
36
37
  submit,
37
38
  isSubmitting,
38
39
  isComplete
39
- } = chunkHAZN43I6_js.useForm(slug, { initialValues: prefill || {} });
40
+ } = chunkLF3ID6WN_js.useForm(slug, { initialValues: prefill || {} });
40
41
  const cardStyle = {
41
42
  marginTop: 8,
42
43
  padding: 12,
@@ -79,7 +80,7 @@ function InlineManagedForm({ slug, prefill, primaryColor, primaryRgb }) {
79
80
  style: { display: "block", fontSize: 12.5, fontWeight: 600, marginBottom: 4, color: "var(--sk-text-secondary, #4b5563)" },
80
81
  children: [
81
82
  field.label,
82
- field.is_required ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--sk-error, #ef4444)" }, children: " *" }) : null
83
+ field.is_required ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--sk-error, #dc2626)" }, children: " *" }) : null
83
84
  ]
84
85
  }
85
86
  ) : null;
@@ -88,7 +89,7 @@ function InlineManagedForm({ slug, prefill, primaryColor, primaryRgb }) {
88
89
  id,
89
90
  placeholder: field.placeholder || (field.hide_label ? field.label : void 0),
90
91
  "aria-invalid": !!err,
91
- style: { ...inputBase, ...err ? { borderColor: "var(--sk-error, #ef4444)" } : {} }
92
+ style: { ...inputBase, ...err ? { borderColor: "var(--sk-error, #dc2626)" } : {} }
92
93
  };
93
94
  let control;
94
95
  switch (field.field_type) {
@@ -161,7 +162,7 @@ function InlineManagedForm({ slug, prefill, primaryColor, primaryRgb }) {
161
162
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: 8 }, children: [
162
163
  field.field_type === "checkbox" ? null : labelEl,
163
164
  control,
164
- err ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: "4px 0 0", fontSize: 11.5, color: "var(--sk-error, #ef4444)" }, children: err }) : null
165
+ err ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: "4px 0 0", fontSize: 11.5, color: "var(--sk-error, #dc2626)" }, children: err }) : null
165
166
  ] }, field.id || field.slug);
166
167
  };
167
168
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -181,7 +182,7 @@ function InlineManagedForm({ slug, prefill, primaryColor, primaryRgb }) {
181
182
  }
182
183
  return renderField(field);
183
184
  }),
184
- submitError ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", style: { margin: "0 0 8px", fontSize: 12, color: "var(--sk-error, #ef4444)" }, children: submitError }) : null,
185
+ submitError ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", style: { margin: "0 0 8px", fontSize: 12, color: "var(--sk-error, #dc2626)" }, children: submitError }) : null,
185
186
  /* @__PURE__ */ jsxRuntime.jsx(
186
187
  "button",
187
188
  {
@@ -388,9 +389,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
388
389
  const { apiKey } = getApiConfig();
389
390
  if (!apiKey) return;
390
391
  let cancelled = false;
391
- fetch(`${baseUrl}/api/public/seo/project-info`, {
392
- headers: { "x-api-key": apiKey }
393
- }).then((res) => res.ok ? res.json() : null).then((data) => {
392
+ chunkGMSPDTEV_js.sonorFetch(`${baseUrl}/api/public/seo/project-info`, {}, { apiKey, retries: 0 }).then((res) => res.ok ? res.json() : null).then((data) => {
394
393
  if (cancelled || !data?.valid || !data?.project_id) return;
395
394
  setResolvedProjectId(data.project_id);
396
395
  }).catch(() => {
@@ -404,9 +403,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
404
403
  const apiKey = ensureApiKey();
405
404
  if (!apiKey) return;
406
405
  try {
407
- const response = await fetch(`${baseUrl}/engage/widget/config?projectId=${projectId}`, {
408
- headers: { "x-api-key": apiKey }
409
- });
406
+ const response = await chunkGMSPDTEV_js.sonorFetch(`${baseUrl}/engage/widget/config?projectId=${projectId}`, {}, { apiKey, retries: 0 });
410
407
  if (response.ok) {
411
408
  const { data } = await response.json();
412
409
  setWidgetConfig(data ?? null);
@@ -422,9 +419,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
422
419
  const apiKey = ensureApiKey();
423
420
  if (!apiKey) return null;
424
421
  try {
425
- const response = await fetch(`${baseUrl}/engage/widget/availability?projectId=${projectId}`, {
426
- headers: { "x-api-key": apiKey }
427
- });
422
+ const response = await chunkGMSPDTEV_js.sonorFetch(`${baseUrl}/engage/widget/availability?projectId=${projectId}`, {}, { apiKey, retries: 0 });
428
423
  if (response.ok) {
429
424
  const { data } = await response.json();
430
425
  setAvailability(data);
@@ -441,16 +436,16 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
441
436
  const apiKey = ensureApiKey();
442
437
  if (!apiKey) return null;
443
438
  try {
444
- const response = await fetch(`${baseUrl}/engage/widget/session`, {
439
+ const response = await chunkGMSPDTEV_js.sonorFetch(`${baseUrl}/engage/widget/session`, {
445
440
  method: "POST",
446
- headers: { "Content-Type": "application/json", "x-api-key": apiKey },
441
+ headers: { "Content-Type": "application/json" },
447
442
  body: JSON.stringify({
448
443
  projectId,
449
444
  visitorId,
450
445
  sourceUrl: typeof window !== "undefined" ? window.location.href : "",
451
446
  userAgent: typeof navigator !== "undefined" ? navigator.userAgent : ""
452
447
  })
453
- });
448
+ }, { apiKey, retries: 0 });
454
449
  if (response.ok) {
455
450
  const { data } = await response.json();
456
451
  const session = data.session ?? data;
@@ -502,14 +497,13 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
502
497
  pageUrl: typeof window !== "undefined" ? window.location.href : void 0,
503
498
  ...siteContext ? { siteContext } : {}
504
499
  };
505
- const res = await fetch(url, {
500
+ const res = await chunkGMSPDTEV_js.sonorFetch(url, {
506
501
  method: "POST",
507
502
  headers: {
508
- "Content-Type": "application/json",
509
- "x-api-key": apiKey
503
+ "Content-Type": "application/json"
510
504
  },
511
505
  body: JSON.stringify(body)
512
- });
506
+ }, { apiKey, retries: 0 });
513
507
  const json = await res.json();
514
508
  if (!res.ok) {
515
509
  throw new Error(json?.error?.message || json?.message || `Signal API error: ${res.status}`);
@@ -614,9 +608,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
614
608
  if (currentSessionId) {
615
609
  const apiKey = ensureApiKey();
616
610
  if (apiKey) {
617
- fetch(`${baseUrl}/engage/widget/messages?sessionId=${currentSessionId}`, {
618
- headers: { "x-api-key": apiKey }
619
- }).then((res) => res.ok ? res.json() : null).then((json) => {
611
+ chunkGMSPDTEV_js.sonorFetch(`${baseUrl}/engage/widget/messages?sessionId=${currentSessionId}`, {}, { apiKey, retries: 0 }).then((res) => res.ok ? res.json() : null).then((json) => {
620
612
  const data = json?.data ?? json;
621
613
  if (Array.isArray(data) && data.length) {
622
614
  setMessages((prev) => {
@@ -679,9 +671,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
679
671
  try {
680
672
  const apiKey = ensureApiKey();
681
673
  if (!apiKey) return;
682
- const response = await fetch(`${baseUrl}/engage/widget/messages?sessionId=${currentSessionId}`, {
683
- headers: { "x-api-key": apiKey }
684
- });
674
+ const response = await chunkGMSPDTEV_js.sonorFetch(`${baseUrl}/engage/widget/messages?sessionId=${currentSessionId}`, {}, { apiKey, retries: 0 });
685
675
  if (response.ok) {
686
676
  const { data } = await response.json();
687
677
  setMessages((prev) => {
@@ -834,11 +824,10 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
834
824
  form.append("file", file);
835
825
  form.append("sessionId", sessionId);
836
826
  form.append("visitorId", visitorId);
837
- const res = await fetch(`${baseUrl}/engage/widget/upload`, {
827
+ const res = await chunkGMSPDTEV_js.sonorFetch(`${baseUrl}/engage/widget/upload`, {
838
828
  method: "POST",
839
- headers: { "x-api-key": apiKey },
840
829
  body: form
841
- });
830
+ }, { apiKey, retries: 0 });
842
831
  if (!res.ok) throw new Error("Upload failed");
843
832
  const json = await res.json();
844
833
  const d = json?.data ?? json;
@@ -982,11 +971,11 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
982
971
  if (!apiKey) return;
983
972
  setCheckingHandoff(true);
984
973
  try {
985
- const res = await fetch(`${baseUrl}/engage/widget/handoff`, {
974
+ const res = await chunkGMSPDTEV_js.sonorFetch(`${baseUrl}/engage/widget/handoff`, {
986
975
  method: "POST",
987
- headers: { "Content-Type": "application/json", "x-api-key": apiKey },
976
+ headers: { "Content-Type": "application/json" },
988
977
  body: JSON.stringify({ sessionId })
989
- });
978
+ }, { apiKey, retries: 0 });
990
979
  const json = await res.json();
991
980
  const available = json?.data?.available === true;
992
981
  setCheckingHandoff(false);
@@ -1021,9 +1010,9 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
1021
1010
  setIsLoading(true);
1022
1011
  setOfflineError(null);
1023
1012
  try {
1024
- const response = await fetch(`${baseUrl}/engage/widget/offline-form`, {
1013
+ const response = await chunkGMSPDTEV_js.sonorFetch(`${baseUrl}/engage/widget/offline-form`, {
1025
1014
  method: "POST",
1026
- headers: { "Content-Type": "application/json", "x-api-key": apiKey },
1015
+ headers: { "Content-Type": "application/json" },
1027
1016
  body: JSON.stringify({
1028
1017
  projectId,
1029
1018
  visitorId,
@@ -1031,7 +1020,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
1031
1020
  pageUrl: typeof window !== "undefined" ? window.location.href : "",
1032
1021
  ...widgetConfig?.offlineFormSlug && { formSlug: widgetConfig.offlineFormSlug }
1033
1022
  })
1034
- });
1023
+ }, { apiKey, retries: 0 });
1035
1024
  if (response.ok) {
1036
1025
  setOfflineSubmitted(true);
1037
1026
  } else {
@@ -1454,7 +1443,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
1454
1443
  {
1455
1444
  type: "button",
1456
1445
  onClick: retryFailedSend,
1457
- style: { padding: "6px 12px", borderRadius: 6, border: "1px solid var(--sk-error, #ef4444)", backgroundColor: "var(--sk-error-bg, #fef2f2)", color: "var(--sk-error, #dc2626)", fontSize: 13, cursor: "pointer" },
1446
+ style: { padding: "6px 12px", borderRadius: 6, border: "1px solid var(--sk-error, #dc2626)", backgroundColor: "var(--sk-error-bg, #fef2f2)", color: "var(--sk-error, #dc2626)", fontSize: 13, cursor: "pointer" },
1458
1447
  children: "Retry send"
1459
1448
  }
1460
1449
  ) }),
@@ -1622,5 +1611,5 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, sign
1622
1611
  }
1623
1612
 
1624
1613
  exports.ChatWidget = ChatWidget;
1625
- //# sourceMappingURL=chunk-NAVDN4AE.js.map
1626
- //# sourceMappingURL=chunk-NAVDN4AE.js.map
1614
+ //# sourceMappingURL=chunk-E7M5MDGC.js.map
1615
+ //# sourceMappingURL=chunk-E7M5MDGC.js.map