@sonordev/site-kit 6.3.6 → 6.5.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.
- package/agent-manifest.json +8 -2
- package/dist/AnalyticsProvider-44PDLORZ.js +34 -0
- package/dist/{AnalyticsProvider-L3GWK5PO.js.map → AnalyticsProvider-44PDLORZ.js.map} +1 -1
- package/dist/AnalyticsProvider-F6KHEAOX.mjs +13 -0
- package/dist/{AnalyticsProvider-XDVJTAPN.mjs.map → AnalyticsProvider-F6KHEAOX.mjs.map} +1 -1
- package/dist/{ArticleViewTracker-YMGW6ZXB.js → ArticleViewTracker-MGNVIHZ4.js} +6 -6
- package/dist/{ArticleViewTracker-YMGW6ZXB.js.map → ArticleViewTracker-MGNVIHZ4.js.map} +1 -1
- package/dist/{ArticleViewTracker-7AJJTGFY.mjs → ArticleViewTracker-NI4UNSY7.mjs} +5 -5
- package/dist/{ArticleViewTracker-7AJJTGFY.mjs.map → ArticleViewTracker-NI4UNSY7.mjs.map} +1 -1
- package/dist/{ChatWidget-MR64ZLOG.mjs → ChatWidget-XSALHDDW.mjs} +7 -7
- package/dist/{ChatWidget-MR64ZLOG.mjs.map → ChatWidget-XSALHDDW.mjs.map} +1 -1
- package/dist/{ChatWidget-IAYEXLNX.js → ChatWidget-YBXJRR2Z.js} +10 -10
- package/dist/{ChatWidget-IAYEXLNX.js.map → ChatWidget-YBXJRR2Z.js.map} +1 -1
- package/dist/EngageWidget-DUEXPVOY.mjs +13 -0
- package/dist/{EngageWidget-RANSIKC3.mjs.map → EngageWidget-DUEXPVOY.mjs.map} +1 -1
- package/dist/EngageWidget-MDCRS3BN.js +22 -0
- package/dist/{EngageWidget-BF7DH4GO.js.map → EngageWidget-MDCRS3BN.js.map} +1 -1
- package/dist/{FileField-VRKATE4G.js → FileField-AXU6KBSV.js} +6 -6
- package/dist/{FileField-VRKATE4G.js.map → FileField-AXU6KBSV.js.map} +1 -1
- package/dist/{FileField-7ZNQ5BID.mjs → FileField-UTLGR5ZN.mjs} +5 -5
- package/dist/{FileField-7ZNQ5BID.mjs.map → FileField-UTLGR5ZN.mjs.map} +1 -1
- package/dist/{FormSpotlight-QNH7XGYS.mjs → FormSpotlight-NWLCZMOT.mjs} +3 -3
- package/dist/{FormSpotlight-QNH7XGYS.mjs.map → FormSpotlight-NWLCZMOT.mjs.map} +1 -1
- package/dist/{FormSpotlight-VQJ2QWIU.js → FormSpotlight-RR5KJDIH.js} +9 -9
- package/dist/{FormSpotlight-VQJ2QWIU.js.map → FormSpotlight-RR5KJDIH.js.map} +1 -1
- package/dist/{FormStage-3JIN6X6O.js → FormStage-GFNX4GLU.js} +9 -9
- package/dist/{FormStage-3JIN6X6O.js.map → FormStage-GFNX4GLU.js.map} +1 -1
- package/dist/{FormStage-XB4JNFCH.mjs → FormStage-V4XKLI6J.mjs} +3 -3
- package/dist/{FormStage-XB4JNFCH.mjs.map → FormStage-V4XKLI6J.mjs.map} +1 -1
- package/dist/ManagedForm-4AD3LWSC.js +25 -0
- package/dist/{ManagedForm-Q5UFMUBE.js.map → ManagedForm-4AD3LWSC.js.map} +1 -1
- package/dist/ManagedForm-4IWPG6AZ.mjs +16 -0
- package/dist/{ManagedForm-E6F4FLVY.mjs.map → ManagedForm-4IWPG6AZ.mjs.map} +1 -1
- package/dist/{ManagedNewsletterForm-OEEC3GVY.mjs → ManagedNewsletterForm-ARSY2VHC.mjs} +6 -6
- package/dist/{ManagedNewsletterForm-OEEC3GVY.mjs.map → ManagedNewsletterForm-ARSY2VHC.mjs.map} +1 -1
- package/dist/{ManagedNewsletterForm-UTNOJ5T4.js → ManagedNewsletterForm-HJZNUABY.js} +7 -7
- package/dist/{ManagedNewsletterForm-UTNOJ5T4.js.map → ManagedNewsletterForm-HJZNUABY.js.map} +1 -1
- package/dist/{SignalCore-PWN5X6FF.mjs → SignalCore-N2LKG4XN.mjs} +5 -5
- package/dist/{SignalCore-PWN5X6FF.mjs.map → SignalCore-N2LKG4XN.mjs.map} +1 -1
- package/dist/{SignalCore-4AUWHMYK.js → SignalCore-P2JUY2BO.js} +11 -11
- package/dist/{SignalCore-4AUWHMYK.js.map → SignalCore-P2JUY2BO.js.map} +1 -1
- package/dist/SitemapSync-KFY4PJ7G.js +19 -0
- package/dist/{SitemapSync-DHJ25PSH.js.map → SitemapSync-KFY4PJ7G.js.map} +1 -1
- package/dist/SitemapSync-UYDL7T4M.mjs +10 -0
- package/dist/{SitemapSync-ZA2MNM63.mjs.map → SitemapSync-UYDL7T4M.mjs.map} +1 -1
- package/dist/analytics/index.js +14 -13
- package/dist/analytics/index.mjs +6 -5
- package/dist/articles/AuthorPage.d.ts +1 -1
- package/dist/articles/AuthorPage.d.ts.map +1 -1
- package/dist/articles/author-schema.d.ts +59 -13
- package/dist/articles/author-schema.d.ts.map +1 -1
- package/dist/articles/index.js +24 -23
- package/dist/articles/index.js.map +1 -1
- package/dist/articles/index.mjs +12 -11
- package/dist/articles/index.mjs.map +1 -1
- package/dist/articles/routes.d.ts +9 -0
- package/dist/articles/routes.d.ts.map +1 -1
- package/dist/articles/server-core.d.ts +5 -2
- package/dist/articles/server-core.d.ts.map +1 -1
- package/dist/articles/server-ui.js +45 -45
- package/dist/articles/server-ui.mjs +8 -8
- package/dist/articles/server.d.ts +5 -2
- package/dist/articles/server.d.ts.map +1 -1
- package/dist/articles/server.js +72 -56
- package/dist/articles/server.mjs +3 -3
- package/dist/articles/types.d.ts +23 -0
- package/dist/articles/types.d.ts.map +1 -1
- package/dist/{chunk-UAOQVHZW.js → chunk-34XL7TVH.js} +4 -4
- package/dist/{chunk-UAOQVHZW.js.map → chunk-34XL7TVH.js.map} +1 -1
- package/dist/chunk-3AOKYAZ2.js +135 -0
- package/dist/chunk-3AOKYAZ2.js.map +1 -0
- package/dist/{chunk-BJKA3XRS.mjs → chunk-3BLKKF67.mjs} +4 -4
- package/dist/{chunk-BJKA3XRS.mjs.map → chunk-3BLKKF67.mjs.map} +1 -1
- package/dist/{chunk-3J5L5DIK.js → chunk-3EAS4PAT.js} +3 -3
- package/dist/{chunk-3J5L5DIK.js.map → chunk-3EAS4PAT.js.map} +1 -1
- package/dist/{chunk-SB4CJX2X.mjs → chunk-42LLFAJQ.mjs} +3 -3
- package/dist/{chunk-SB4CJX2X.mjs.map → chunk-42LLFAJQ.mjs.map} +1 -1
- package/dist/{chunk-ZR43XFUM.js → chunk-55J2KE7D.js} +3 -3
- package/dist/chunk-55J2KE7D.js.map +1 -0
- package/dist/{chunk-VGBUC2JP.js → chunk-5ZMTEK7U.js} +10 -10
- package/dist/{chunk-VGBUC2JP.js.map → chunk-5ZMTEK7U.js.map} +1 -1
- package/dist/{chunk-6DCAMW62.mjs → chunk-6C47333H.mjs} +3 -3
- package/dist/chunk-6C47333H.mjs.map +1 -0
- package/dist/{chunk-E7EV2AHT.js → chunk-6OQYRVMI.js} +9 -9
- package/dist/{chunk-E7EV2AHT.js.map → chunk-6OQYRVMI.js.map} +1 -1
- package/dist/{chunk-UJIKP35G.mjs → chunk-7F66Y4MA.mjs} +4 -4
- package/dist/{chunk-UJIKP35G.mjs.map → chunk-7F66Y4MA.mjs.map} +1 -1
- package/dist/{chunk-6MOGGEY3.mjs → chunk-A2HL22BO.mjs} +3 -3
- package/dist/{chunk-6MOGGEY3.mjs.map → chunk-A2HL22BO.mjs.map} +1 -1
- package/dist/{chunk-7NFSSPGM.js → chunk-AL4Z6VYF.js} +8 -8
- package/dist/{chunk-7NFSSPGM.js.map → chunk-AL4Z6VYF.js.map} +1 -1
- package/dist/{chunk-W46QIVBM.mjs → chunk-B6QPCAEG.mjs} +3 -3
- package/dist/{chunk-W46QIVBM.mjs.map → chunk-B6QPCAEG.mjs.map} +1 -1
- package/dist/{chunk-EB33U2WT.js → chunk-BHZHWXER.js} +131 -71
- package/dist/chunk-BHZHWXER.js.map +1 -0
- package/dist/{chunk-R26FAQWF.mjs → chunk-BNKBRLJK.mjs} +3 -3
- package/dist/{chunk-R26FAQWF.mjs.map → chunk-BNKBRLJK.mjs.map} +1 -1
- package/dist/{chunk-A6UYV475.mjs → chunk-CABEVWKJ.mjs} +4 -24
- package/dist/chunk-CABEVWKJ.mjs.map +1 -0
- package/dist/{chunk-LWCAZDY2.js → chunk-CDRQYJUT.js} +4 -4
- package/dist/{chunk-LWCAZDY2.js.map → chunk-CDRQYJUT.js.map} +1 -1
- package/dist/{chunk-SAOUAIRS.js → chunk-CM4AVKXR.js} +14 -14
- package/dist/{chunk-SAOUAIRS.js.map → chunk-CM4AVKXR.js.map} +1 -1
- package/dist/{chunk-KMONA7CT.mjs → chunk-D3WJMSTB.mjs} +3 -3
- package/dist/{chunk-KMONA7CT.mjs.map → chunk-D3WJMSTB.mjs.map} +1 -1
- package/dist/{chunk-3Q3Y6OQE.mjs → chunk-DWZGW77V.mjs} +4 -4
- package/dist/{chunk-3Q3Y6OQE.mjs.map → chunk-DWZGW77V.mjs.map} +1 -1
- package/dist/{chunk-L6BQIDSZ.mjs → chunk-FPVYKSXE.mjs} +13 -10
- package/dist/chunk-FPVYKSXE.mjs.map +1 -0
- package/dist/{chunk-5XDOBM5S.js → chunk-G2KGHIAP.js} +3 -3
- package/dist/{chunk-5XDOBM5S.js.map → chunk-G2KGHIAP.js.map} +1 -1
- package/dist/chunk-GFSQMK35.mjs +127 -0
- package/dist/chunk-GFSQMK35.mjs.map +1 -0
- package/dist/chunk-GIGUDKLS.mjs +6 -0
- package/dist/{chunk-3V6DIQI7.mjs.map → chunk-GIGUDKLS.mjs.map} +1 -1
- package/dist/{chunk-BJ4T65OK.mjs → chunk-H4TSADY3.mjs} +3 -3
- package/dist/{chunk-BJ4T65OK.mjs.map → chunk-H4TSADY3.mjs.map} +1 -1
- package/dist/{chunk-J4C3JAJF.js → chunk-IO65ROAO.js} +15 -15
- package/dist/{chunk-J4C3JAJF.js.map → chunk-IO65ROAO.js.map} +1 -1
- package/dist/chunk-JCDX37BY.js +58 -0
- package/dist/chunk-JCDX37BY.js.map +1 -0
- package/dist/{chunk-5J4FKRGH.mjs → chunk-MDQLON5R.mjs} +5 -5
- package/dist/{chunk-5J4FKRGH.mjs.map → chunk-MDQLON5R.mjs.map} +1 -1
- package/dist/{chunk-3POB4JKR.js → chunk-MHKD34B4.js} +15 -15
- package/dist/{chunk-3POB4JKR.js.map → chunk-MHKD34B4.js.map} +1 -1
- package/dist/chunk-MXJOKOFK.mjs +51 -0
- package/dist/chunk-MXJOKOFK.mjs.map +1 -0
- package/dist/{chunk-5RNAUYWE.js → chunk-NH2P27MA.js} +4 -27
- package/dist/chunk-NH2P27MA.js.map +1 -0
- package/dist/{chunk-5DZVQW35.mjs → chunk-OFBEBMXN.mjs} +4 -4
- package/dist/{chunk-5DZVQW35.mjs.map → chunk-OFBEBMXN.mjs.map} +1 -1
- package/dist/{chunk-G3L26XQ7.js → chunk-OIPG3EGM.js} +5 -5
- package/dist/{chunk-G3L26XQ7.js.map → chunk-OIPG3EGM.js.map} +1 -1
- package/dist/{chunk-2UZULHI4.js → chunk-OY3PDIB3.js} +10 -10
- package/dist/{chunk-2UZULHI4.js.map → chunk-OY3PDIB3.js.map} +1 -1
- package/dist/{chunk-SNXJXPB6.js → chunk-PFDRQJKJ.js} +13 -13
- package/dist/{chunk-SNXJXPB6.js.map → chunk-PFDRQJKJ.js.map} +1 -1
- package/dist/{chunk-CXYGKK4U.mjs → chunk-PGYOBEPL.mjs} +3 -3
- package/dist/{chunk-CXYGKK4U.mjs.map → chunk-PGYOBEPL.mjs.map} +1 -1
- package/dist/{chunk-TE3YNZVH.js → chunk-PIPGH7GA.js} +4 -4
- package/dist/{chunk-TE3YNZVH.js.map → chunk-PIPGH7GA.js.map} +1 -1
- package/dist/chunk-PURI56RE.js +8 -0
- package/dist/{chunk-6SBRD5KT.js.map → chunk-PURI56RE.js.map} +1 -1
- package/dist/{chunk-X3MY4PL7.mjs → chunk-QAQTDHHT.mjs} +10 -14
- package/dist/chunk-QAQTDHHT.mjs.map +1 -0
- package/dist/{chunk-PMWF5CRL.js → chunk-QCS7NWMA.js} +15 -12
- package/dist/chunk-QCS7NWMA.js.map +1 -0
- package/dist/{chunk-HXHRS3PX.mjs → chunk-RCB6HEHM.mjs} +3 -3
- package/dist/{chunk-HXHRS3PX.mjs.map → chunk-RCB6HEHM.mjs.map} +1 -1
- package/dist/{chunk-ANYCUTS5.js → chunk-RMDH2HMW.js} +3 -3
- package/dist/{chunk-ANYCUTS5.js.map → chunk-RMDH2HMW.js.map} +1 -1
- package/dist/{chunk-NAA5J2JM.js → chunk-RQROZLH3.js} +47 -51
- package/dist/chunk-RQROZLH3.js.map +1 -0
- package/dist/{chunk-X5J3PYZJ.js → chunk-SUGBIEYQ.js} +9 -9
- package/dist/{chunk-X5J3PYZJ.js.map → chunk-SUGBIEYQ.js.map} +1 -1
- package/dist/{chunk-LFF32POH.mjs → chunk-SVCKJ5KH.mjs} +4 -4
- package/dist/{chunk-LFF32POH.mjs.map → chunk-SVCKJ5KH.mjs.map} +1 -1
- package/dist/{chunk-YKZ3EVAQ.mjs → chunk-THO4NS6Z.mjs} +3 -3
- package/dist/{chunk-YKZ3EVAQ.mjs.map → chunk-THO4NS6Z.mjs.map} +1 -1
- package/dist/{chunk-K6ZQVDP4.mjs → chunk-TPEPAHU5.mjs} +3 -3
- package/dist/{chunk-K6ZQVDP4.mjs.map → chunk-TPEPAHU5.mjs.map} +1 -1
- package/dist/{chunk-FRUBUQOH.js → chunk-U577ITSA.js} +5 -5
- package/dist/{chunk-FRUBUQOH.js.map → chunk-U577ITSA.js.map} +1 -1
- package/dist/{chunk-B2NO5QVY.mjs → chunk-UCQDE5UH.mjs} +3 -3
- package/dist/{chunk-B2NO5QVY.mjs.map → chunk-UCQDE5UH.mjs.map} +1 -1
- package/dist/{chunk-KB7SIIVY.mjs → chunk-VA2O5OSV.mjs} +3 -3
- package/dist/{chunk-KB7SIIVY.mjs.map → chunk-VA2O5OSV.mjs.map} +1 -1
- package/dist/{chunk-6I5O5CTL.mjs → chunk-VJTKIKZY.mjs} +128 -68
- package/dist/chunk-VJTKIKZY.mjs.map +1 -0
- package/dist/{chunk-OLVCGOXZ.js → chunk-VUAGR6VL.js} +12 -12
- package/dist/{chunk-OLVCGOXZ.js.map → chunk-VUAGR6VL.js.map} +1 -1
- package/dist/{chunk-PQICWWQW.mjs → chunk-XEOIGCUE.mjs} +5 -5
- package/dist/{chunk-PQICWWQW.mjs.map → chunk-XEOIGCUE.mjs.map} +1 -1
- package/dist/chunk-YMZNEDFP.js +39 -0
- package/dist/chunk-YMZNEDFP.js.map +1 -0
- package/dist/chunk-Z2URIOKG.mjs +36 -0
- package/dist/chunk-Z2URIOKG.mjs.map +1 -0
- package/dist/{chunk-2MEMK5XC.js → chunk-ZXC56JS3.js} +14 -14
- package/dist/{chunk-2MEMK5XC.js.map → chunk-ZXC56JS3.js.map} +1 -1
- package/dist/cli/index.js +3 -3
- package/dist/cli/index.mjs +1 -1
- package/dist/client/index.js +4 -4
- package/dist/client/index.mjs +3 -3
- package/dist/commerce/index.js +59 -58
- package/dist/commerce/index.mjs +7 -6
- package/dist/engage/DesignRenderer.d.ts.map +1 -1
- package/dist/engage/EngageWidget.d.ts.map +1 -1
- package/dist/engage/element-rules.d.ts +39 -0
- package/dist/engage/element-rules.d.ts.map +1 -0
- package/dist/engage/index.js +11 -10
- package/dist/engage/index.js.map +1 -1
- package/dist/engage/index.mjs +8 -7
- package/dist/engage/index.mjs.map +1 -1
- package/dist/fleet/index.js +10 -9
- package/dist/fleet/index.mjs +6 -5
- package/dist/forms/index.js +13 -13
- package/dist/forms/index.mjs +7 -7
- package/dist/forms/server.js +2 -2
- package/dist/forms/server.mjs +1 -1
- package/dist/images/index.js +11 -11
- package/dist/images/index.mjs +4 -4
- package/dist/index.js +65 -64
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -10
- package/dist/index.mjs.map +1 -1
- package/dist/layout/SiteKitClientProviders.d.ts.map +1 -1
- package/dist/layout/client.d.ts.map +1 -1
- package/dist/layout/client.js +10 -9
- package/dist/layout/client.mjs +9 -8
- package/dist/layout/index.js +12 -11
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/index.mjs +10 -9
- package/dist/layout/index.mjs.map +1 -1
- package/dist/layout/types.d.ts +6 -0
- package/dist/layout/types.d.ts.map +1 -1
- package/dist/llms/index.d.ts +2 -0
- package/dist/llms/index.d.ts.map +1 -1
- package/dist/llms/index.js +129 -14
- package/dist/llms/index.js.map +1 -1
- package/dist/llms/index.mjs +115 -5
- package/dist/llms/index.mjs.map +1 -1
- package/dist/llms/revalidate.d.ts +3 -0
- package/dist/llms/revalidate.d.ts.map +1 -1
- package/dist/llms/seo-revalidate.d.ts +105 -0
- package/dist/llms/seo-revalidate.d.ts.map +1 -0
- package/dist/maps/index.js +5 -5
- package/dist/maps/index.mjs +3 -3
- package/dist/mcp/transport.d.ts +166 -0
- package/dist/mcp/transport.d.ts.map +1 -0
- package/dist/mcp/transport.js +137 -0
- package/dist/mcp/transport.js.map +1 -0
- package/dist/mcp/transport.mjs +123 -0
- package/dist/mcp/transport.mjs.map +1 -0
- package/dist/portfolio/contract.d.ts +93 -0
- package/dist/portfolio/contract.d.ts.map +1 -1
- package/dist/portfolio/contract.js +94 -1
- package/dist/portfolio/contract.js.map +1 -1
- package/dist/portfolio/contract.mjs +79 -2
- package/dist/portfolio/contract.mjs.map +1 -1
- package/dist/search/index.js +4 -4
- package/dist/search/index.mjs +3 -3
- package/dist/seo/client.js +7 -6
- package/dist/seo/client.mjs +6 -5
- package/dist/seo/index.js +7 -6
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +6 -5
- package/dist/seo/index.mjs.map +1 -1
- package/dist/seo/register-sitemap-cli.js +1 -1
- package/dist/seo/register-sitemap-cli.mjs +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +2 -2
- package/dist/shared/build-entries.d.ts +7 -0
- package/dist/shared/build-entries.d.ts.map +1 -1
- package/dist/shared/frame.d.ts +15 -0
- package/dist/shared/frame.d.ts.map +1 -1
- package/dist/shared/request-guards.d.ts +27 -0
- package/dist/shared/request-guards.d.ts.map +1 -0
- package/dist/shared/version.d.ts +1 -1
- package/dist/signal/index.js +11 -11
- package/dist/signal/index.mjs +2 -2
- package/dist/sitemap/index.js +3 -3
- package/dist/sitemap/index.mjs +2 -2
- package/dist/sync/index.js +17 -17
- package/dist/sync/index.mjs +4 -4
- package/dist/{writeLLMsTxt-LYYC3ZSN.mjs → writeLLMsTxt-IYJILIU3.mjs} +3 -3
- package/dist/{writeLLMsTxt-XHLHJ5XY.js → writeLLMsTxt-SQG4B63X.js} +4 -4
- package/package.json +24 -21
- package/dist/AnalyticsProvider-L3GWK5PO.js +0 -33
- package/dist/AnalyticsProvider-XDVJTAPN.mjs +0 -12
- package/dist/EngageWidget-BF7DH4GO.js +0 -21
- package/dist/EngageWidget-RANSIKC3.mjs +0 -12
- package/dist/ManagedForm-E6F4FLVY.mjs +0 -16
- package/dist/ManagedForm-Q5UFMUBE.js +0 -25
- package/dist/SitemapSync-DHJ25PSH.js +0 -18
- package/dist/SitemapSync-ZA2MNM63.mjs +0 -9
- package/dist/chunk-3V6DIQI7.mjs +0 -6
- package/dist/chunk-5RNAUYWE.js.map +0 -1
- package/dist/chunk-6DCAMW62.mjs.map +0 -1
- package/dist/chunk-6I5O5CTL.mjs.map +0 -1
- package/dist/chunk-6SBRD5KT.js +0 -8
- package/dist/chunk-A6UYV475.mjs.map +0 -1
- package/dist/chunk-EB33U2WT.js.map +0 -1
- package/dist/chunk-L6BQIDSZ.mjs.map +0 -1
- package/dist/chunk-NAA5J2JM.js.map +0 -1
- package/dist/chunk-PMWF5CRL.js.map +0 -1
- package/dist/chunk-X3MY4PL7.mjs.map +0 -1
- package/dist/chunk-YRCR7WY3.js +0 -65
- package/dist/chunk-YRCR7WY3.js.map +0 -1
- package/dist/chunk-ZL35JCDA.mjs +0 -61
- package/dist/chunk-ZL35JCDA.mjs.map +0 -1
- package/dist/chunk-ZR43XFUM.js.map +0 -1
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { publishSiteCredential } from './chunk-
|
|
3
|
-
import { FleetHeartbeat } from './chunk-
|
|
2
|
+
import { publishSiteCredential } from './chunk-VA2O5OSV.mjs';
|
|
3
|
+
import { FleetHeartbeat } from './chunk-MDQLON5R.mjs';
|
|
4
4
|
import { useDeferredActivation } from './chunk-ZVBLXXNJ.mjs';
|
|
5
|
-
import { SignalBridge } from './chunk-
|
|
5
|
+
import { SignalBridge } from './chunk-A2HL22BO.mjs';
|
|
6
6
|
import { resolveSiteHost } from './chunk-KZVSB5WE.mjs';
|
|
7
7
|
import { getOrCreateVisitorId, getOrCreateSessionId } from './chunk-ZZQAGCSI.mjs';
|
|
8
|
-
import
|
|
8
|
+
import { announceFrameReady, isCrossOriginFrame } from './chunk-MXJOKOFK.mjs';
|
|
9
|
+
import React, { useState, useRef, useCallback, useEffect, Suspense } from 'react';
|
|
9
10
|
import dynamic from 'next/dynamic';
|
|
10
11
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
11
12
|
|
|
12
13
|
var LazyAnalyticsProvider = dynamic(
|
|
13
|
-
() => import('./AnalyticsProvider-
|
|
14
|
+
() => import('./AnalyticsProvider-F6KHEAOX.mjs').then((m) => ({ default: m.AnalyticsProvider })),
|
|
14
15
|
{ ssr: false }
|
|
15
16
|
);
|
|
16
17
|
var LazyEngageWidget = dynamic(
|
|
17
|
-
() => import('./EngageWidget-
|
|
18
|
+
() => import('./EngageWidget-DUEXPVOY.mjs').then((m) => ({ default: m.EngageWidget })),
|
|
18
19
|
{ ssr: false }
|
|
19
20
|
);
|
|
20
21
|
var LazySitemapSync = dynamic(
|
|
21
|
-
() => import('./SitemapSync-
|
|
22
|
+
() => import('./SitemapSync-UYDL7T4M.mjs').then((m) => ({ default: m.SitemapSync })),
|
|
22
23
|
{ ssr: false }
|
|
23
24
|
);
|
|
24
25
|
function SiteKitClientProviders({
|
|
@@ -44,6 +45,7 @@ function SiteKitClientProviders({
|
|
|
44
45
|
const onPageMetadata = useCallback((metadata) => {
|
|
45
46
|
pageMetadataRef.current = metadata;
|
|
46
47
|
}, []);
|
|
48
|
+
useEffect(() => announceFrameReady(), []);
|
|
47
49
|
const siblings = [];
|
|
48
50
|
if (signal) {
|
|
49
51
|
const signalConfig = typeof signal === "object" ? signal : {};
|
|
@@ -89,8 +91,9 @@ function SiteKitClientProviders({
|
|
|
89
91
|
}
|
|
90
92
|
if (engage) {
|
|
91
93
|
const engageConfig = typeof engage === "object" ? engage : {};
|
|
94
|
+
const engageInFrame = engageConfig.allowInFrame === true;
|
|
92
95
|
siblings.push(
|
|
93
|
-
/* @__PURE__ */ jsx(React.Fragment, { children: modulesReady && /* @__PURE__ */ jsx(
|
|
96
|
+
/* @__PURE__ */ jsx(React.Fragment, { children: modulesReady && (engageInFrame || !isCrossOriginFrame()) && /* @__PURE__ */ jsx(
|
|
94
97
|
LazyEngageWidget,
|
|
95
98
|
{
|
|
96
99
|
apiUrl,
|
|
@@ -147,5 +150,5 @@ function SiteKitClientProviders({
|
|
|
147
150
|
}
|
|
148
151
|
|
|
149
152
|
export { SiteKitClientProviders };
|
|
150
|
-
//# sourceMappingURL=chunk-
|
|
151
|
-
//# sourceMappingURL=chunk-
|
|
153
|
+
//# sourceMappingURL=chunk-FPVYKSXE.mjs.map
|
|
154
|
+
//# sourceMappingURL=chunk-FPVYKSXE.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/layout/SiteKitClientProviders.tsx"],"names":[],"mappings":"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","file":"chunk-FPVYKSXE.mjs","sourcesContent":["'use client'\n\n/**\n * SiteKitClientProviders — Client Island\n *\n * This is the 'use client' boundary for SiteKitLayout.\n * It composes the client-only providers (Analytics, Engage, Signal, SitemapSync)\n * that require React context or browser APIs.\n *\n * All modules are lazy-loaded via next/dynamic so their JS is only downloaded\n * when the feature is enabled — keeping the initial bundle lightweight.\n *\n * All modules share a unified identity (visitor ID + session ID) read from\n * the storage-backed singleton (shared/identity), ensuring consistent\n * tracking across Analytics, Signal, and Engage.\n *\n * 4.0 INVARIANT — CHILDREN ARE NEVER WRAPPED. Every module here renders as a\n * childless sibling AFTER {children}; nothing provides context around page\n * content. That makes the prerender-bailout / remount-flash class of bug\n * structurally impossible. Do not reintroduce a wrapper.\n *\n * Props are passed down from the server-side SiteKitLayout component,\n * which reads env vars at render time.\n */\n\nimport React, { Suspense, useCallback, useEffect, useRef, useState, type ReactNode } from 'react'\nimport dynamic from 'next/dynamic'\nimport {\n getOrCreateVisitorId,\n getOrCreateSessionId,\n} from '../shared/identity'\n// Defer non-critical module mounting until the page is quiet: the lazy\n// modules below are dynamic(ssr:false) and never render on the server, but\n// rendering them during hydration still kicks off their chunk downloads +\n// mount effects inside the critical startup window. useDeferredActivation\n// holds them until window.load + idle or first interaction — the same\n// strategy as the hand-rolled per-site deferrals this replaces (upforge\n// `deferred-analytics.tsx`, TPS `DeferredAnalytics.tsx`). The hook is public\n// (`@sonordev/site-kit/client`) so sites can reuse it for their own scripts.\nimport { useDeferredActivation } from '../shared/defer'\nimport { announceFrameReady, isCrossOriginFrame } from '../shared/frame'\n// Single source of truth for seeding the token manager + the __SITE_KIT_*\n// globals — shared with the public `SiteKitCredential` component that\n// non-core layouts (agency-site-kit) use. Do not re-inline it here.\nimport { publishSiteCredential, resolveSiteHost } from '../shared/publishCredential'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\n// Lazy-load feature modules — JS only downloaded when feature is enabled\nconst LazyAnalyticsProvider = dynamic(\n () => import('../analytics/AnalyticsProvider').then(m => ({ default: m.AnalyticsProvider })),\n { ssr: false },\n)\nconst LazyEngageWidget = dynamic(\n () => import('../engage/EngageWidget').then(m => ({ default: m.EngageWidget })),\n { ssr: false },\n)\nconst LazySitemapSync = dynamic(\n () => import('../SitemapSync').then(m => ({ default: m.SitemapSync })),\n { ssr: false },\n)\n// SignalBridge is imported STATICALLY, not via dynamic(ssr:false): it is a\n// tiny SSR-safe context shell that renders children immediately and\n// lazy-loads its machinery (SignalCore) as a childless sibling internally.\n// Wrapping children in a dynamic(ssr:false) component was the old SSR-bailout\n// failure mode — do not reintroduce it.\nimport { SignalBridge } from '../signal/SignalBridge'\n// Fleet heartbeat: a deferred, CHILDLESS SIBLING (like Analytics/Engage) that\n// reports this site's kit version + active modules once per session, so the\n// platform can see version drift across the fleet. Tiny and SSR-safe — renders\n// null until the shared idle gate fires; never wraps page content.\nimport { FleetHeartbeat } from '../fleet/FleetHeartbeat'\nimport type { FleetModule } from '../fleet/contract'\n\nexport interface SiteKitClientProvidersProps {\n children: ReactNode\n apiKey: string\n apiUrl: string\n projectId?: string\n analytics?: boolean | AnalyticsConfig\n engage?: boolean | EngageConfig\n signal?: boolean | SignalConfig\n /**\n * Runtime SitemapSync from the visitor's browser. Default FALSE — sitemap\n * registration belongs to build time and to sonor-api's nightly reconciler,\n * not to whoever happens to load the page. See SiteKitLayout for the full\n * reasoning; in short, its guards live in session/localStorage, so every new\n * visitor missed them and re-POSTed the whole sitemap.\n */\n sitemapSync?: boolean\n /**\n * Fleet heartbeat — reports kit version + active modules to Sonor once per\n * session so the platform can track version drift and key state across every\n * site. Default true. Deferred exactly like Analytics; never in the hydration\n * path, carries no visitor data.\n */\n fleet?: boolean\n /**\n * Defer Analytics / Engage / SitemapSync until window load + idle or first\n * interaction (default true). Pass false to restore legacy eager mounting\n * on hydration. SignalBridge is never deferred — it must apply experiment\n * variants as early as possible.\n */\n defer?: boolean\n debug?: boolean\n /** Browser-safe Google Maps key, resolved server-side by SiteKitLayout. */\n}\n\nexport function SiteKitClientProviders({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = false,\n fleet = true,\n defer = true,\n debug = false,\n}: SiteKitClientProvidersProps) {\n // One shared activation gate for all deferred siblings, so they mount in a\n // single commit instead of staggered re-renders.\n const modulesReady = useDeferredActivation(defer)\n // Hoist analytics config so the `site` dimension is resolvable up here.\n const analyticsConfig: AnalyticsConfig =\n typeof analytics === 'object' ? analytics : {}\n\n // Resolve the sub-site identifier — the dimension that lets one Sonor project\n // host many sites (e.g. truepowersystems.com + ohiopowerstudies.com under one\n // TPS project). Precedence lives in resolveSiteHost (shared contract):\n // explicit `analytics.site` > NEXT_PUBLIC_SITE_URL host > window.location.host.\n // Needed as a local too — SignalBridge and the analytics config read it below.\n const site = resolveSiteHost(analyticsConfig.site)\n\n // Seed the token manager + publish the window globals modules read from.\n // No-op on the server; runs during render so it lands before child effects.\n publishSiteCredential({ apiKey, apiUrl, site, debug })\n\n // Unified identity — single source of truth for all modules\n const [visitorId] = useState(() => getOrCreateVisitorId())\n const [sessionId] = useState(() => getOrCreateSessionId())\n\n // Page metadata bridge: Analytics writes, Signal reads\n const pageMetadataRef = useRef<Record<string, unknown> | null>(null)\n const onPageMetadata = useCallback((metadata: Record<string, unknown>) => {\n pageMetadataRef.current = metadata\n }, [])\n\n // Framed by another origin (a case study's device frame), tell the embedder\n // once this page has painted, so it can let the live page show through its\n // screenshot. A no-op at the top level. See shared/frame.ts.\n useEffect(() => announceFrameReady(), [])\n\n // Children render FIRST and are never re-parented. Siblings accumulate after.\n const siblings: ReactNode[] = []\n\n // SignalBridge — childless sibling (4.0: useSignal reads the module store,\n // so it no longer needs to wrap anything). Not gated on modulesReady:\n // experiment variants must apply as early as possible.\n if (signal) {\n const signalConfig: SignalConfig =\n typeof signal === 'object' ? signal : {}\n siblings.push(\n <SignalBridge\n key=\"sk-signal\"\n enabled\n realtime={signalConfig.realtime !== false}\n experiments={signalConfig.experiments !== false}\n behaviorTracking={signalConfig.behaviorTracking !== false}\n visitorId={visitorId}\n sessionId={sessionId}\n pageMetadataRef={pageMetadataRef}\n />,\n )\n }\n\n // Add Analytics if enabled (renders alongside, doesn't wrap).\n //\n // CRITICAL: LazyAnalyticsProvider is dynamic(..., { ssr: false }). Wrapping\n // {content} inside an ssr:false component makes the entire page tree skip\n // server rendering — the route de-opts to 100% client rendering and the\n // hero / LCP element only paints after hydration (mobile LCP ~4s, Lighthouse\n // ~85). Analytics tracks via effects + a metadata ref, so it never needs to\n // wrap page content — mount it as a childless sibling, exactly like Engage.\n // Each deferred sibling is appended as `{modulesReady && <Module/>}` so the\n // children slot never moves in the tree — flipping ready only mounts the\n // sibling, it never remounts page content.\n if (analytics) {\n siblings.push(\n <React.Fragment key=\"sk-analytics\">\n {modulesReady && (\n <Suspense fallback={null}>\n <LazyAnalyticsProvider\n apiUrl={apiUrl}\n apiKey={apiKey}\n site={site}\n trackPageViews={analyticsConfig.trackPageViews !== false}\n trackWebVitals={analyticsConfig.trackWebVitals !== false}\n trackScrollDepth={analyticsConfig.trackScrollDepth !== false}\n trackClicks={analyticsConfig.trackClicks !== false}\n sessionTimeout={analyticsConfig.sessionDuration}\n excludePaths={analyticsConfig.excludePaths}\n // Off by default: a cross-origin embed of this site reports\n // nothing (see analytics/send-gate.ts). Opt in per site.\n allowInFrame={analyticsConfig.allowInFrame === true}\n allowLocalhost={analyticsConfig.allowLocalhost === true}\n debug={debug}\n externalVisitorId={visitorId}\n externalSessionId={sessionId}\n onPageMetadata={onPageMetadata}\n />\n </Suspense>\n )}\n </React.Fragment>,\n )\n }\n\n // Engage widget — childless sibling\n if (engage) {\n const engageConfig: EngageConfig =\n typeof engage === 'object' ? engage : {}\n // Not inside someone else's page: a popup or chat launcher in a case\n // study's device frame is shown to the agency's visitor, not this site's,\n // and its impressions would count against this site. Same default and\n // opt-in as analytics (allowInFrame). modulesReady is false on the server\n // and in the first client render, so the frame check never runs there.\n const engageInFrame = engageConfig.allowInFrame === true\n siblings.push(\n <React.Fragment key=\"sk-engage\">\n {modulesReady && (engageInFrame || !isCrossOriginFrame()) && (\n <LazyEngageWidget\n apiUrl={apiUrl}\n apiKey={apiKey}\n projectId={projectId}\n allowInFrame={analyticsConfig.allowInFrame === true}\n allowLocalhost={analyticsConfig.allowLocalhost === true}\n position={engageConfig.position || 'bottom-right'}\n offsetBottom={engageConfig.offsetBottom}\n zIndex={engageConfig.zIndex}\n chatEnabled={engageConfig.chatEnabled !== false}\n />\n )}\n </React.Fragment>,\n )\n }\n\n // SitemapSync — childless sibling\n if (sitemapSync) {\n siblings.push(\n <React.Fragment key=\"sk-sitemap\">\n {modulesReady && (\n <LazySitemapSync\n debug={debug}\n allowInFrame={analyticsConfig.allowInFrame === true}\n allowLocalhost={analyticsConfig.allowLocalhost === true}\n />\n )}\n </React.Fragment>,\n )\n }\n\n // Fleet heartbeat — childless sibling on the same modulesReady idle gate.\n // Reports the modules actually enabled on THIS layout (honest client-observable\n // set) so the platform can answer \"which version / modules is each site\n // running\". defer={false}: the modulesReady gate already handled deferral, so\n // the heartbeat fires on mount (still bounded to once per session internally).\n if (fleet) {\n const activeModules: FleetModule[] = []\n if (analytics) activeModules.push('analytics')\n if (engage) activeModules.push('engage')\n if (signal) activeModules.push('signal')\n if (sitemapSync) activeModules.push('sitemapSync')\n siblings.push(\n <React.Fragment key=\"sk-fleet\">\n {modulesReady && (\n <FleetHeartbeat\n apiUrl={apiUrl}\n apiKey={apiKey}\n site={site}\n modules={activeModules}\n allowInFrame={analyticsConfig.allowInFrame === true}\n allowLocalhost={analyticsConfig.allowLocalhost === true}\n defer={false}\n debug={debug}\n />\n )}\n </React.Fragment>,\n )\n }\n\n return (\n <>\n {children}\n {siblings}\n </>\n )\n}\n"]}
|
|
@@ -60,7 +60,7 @@ function useSignal() {
|
|
|
60
60
|
return react.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
61
61
|
}
|
|
62
62
|
var LazySignalCore = dynamic__default.default(
|
|
63
|
-
() => import('./SignalCore-
|
|
63
|
+
() => import('./SignalCore-P2JUY2BO.js').then((m) => ({ default: m.SignalCore })),
|
|
64
64
|
{ ssr: false }
|
|
65
65
|
);
|
|
66
66
|
function SignalBridge({
|
|
@@ -172,5 +172,5 @@ exports.useSignalConfig = useSignalConfig;
|
|
|
172
172
|
exports.useSignalEvent = useSignalEvent;
|
|
173
173
|
exports.useSignalExperiment = useSignalExperiment;
|
|
174
174
|
exports.useSignalOutcome = useSignalOutcome;
|
|
175
|
-
//# sourceMappingURL=chunk-
|
|
176
|
-
//# sourceMappingURL=chunk-
|
|
175
|
+
//# sourceMappingURL=chunk-G2KGHIAP.js.map
|
|
176
|
+
//# sourceMappingURL=chunk-G2KGHIAP.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/signal/store.ts","../src/signal/SignalBridge.tsx"],"names":["useSyncExternalStore","dynamic","useState","useRef","useCallback","useMemo","useEffect","jsxs","Fragment","jsx"],"mappings":"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","file":"chunk-5XDOBM5S.js","sourcesContent":["'use client'\n\n/**\n * Signal store — module singleton behind useSignal().\n *\n * 4.0: SignalBridge no longer wraps page children in a React context; it\n * mounts as a childless sibling and publishes its API here. useSignal()\n * subscribes via useSyncExternalStore, so consumers work anywhere in the\n * tree — and BEFORE the bridge mounts, they get a buffering stub whose\n * trackEvent/trackOutcome queue calls that the bridge drains on publish.\n * getExperiment returns null pre-publish, identical to the pre-config\n * `loading` window consumers already handle.\n *\n * Behavior change vs 3.x (major): useSignal() no longer throws outside a\n * SignalBridge. With signal disabled it stays a bounded no-op stub — a\n * one-time debug warning fires instead of a crash.\n */\n\nimport { useSyncExternalStore } from 'react'\nimport type {\n SignalContextValue,\n SignalEvent,\n SignalOutcome,\n} from './types'\n\nconst pendingEvents: Partial<SignalEvent>[] = []\nconst pendingOutcomes: SignalOutcome[] = []\nconst MAX_PENDING = 100\nlet warnedNoBridge = false\n\n/** Frozen pre-bridge stub — stable reference (useSyncExternalStore requirement). */\nconst STUB: SignalContextValue = Object.freeze({\n config: null,\n loading: true,\n error: null,\n trackEvent: (event: Partial<SignalEvent>) => {\n if (pendingEvents.length < MAX_PENDING) pendingEvents.push(event)\n else if (!warnedNoBridge) {\n warnedNoBridge = true\n console.warn('[site-kit] Signal events are queuing but no SignalBridge has mounted — is signal enabled on SiteKitLayout?')\n }\n },\n trackOutcome: (outcome: SignalOutcome) => {\n if (pendingOutcomes.length < MAX_PENDING) pendingOutcomes.push(outcome)\n },\n getExperiment: () => null,\n refreshConfig: async () => {},\n})\n\nlet current: SignalContextValue = STUB\nconst listeners = new Set<() => void>()\n\nfunction emit() {\n for (const l of listeners) l()\n}\n\n/** Bridge-side: publish the live API (called whenever its value changes). */\nexport function publishSignal(value: SignalContextValue): void {\n const firstPublish = current === STUB\n current = value\n if (firstPublish) {\n // Drain calls made before the bridge mounted. The bridge's own trackEvent\n // buffers again internally until SignalCore loads, so nothing is lost.\n pendingEvents.splice(0).forEach(e => value.trackEvent(e))\n pendingOutcomes.splice(0).forEach(o => value.trackOutcome(o))\n }\n emit()\n}\n\n/** Bridge-side: reset on unmount so a remount starts clean (tests, HMR). */\nexport function resetSignal(): void {\n current = STUB\n emit()\n}\n\nfunction subscribe(onChange: () => void) {\n listeners.add(onChange)\n return () => listeners.delete(onChange)\n}\n\nconst getSnapshot = () => current\nconst getServerSnapshot = () => STUB\n\n/**\n * Access Signal (experiments, behavioral events) from anywhere in the tree.\n * No provider required — see module docs for pre-mount buffering semantics.\n */\nexport function useSignal(): SignalContextValue {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n}\n","/**\n * @sonordev/site-kit/signal - SignalBridge\n *\n * Central coordination layer for Signal AI integration.\n *\n * Architecture (2026-07 perf release): SignalBridge is a tiny SSR-SAFE context shell. It\n * renders {children} immediately — children server-render and hydrate\n * normally, no ssr:false wrapper — and lazy-loads the heavy machinery\n * (SignalCore: config fetch, SSE streaming, experiment assignment, event\n * queue, behavior tracking) as a CHILDLESS sibling. The core registers its\n * imperative API into the shell on mount; `trackEvent`/`trackOutcome` calls\n * made before the core is ready are buffered and drained on registration.\n *\n * This removes the old failure mode where enabling `signal` de-opted the\n * whole route to client rendering (the same SSR bailout the analytics\n * sibling-mount fixed) — the #1 recommendation of the 2026-07 perf audit.\n *\n * The core is NOT idle-deferred: experiment variants must apply as early as\n * possible, so it starts loading on hydration.\n */\n\n'use client'\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport dynamic from 'next/dynamic'\nimport type { SignalCoreApi, SignalCoreState } from './SignalCore'\nimport type {\n SignalConfig,\n SignalContextValue,\n SignalBridgeProps,\n SignalEvent,\n SignalOutcome,\n ExperimentAssignment,\n} from './types'\n\n// Heavy machinery — loaded client-side only, never wraps content.\nimport { publishSignal, resetSignal, useSignal } from './store'\n\nconst LazySignalCore = dynamic(\n () => import('./SignalCore').then(m => ({ default: m.SignalCore })),\n { ssr: false },\n)\n\n// ============================================\n// Context\n// ============================================\n\n// 4.0: the context is gone. useSignal() reads the module store, so consumers\n// work anywhere in the tree and SignalBridge mounts as a childless sibling.\nexport { useSignal } from './store'\n\n// ============================================\n// SignalBridge Component (shell)\n// ============================================\n\nexport function SignalBridge({\n enabled = true,\n realtime = true,\n experiments = true,\n behaviorTracking = true,\n visitorId: externalVisitorId,\n sessionId: externalSessionId,\n pageMetadataRef,\n children,\n}: SignalBridgeProps) {\n const [config, setConfig] = useState<SignalConfig | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n\n const coreRef = useRef<SignalCoreApi | null>(null)\n // Calls made before the core chunk loads are buffered here and drained on\n // registration — consumers can call trackEvent/trackOutcome from first render.\n const pendingEventsRef = useRef<Partial<SignalEvent>[]>([])\n const pendingOutcomesRef = useRef<SignalOutcome[]>([])\n\n const handleState = useCallback((state: SignalCoreState) => {\n setConfig(state.config)\n setLoading(state.loading)\n setError(state.error)\n }, [])\n\n const handleRegister = useCallback((api: SignalCoreApi | null) => {\n coreRef.current = api\n if (api) {\n pendingEventsRef.current.splice(0).forEach(event => api.trackEvent(event))\n pendingOutcomesRef.current.splice(0).forEach(outcome => api.trackOutcome(outcome))\n }\n }, [])\n\n const trackEvent = useCallback((event: Partial<SignalEvent>) => {\n if (coreRef.current) {\n coreRef.current.trackEvent(event)\n } else {\n pendingEventsRef.current.push(event)\n }\n }, [])\n\n const trackOutcome = useCallback((outcome: SignalOutcome) => {\n if (coreRef.current) {\n coreRef.current.trackOutcome(outcome)\n } else {\n pendingOutcomesRef.current.push(outcome)\n }\n }, [])\n\n const getExperiment = useCallback((experimentId: string): ExperimentAssignment | null => {\n // null before the core loads — identical to the pre-config-fetch behavior\n // consumers already handle via `loading`.\n return coreRef.current?.getExperiment(experimentId) ?? null\n }, [])\n\n const refreshConfig = useCallback(async () => {\n await coreRef.current?.refreshConfig()\n }, [])\n\n const contextValue = useMemo<SignalContextValue>(() => ({\n config,\n loading,\n error,\n trackEvent,\n trackOutcome,\n getExperiment,\n refreshConfig,\n }), [config, loading, error, trackEvent, trackOutcome, getExperiment, refreshConfig])\n\n // Publish to the module store (drains pre-mount buffered calls on first\n // publish); reset on unmount so tests/HMR start clean.\n useEffect(() => {\n publishSignal(contextValue)\n }, [contextValue])\n useEffect(() => () => resetSignal(), [])\n\n return (\n <>\n {children}\n {enabled && (\n <LazySignalCore\n enabled={enabled}\n realtime={realtime}\n experiments={experiments}\n behaviorTracking={behaviorTracking}\n externalVisitorId={externalVisitorId}\n externalSessionId={externalSessionId}\n pageMetadataRef={pageMetadataRef}\n onRegister={handleRegister}\n onState={handleState}\n />\n )}\n </>\n )\n}\n\n// ============================================\n// Convenience Hooks\n// ============================================\n\n/**\n * Hook to access Signal config\n */\nexport function useSignalConfig(): SignalConfig | null {\n const { config } = useSignal()\n return config\n}\n\n/**\n * Hook for tracking events\n */\nexport function useSignalEvent() {\n const { trackEvent } = useSignal()\n return trackEvent\n}\n\n/**\n * Hook for tracking outcomes/conversions\n */\nexport function useSignalOutcome() {\n const { trackOutcome } = useSignal()\n return { trackOutcome }\n}\n\n/**\n * Hook for experiment assignment\n */\nexport function useSignalExperiment(experimentId: string): {\n assignment: ExperimentAssignment | null\n variant: string | null\n isControl: boolean\n} {\n const { getExperiment, config } = useSignal()\n const assignment = getExperiment(experimentId)\n\n // Check if experiment is running\n const experiment = config?.experiments?.find(e => e.id === experimentId)\n const isRunning = experiment?.status === 'running'\n\n return {\n assignment: isRunning ? assignment : null,\n variant: isRunning && assignment ? assignment.variant_key : null,\n isControl: !assignment || assignment.variant_key === 'control',\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/signal/store.ts","../src/signal/SignalBridge.tsx"],"names":["useSyncExternalStore","dynamic","useState","useRef","useCallback","useMemo","useEffect","jsxs","Fragment","jsx"],"mappings":"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","file":"chunk-G2KGHIAP.js","sourcesContent":["'use client'\n\n/**\n * Signal store — module singleton behind useSignal().\n *\n * 4.0: SignalBridge no longer wraps page children in a React context; it\n * mounts as a childless sibling and publishes its API here. useSignal()\n * subscribes via useSyncExternalStore, so consumers work anywhere in the\n * tree — and BEFORE the bridge mounts, they get a buffering stub whose\n * trackEvent/trackOutcome queue calls that the bridge drains on publish.\n * getExperiment returns null pre-publish, identical to the pre-config\n * `loading` window consumers already handle.\n *\n * Behavior change vs 3.x (major): useSignal() no longer throws outside a\n * SignalBridge. With signal disabled it stays a bounded no-op stub — a\n * one-time debug warning fires instead of a crash.\n */\n\nimport { useSyncExternalStore } from 'react'\nimport type {\n SignalContextValue,\n SignalEvent,\n SignalOutcome,\n} from './types'\n\nconst pendingEvents: Partial<SignalEvent>[] = []\nconst pendingOutcomes: SignalOutcome[] = []\nconst MAX_PENDING = 100\nlet warnedNoBridge = false\n\n/** Frozen pre-bridge stub — stable reference (useSyncExternalStore requirement). */\nconst STUB: SignalContextValue = Object.freeze({\n config: null,\n loading: true,\n error: null,\n trackEvent: (event: Partial<SignalEvent>) => {\n if (pendingEvents.length < MAX_PENDING) pendingEvents.push(event)\n else if (!warnedNoBridge) {\n warnedNoBridge = true\n console.warn('[site-kit] Signal events are queuing but no SignalBridge has mounted — is signal enabled on SiteKitLayout?')\n }\n },\n trackOutcome: (outcome: SignalOutcome) => {\n if (pendingOutcomes.length < MAX_PENDING) pendingOutcomes.push(outcome)\n },\n getExperiment: () => null,\n refreshConfig: async () => {},\n})\n\nlet current: SignalContextValue = STUB\nconst listeners = new Set<() => void>()\n\nfunction emit() {\n for (const l of listeners) l()\n}\n\n/** Bridge-side: publish the live API (called whenever its value changes). */\nexport function publishSignal(value: SignalContextValue): void {\n const firstPublish = current === STUB\n current = value\n if (firstPublish) {\n // Drain calls made before the bridge mounted. The bridge's own trackEvent\n // buffers again internally until SignalCore loads, so nothing is lost.\n pendingEvents.splice(0).forEach(e => value.trackEvent(e))\n pendingOutcomes.splice(0).forEach(o => value.trackOutcome(o))\n }\n emit()\n}\n\n/** Bridge-side: reset on unmount so a remount starts clean (tests, HMR). */\nexport function resetSignal(): void {\n current = STUB\n emit()\n}\n\nfunction subscribe(onChange: () => void) {\n listeners.add(onChange)\n return () => listeners.delete(onChange)\n}\n\nconst getSnapshot = () => current\nconst getServerSnapshot = () => STUB\n\n/**\n * Access Signal (experiments, behavioral events) from anywhere in the tree.\n * No provider required — see module docs for pre-mount buffering semantics.\n */\nexport function useSignal(): SignalContextValue {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n}\n","/**\n * @sonordev/site-kit/signal - SignalBridge\n *\n * Central coordination layer for Signal AI integration.\n *\n * Architecture (2026-07 perf release): SignalBridge is a tiny SSR-SAFE context shell. It\n * renders {children} immediately — children server-render and hydrate\n * normally, no ssr:false wrapper — and lazy-loads the heavy machinery\n * (SignalCore: config fetch, SSE streaming, experiment assignment, event\n * queue, behavior tracking) as a CHILDLESS sibling. The core registers its\n * imperative API into the shell on mount; `trackEvent`/`trackOutcome` calls\n * made before the core is ready are buffered and drained on registration.\n *\n * This removes the old failure mode where enabling `signal` de-opted the\n * whole route to client rendering (the same SSR bailout the analytics\n * sibling-mount fixed) — the #1 recommendation of the 2026-07 perf audit.\n *\n * The core is NOT idle-deferred: experiment variants must apply as early as\n * possible, so it starts loading on hydration.\n */\n\n'use client'\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport dynamic from 'next/dynamic'\nimport type { SignalCoreApi, SignalCoreState } from './SignalCore'\nimport type {\n SignalConfig,\n SignalContextValue,\n SignalBridgeProps,\n SignalEvent,\n SignalOutcome,\n ExperimentAssignment,\n} from './types'\n\n// Heavy machinery — loaded client-side only, never wraps content.\nimport { publishSignal, resetSignal, useSignal } from './store'\n\nconst LazySignalCore = dynamic(\n () => import('./SignalCore').then(m => ({ default: m.SignalCore })),\n { ssr: false },\n)\n\n// ============================================\n// Context\n// ============================================\n\n// 4.0: the context is gone. useSignal() reads the module store, so consumers\n// work anywhere in the tree and SignalBridge mounts as a childless sibling.\nexport { useSignal } from './store'\n\n// ============================================\n// SignalBridge Component (shell)\n// ============================================\n\nexport function SignalBridge({\n enabled = true,\n realtime = true,\n experiments = true,\n behaviorTracking = true,\n visitorId: externalVisitorId,\n sessionId: externalSessionId,\n pageMetadataRef,\n children,\n}: SignalBridgeProps) {\n const [config, setConfig] = useState<SignalConfig | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n\n const coreRef = useRef<SignalCoreApi | null>(null)\n // Calls made before the core chunk loads are buffered here and drained on\n // registration — consumers can call trackEvent/trackOutcome from first render.\n const pendingEventsRef = useRef<Partial<SignalEvent>[]>([])\n const pendingOutcomesRef = useRef<SignalOutcome[]>([])\n\n const handleState = useCallback((state: SignalCoreState) => {\n setConfig(state.config)\n setLoading(state.loading)\n setError(state.error)\n }, [])\n\n const handleRegister = useCallback((api: SignalCoreApi | null) => {\n coreRef.current = api\n if (api) {\n pendingEventsRef.current.splice(0).forEach(event => api.trackEvent(event))\n pendingOutcomesRef.current.splice(0).forEach(outcome => api.trackOutcome(outcome))\n }\n }, [])\n\n const trackEvent = useCallback((event: Partial<SignalEvent>) => {\n if (coreRef.current) {\n coreRef.current.trackEvent(event)\n } else {\n pendingEventsRef.current.push(event)\n }\n }, [])\n\n const trackOutcome = useCallback((outcome: SignalOutcome) => {\n if (coreRef.current) {\n coreRef.current.trackOutcome(outcome)\n } else {\n pendingOutcomesRef.current.push(outcome)\n }\n }, [])\n\n const getExperiment = useCallback((experimentId: string): ExperimentAssignment | null => {\n // null before the core loads — identical to the pre-config-fetch behavior\n // consumers already handle via `loading`.\n return coreRef.current?.getExperiment(experimentId) ?? null\n }, [])\n\n const refreshConfig = useCallback(async () => {\n await coreRef.current?.refreshConfig()\n }, [])\n\n const contextValue = useMemo<SignalContextValue>(() => ({\n config,\n loading,\n error,\n trackEvent,\n trackOutcome,\n getExperiment,\n refreshConfig,\n }), [config, loading, error, trackEvent, trackOutcome, getExperiment, refreshConfig])\n\n // Publish to the module store (drains pre-mount buffered calls on first\n // publish); reset on unmount so tests/HMR start clean.\n useEffect(() => {\n publishSignal(contextValue)\n }, [contextValue])\n useEffect(() => () => resetSignal(), [])\n\n return (\n <>\n {children}\n {enabled && (\n <LazySignalCore\n enabled={enabled}\n realtime={realtime}\n experiments={experiments}\n behaviorTracking={behaviorTracking}\n externalVisitorId={externalVisitorId}\n externalSessionId={externalSessionId}\n pageMetadataRef={pageMetadataRef}\n onRegister={handleRegister}\n onState={handleState}\n />\n )}\n </>\n )\n}\n\n// ============================================\n// Convenience Hooks\n// ============================================\n\n/**\n * Hook to access Signal config\n */\nexport function useSignalConfig(): SignalConfig | null {\n const { config } = useSignal()\n return config\n}\n\n/**\n * Hook for tracking events\n */\nexport function useSignalEvent() {\n const { trackEvent } = useSignal()\n return trackEvent\n}\n\n/**\n * Hook for tracking outcomes/conversions\n */\nexport function useSignalOutcome() {\n const { trackOutcome } = useSignal()\n return { trackOutcome }\n}\n\n/**\n * Hook for experiment assignment\n */\nexport function useSignalExperiment(experimentId: string): {\n assignment: ExperimentAssignment | null\n variant: string | null\n isControl: boolean\n} {\n const { getExperiment, config } = useSignal()\n const assignment = getExperiment(experimentId)\n\n // Check if experiment is running\n const experiment = config?.experiments?.find(e => e.id === experimentId)\n const isRunning = experiment?.status === 'running'\n\n return {\n assignment: isRunning ? assignment : null,\n variant: isRunning && assignment ? assignment.variant_key : null,\n isControl: !assignment || assignment.variant_key === 'control',\n }\n}\n"]}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { resolvePublicationUrl, createPublicationRoutes } from './chunk-6C47333H.mjs';
|
|
2
|
+
|
|
3
|
+
// src/articles/artwork.ts
|
|
4
|
+
function resolveArticleArtwork(post, placement = "card") {
|
|
5
|
+
const editorial = placement === "article" && !!post.editorial_image;
|
|
6
|
+
const src = (editorial ? post.editorial_image : post.featured_image) || void 0;
|
|
7
|
+
const alt = editorial ? post.editorial_image_alt ?? "" : post.featured_image_alt ?? post.title ?? "";
|
|
8
|
+
let composed = false;
|
|
9
|
+
if (src) {
|
|
10
|
+
try {
|
|
11
|
+
composed = /\/Blog\/Cards\//i.test(new URL(src, "https://site-kit.invalid").pathname);
|
|
12
|
+
} catch {
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return { src, alt, composed };
|
|
16
|
+
}
|
|
17
|
+
function articleArtworkImageStyle(artwork) {
|
|
18
|
+
return artwork.composed ? { display: "block", height: "auto", maxHeight: "none", objectFit: "contain", transform: "none" } : void 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/articles/author-schema.ts
|
|
22
|
+
var ARTICLE_TYPES = /* @__PURE__ */ new Set(["Article", "BlogPosting", "NewsArticle", "TechArticle", "Report", "ScholarlyArticle"]);
|
|
23
|
+
function isAbsoluteUrl(value) {
|
|
24
|
+
return /^https?:\/\//i.test(value);
|
|
25
|
+
}
|
|
26
|
+
function routedAuthorPageUrl(author, options) {
|
|
27
|
+
return resolvePublicationUrl(createPublicationRoutes(options).author(author.slug), options.siteUrl ?? "");
|
|
28
|
+
}
|
|
29
|
+
function authorProfileUrl(author, options) {
|
|
30
|
+
return author.author_page_url?.trim() || routedAuthorPageUrl(author, options);
|
|
31
|
+
}
|
|
32
|
+
function authorEntityId(author, profileUrl) {
|
|
33
|
+
const explicit = author.entity_id?.trim();
|
|
34
|
+
if (explicit) return explicit;
|
|
35
|
+
if (!profileUrl || !isAbsoluteUrl(profileUrl)) return void 0;
|
|
36
|
+
return `${profileUrl.replace(/#.*$/, "")}#person`;
|
|
37
|
+
}
|
|
38
|
+
function generateAuthorPersonSchema(author, options = {}) {
|
|
39
|
+
const { siteUrl, siteName } = options;
|
|
40
|
+
const sameAs = [...author.same_as || []];
|
|
41
|
+
if (author.linkedin_url) sameAs.push(author.linkedin_url);
|
|
42
|
+
if (author.twitter_url) sameAs.push(author.twitter_url);
|
|
43
|
+
if (author.website_url) sameAs.push(author.website_url);
|
|
44
|
+
if (author.social_links?.twitter) sameAs.push(`https://twitter.com/${author.social_links.twitter}`);
|
|
45
|
+
if (author.social_links?.linkedin) sameAs.push(author.social_links.linkedin);
|
|
46
|
+
if (author.social_links?.github) sameAs.push(`https://github.com/${author.social_links.github}`);
|
|
47
|
+
const uniqueSameAs = [...new Set(sameAs.filter(Boolean))];
|
|
48
|
+
const url = authorProfileUrl(author, options);
|
|
49
|
+
const id = authorEntityId(author, url);
|
|
50
|
+
const person = {
|
|
51
|
+
"@type": "Person",
|
|
52
|
+
...id ? { "@id": id } : {},
|
|
53
|
+
name: author.name,
|
|
54
|
+
url
|
|
55
|
+
};
|
|
56
|
+
if (author.title) person.jobTitle = author.title;
|
|
57
|
+
if (author.company || siteName) {
|
|
58
|
+
person.worksFor = {
|
|
59
|
+
"@type": "Organization",
|
|
60
|
+
name: author.company || siteName,
|
|
61
|
+
...siteUrl ? { url: siteUrl } : {}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (author.bio || author.short_bio) person.description = author.short_bio || author.bio;
|
|
65
|
+
if (author.avatar_url) person.image = author.avatar_url;
|
|
66
|
+
if (uniqueSameAs.length > 0) person.sameAs = uniqueSameAs;
|
|
67
|
+
if (author.knows_about && author.knows_about.length > 0) person.knowsAbout = author.knows_about;
|
|
68
|
+
if (author.credentials && author.credentials.length > 0) {
|
|
69
|
+
person.hasCredential = author.credentials.map((c) => ({
|
|
70
|
+
"@type": "EducationalOccupationalCredential",
|
|
71
|
+
credentialCategory: c
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
return person;
|
|
75
|
+
}
|
|
76
|
+
function generateAuthorSchema(author, options = {}) {
|
|
77
|
+
const pageUrl = routedAuthorPageUrl(author, options);
|
|
78
|
+
const schema = {
|
|
79
|
+
"@context": "https://schema.org",
|
|
80
|
+
"@type": "ProfilePage",
|
|
81
|
+
...isAbsoluteUrl(pageUrl) ? { "@id": `${pageUrl}#profilepage` } : {},
|
|
82
|
+
url: pageUrl,
|
|
83
|
+
name: author.name,
|
|
84
|
+
mainEntity: generateAuthorPersonSchema(author, options)
|
|
85
|
+
};
|
|
86
|
+
if (author.created_at) schema.dateCreated = author.created_at;
|
|
87
|
+
if (author.updated_at) schema.dateModified = author.updated_at;
|
|
88
|
+
return schema;
|
|
89
|
+
}
|
|
90
|
+
function generateArticleAuthorNode(author, options = {}) {
|
|
91
|
+
if (!author) return void 0;
|
|
92
|
+
if (typeof author === "string") {
|
|
93
|
+
const name = author.trim();
|
|
94
|
+
return name ? { "@type": "Person", name } : void 0;
|
|
95
|
+
}
|
|
96
|
+
if (!author.name) return void 0;
|
|
97
|
+
const url = author.author_page_url?.trim() || (options.authorPages && author.slug ? routedAuthorPageUrl(author, options) : void 0);
|
|
98
|
+
const id = authorEntityId(author, url);
|
|
99
|
+
return {
|
|
100
|
+
"@type": "Person",
|
|
101
|
+
...id ? { "@id": id } : {},
|
|
102
|
+
name: author.name,
|
|
103
|
+
...url ? { url } : {}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function withArticleAuthorIdentity(node, author, options = {}) {
|
|
107
|
+
if (!node || typeof node !== "object" || Array.isArray(node)) return node;
|
|
108
|
+
const record = node;
|
|
109
|
+
const types = [].concat(record["@type"]);
|
|
110
|
+
if (!types.some((t) => typeof t === "string" && ARTICLE_TYPES.has(t))) return node;
|
|
111
|
+
const stored = record.author;
|
|
112
|
+
if (!stored || typeof stored !== "object" || Array.isArray(stored)) return node;
|
|
113
|
+
const byline = stored;
|
|
114
|
+
if (byline["@type"] !== "Person" || typeof byline.name !== "string") return node;
|
|
115
|
+
const identity = generateArticleAuthorNode(author, options);
|
|
116
|
+
if (!identity || typeof identity.name !== "string") return node;
|
|
117
|
+
if (identity.name.trim().toLowerCase() !== byline.name.trim().toLowerCase()) return node;
|
|
118
|
+
const additions = {};
|
|
119
|
+
if (!byline["@id"] && identity["@id"]) additions["@id"] = identity["@id"];
|
|
120
|
+
if (!byline.url && identity.url) additions.url = identity.url;
|
|
121
|
+
if (Object.keys(additions).length === 0) return node;
|
|
122
|
+
return { ...record, author: { ...byline, ...additions } };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export { articleArtworkImageStyle, authorEntityId, generateArticleAuthorNode, generateAuthorPersonSchema, generateAuthorSchema, resolveArticleArtwork, withArticleAuthorIdentity };
|
|
126
|
+
//# sourceMappingURL=chunk-GFSQMK35.mjs.map
|
|
127
|
+
//# sourceMappingURL=chunk-GFSQMK35.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/articles/artwork.ts","../src/articles/author-schema.ts"],"names":[],"mappings":"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","file":"chunk-GFSQMK35.mjs","sourcesContent":["import type { CSSProperties } from 'react'\nimport type { Article } from './types'\n\nexport interface ArticleArtwork {\n src: string | undefined\n alt: string\n composed: boolean\n}\n\ntype ArtworkSource = Pick<Article, 'title' | 'featured_image' | 'featured_image_alt' | 'editorial_image' | 'editorial_image_alt'>\n\n/** Single source of truth for article artwork versus complete promotional cards. */\nexport function resolveArticleArtwork(post: ArtworkSource, placement: 'article' | 'card' = 'card'): ArticleArtwork {\n const editorial = placement === 'article' && !!post.editorial_image\n const src = (editorial ? post.editorial_image : post.featured_image) || undefined\n const alt = editorial\n ? post.editorial_image_alt ?? ''\n : post.featured_image_alt ?? post.title ?? ''\n let composed = false\n if (src) {\n try {\n // Inspect the path, not a query string that happens to mention a card.\n // `Blog/Cards/` is the storage folder Sonor writes cards to (a path, not a name).\n composed = /\\/Blog\\/Cards\\//i.test(new URL(src, 'https://site-kit.invalid').pathname)\n } catch { /* An unrecognized source retains the normal photograph layout. */ }\n }\n return { src, alt, composed }\n}\n\n/** Preserve generated text and graphics across every stock card surface. */\nexport function articleArtworkImageStyle(artwork: ArticleArtwork): CSSProperties | undefined {\n return artwork.composed\n ? { display: 'block', height: 'auto', maxHeight: 'none', objectFit: 'contain', transform: 'none' }\n : undefined\n}\n","/**\n * @sonordev/site-kit/articles — Author JSON-LD (pure)\n *\n * Split out of `./server-core` on purpose. Everything here is a pure function:\n * it maps an `ArticleAuthor` to schema objects and touches no env, no config,\n * and no network. It only ever lived in `server-core` because the other author\n * helpers there (`getAuthorBySlug`, `getAuthorPosts`) do fetch.\n *\n * `AuthorPage` is exported from the client-stamped `@sonordev/site-kit/articles`\n * barrel (see `./index.ts`), so importing these from `server-core` dragged that\n * whole server module — its `x-api-key` fetches included — into the browser\n * bundle. Keeping the pure half here means `AuthorPage` can stay in the barrel\n * without pulling a single line of server code with it.\n *\n * Anything added here must stay pure. If it needs an API key or a fetch, it\n * belongs in `./server-core`, not in this file.\n *\n * Identity model (single source of truth for every author node the kit emits):\n * - The author page is a `ProfilePage` whose `mainEntity` is the `Person`\n * (Google's profile-page markup for author pages).\n * - The `Person` carries one `@id` everywhere it appears (`authorEntityId`):\n * the row's `entity_id` when the person has a cross-site identity (e.g.\n * https://ramseydeal.com/#person), else `<author profile URL>#person`.\n * - Article bylines (`generateArticleAuthorNode`) reference that same `@id`,\n * so an article, its author page and the person's own site describe one\n * person, which is what a Knowledge Panel is built from.\n */\n\nimport type { ArticleAuthor } from './types'\nimport { createPublicationRoutes, resolvePublicationUrl, type PublicationRoutingOptions } from './routes'\n\nexport type AuthorSchemaOptions = PublicationRoutingOptions & { siteUrl?: string; siteName?: string }\n\nconst ARTICLE_TYPES = new Set(['Article', 'BlogPosting', 'NewsArticle', 'TechArticle', 'Report', 'ScholarlyArticle'])\n\nfunction isAbsoluteUrl(value: string): boolean {\n return /^https?:\\/\\//i.test(value)\n}\n\n/** This site's page for the author, the page `AuthorPage` renders. */\nfunction routedAuthorPageUrl(author: Pick<ArticleAuthor, 'slug'>, options: AuthorSchemaOptions): string {\n return resolvePublicationUrl(createPublicationRoutes(options).author(author.slug), options.siteUrl ?? '')\n}\n\n/** Where the Person points `url`: the row's canonical author page, else this site's. */\nfunction authorProfileUrl(author: Pick<ArticleAuthor, 'slug' | 'author_page_url'>, options: AuthorSchemaOptions): string {\n return author.author_page_url?.trim() || routedAuthorPageUrl(author, options)\n}\n\n/**\n * Single source of truth for an author's Person `@id`.\n *\n * The row's `entity_id` (one id shared by every site that describes the\n * person) wins. Otherwise the Person lives at `<profile URL>#person`. A\n * relative profile URL gives no `@id`: an id must be absolute to mean the\n * same thing on every page.\n */\nexport function authorEntityId(\n author: Pick<ArticleAuthor, 'entity_id'>,\n profileUrl?: string,\n): string | undefined {\n const explicit = author.entity_id?.trim()\n if (explicit) return explicit\n if (!profileUrl || !isAbsoluteUrl(profileUrl)) return undefined\n return `${profileUrl.replace(/#.*$/, '')}#person`\n}\n\n/**\n * The bare `Person` for an author, with no `@context`, for embedding in a\n * larger graph (an Organization's `founder`, an `@graph` array). Author pages\n * want `generateAuthorSchema`, which wraps this in a `ProfilePage`.\n */\nexport function generateAuthorPersonSchema(\n author: ArticleAuthor,\n options: AuthorSchemaOptions = {},\n): Record<string, unknown> {\n const { siteUrl, siteName } = options\n\n const sameAs: string[] = [...(author.same_as || [])]\n if (author.linkedin_url) sameAs.push(author.linkedin_url)\n if (author.twitter_url) sameAs.push(author.twitter_url)\n if (author.website_url) sameAs.push(author.website_url)\n if (author.social_links?.twitter) sameAs.push(`https://twitter.com/${author.social_links.twitter}`)\n if (author.social_links?.linkedin) sameAs.push(author.social_links.linkedin)\n if (author.social_links?.github) sameAs.push(`https://github.com/${author.social_links.github}`)\n\n // Deduplicate\n const uniqueSameAs = [...new Set(sameAs.filter(Boolean))]\n\n const url = authorProfileUrl(author, options)\n const id = authorEntityId(author, url)\n\n const person: Record<string, any> = {\n '@type': 'Person',\n ...(id ? { '@id': id } : {}),\n name: author.name,\n url,\n }\n\n if (author.title) person.jobTitle = author.title\n if (author.company || siteName) {\n person.worksFor = {\n '@type': 'Organization',\n name: author.company || siteName,\n ...(siteUrl ? { url: siteUrl } : {}),\n }\n }\n if (author.bio || author.short_bio) person.description = author.short_bio || author.bio\n if (author.avatar_url) person.image = author.avatar_url\n if (uniqueSameAs.length > 0) person.sameAs = uniqueSameAs\n if (author.knows_about && author.knows_about.length > 0) person.knowsAbout = author.knows_about\n if (author.credentials && author.credentials.length > 0) {\n person.hasCredential = author.credentials.map((c) => ({\n '@type': 'EducationalOccupationalCredential',\n credentialCategory: c,\n }))\n }\n\n return person\n}\n\n/**\n * JSON-LD for an author page: a `ProfilePage` whose `mainEntity` is the\n * author's `Person`. Render it once per author page (`AuthorPage` does, unless\n * its `jsonLd` prop is false).\n */\nexport function generateAuthorSchema(\n author: ArticleAuthor,\n options: AuthorSchemaOptions = {},\n): object {\n const pageUrl = routedAuthorPageUrl(author, options)\n\n const schema: Record<string, any> = {\n '@context': 'https://schema.org',\n '@type': 'ProfilePage',\n ...(isAbsoluteUrl(pageUrl) ? { '@id': `${pageUrl}#profilepage` } : {}),\n url: pageUrl,\n name: author.name,\n mainEntity: generateAuthorPersonSchema(author, options),\n }\n if (author.created_at) schema.dateCreated = author.created_at\n if (author.updated_at) schema.dateModified = author.updated_at\n\n return schema\n}\n\n/**\n * The `author` node for article JSON-LD. Single source of truth for bylines:\n * generateArticleSchema, generateClusterArticleSchema and stored schema_json\n * (via withArticleAuthorIdentity) all route through here.\n *\n * Links to an author page only when one is known to exist: the row's\n * `author_page_url`, or the site declaring `authorPages` in its routing. A\n * bare string byline stays a named Person.\n */\nexport function generateArticleAuthorNode(\n author: ArticleAuthor | string | null | undefined,\n options: AuthorSchemaOptions = {},\n): Record<string, unknown> | undefined {\n if (!author) return undefined\n if (typeof author === 'string') {\n const name = author.trim()\n return name ? { '@type': 'Person', name } : undefined\n }\n if (!author.name) return undefined\n\n const url =\n author.author_page_url?.trim() ||\n (options.authorPages && author.slug ? routedAuthorPageUrl(author, options) : undefined)\n const id = authorEntityId(author, url)\n\n return {\n '@type': 'Person',\n ...(id ? { '@id': id } : {}),\n name: author.name,\n ...(url ? { url } : {}),\n }\n}\n\n/**\n * Attach the author's identity to an article node from stored schema_json\n * (built by Signal at publish time, frozen in the row). Adds `@id` and `url`\n * from generateArticleAuthorNode when the stored byline is a Person with the\n * same name and lacks them; stored values always win and nothing else in the\n * node changes. Non-article nodes pass through untouched.\n */\nexport function withArticleAuthorIdentity(\n node: unknown,\n author: ArticleAuthor | string | null | undefined,\n options: AuthorSchemaOptions = {},\n): unknown {\n if (!node || typeof node !== 'object' || Array.isArray(node)) return node\n const record = node as Record<string, unknown>\n const types = ([] as unknown[]).concat(record['@type'])\n if (!types.some((t) => typeof t === 'string' && ARTICLE_TYPES.has(t))) return node\n\n const stored = record.author\n if (!stored || typeof stored !== 'object' || Array.isArray(stored)) return node\n const byline = stored as Record<string, unknown>\n if (byline['@type'] !== 'Person' || typeof byline.name !== 'string') return node\n\n const identity = generateArticleAuthorNode(author, options)\n if (!identity || typeof identity.name !== 'string') return node\n if (identity.name.trim().toLowerCase() !== byline.name.trim().toLowerCase()) return node\n\n const additions: Record<string, unknown> = {}\n if (!byline['@id'] && identity['@id']) additions['@id'] = identity['@id']\n if (!byline.url && identity.url) additions.url = identity.url\n if (Object.keys(additions).length === 0) return node\n\n return { ...record, author: { ...byline, ...additions } }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/version.ts"],"names":[],"mappings":";AASO,IAAM,gBAAA,GAAmB","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/shared/version.ts"],"names":[],"mappings":";AASO,IAAM,gBAAA,GAAmB","file":"chunk-GIGUDKLS.mjs","sourcesContent":["/**\n * @sonordev/site-kit shared - Package version constant\n *\n * Single source of truth for the version the kit reports at runtime (the\n * x-sitekit-version request header set by sonorFetch). Kept as a plain const\n * so client bundles don't need JSON imports; scripts/verify-dts.cjs asserts\n * it matches package.json at publish time, and version.test.ts asserts it in\n * dev, so it can't silently drift.\n */\nexport const SITE_KIT_VERSION = '6.5.0'\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { linkClassificationHost } from './chunk-5YVQWLSQ.mjs';
|
|
2
|
-
import { resolveArticleUrl } from './chunk-
|
|
2
|
+
import { resolveArticleUrl } from './chunk-6C47333H.mjs';
|
|
3
3
|
import { freshFetch } from './chunk-BQP6JIE2.mjs';
|
|
4
4
|
import { LLM_GEO_CONTRACT_VERSION, sanitizePrimaryLanguageTag, sanitizeLlmsDisclaimerLine, sanitizeLlmsPublicSummary } from './chunk-PENNTSJE.mjs';
|
|
5
5
|
import { withSiteParam } from './chunk-AS2HUIDW.mjs';
|
|
@@ -757,5 +757,5 @@ function atomicWriteSync(filePath, content) {
|
|
|
757
757
|
}
|
|
758
758
|
|
|
759
759
|
export { generateLLMsFullTxt, generateLLMsTxt, getBusinessInfo, getFAQItems, getLLMsData, getOptimizedLLMsTxt, getPageSummaries, getServices, writeLLMsTxtToPublic };
|
|
760
|
-
//# sourceMappingURL=chunk-
|
|
761
|
-
//# sourceMappingURL=chunk-
|
|
760
|
+
//# sourceMappingURL=chunk-H4TSADY3.mjs.map
|
|
761
|
+
//# sourceMappingURL=chunk-H4TSADY3.mjs.map
|