@salla.sa/twilight-theme-engine 1.0.149 → 1.0.150
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/dist/{AddToCartForm-NMHCW3UT.js → AddToCartForm-P5Q4P763.js} +3 -3
- package/dist/{AddToCartForm-NMHCW3UT.js.map → AddToCartForm-P5Q4P763.js.map} +1 -1
- package/dist/{BlogAuthorPage-2WTKZNOV.js → BlogAuthorPage-Z3R6AETN.js} +27 -27
- package/dist/{BlogAuthorPage-2WTKZNOV.js.map → BlogAuthorPage-Z3R6AETN.js.map} +1 -1
- package/dist/{BlogCategoryPage-SF3FJKUX.js → BlogCategoryPage-7VROFBGI.js} +27 -27
- package/dist/{BlogCategoryPage-SF3FJKUX.js.map → BlogCategoryPage-7VROFBGI.js.map} +1 -1
- package/dist/{BlogPage-LYB32QET.js → BlogPage-Q2NN4WTB.js} +25 -25
- package/dist/{BlogPage-LYB32QET.js.map → BlogPage-Q2NN4WTB.js.map} +1 -1
- package/dist/{BlogSinglePage-BLPEE6HL.js → BlogSinglePage-ZPCSNBIX.js} +25 -25
- package/dist/{BlogSinglePage-BLPEE6HL.js.map → BlogSinglePage-ZPCSNBIX.js.map} +1 -1
- package/dist/{BlogTagPage-D7QVEP5N.js → BlogTagPage-IGG2VEMR.js} +27 -27
- package/dist/{BlogTagPage-D7QVEP5N.js.map → BlogTagPage-IGG2VEMR.js.map} +1 -1
- package/dist/{BrandsPage-7C5IPCVT.js → BrandsPage-ZAJT6RGM.js} +26 -26
- package/dist/{BrandsPage-7C5IPCVT.js.map → BrandsPage-ZAJT6RGM.js.map} +1 -1
- package/dist/{Breadcrumb-WMXQ3SI3.js → Breadcrumb-KE4EWH7L.js} +25 -25
- package/dist/{Breadcrumb-WMXQ3SI3.js.map → Breadcrumb-KE4EWH7L.js.map} +1 -1
- package/dist/{CartItem-BBC25XRJ.js → CartItem-RMCXCGHT.js} +25 -25
- package/dist/{CartItem-BBC25XRJ.js.map → CartItem-RMCXCGHT.js.map} +1 -1
- package/dist/{CartSummary-6QADXXET.js → CartSummary-NLEAHKWF.js} +25 -25
- package/dist/{CartSummary-6QADXXET.js.map → CartSummary-NLEAHKWF.js.map} +1 -1
- package/dist/{Copyright-GFBOKME6.js → Copyright-EIBPTE3B.js} +3 -3
- package/dist/{Copyright-GFBOKME6.js.map → Copyright-EIBPTE3B.js.map} +1 -1
- package/dist/{CustomerLayout-4LOPQ7HW.js → CustomerLayout-POGWFN6R.js} +25 -25
- package/dist/{CustomerLayout-4LOPQ7HW.js.map → CustomerLayout-POGWFN6R.js.map} +1 -1
- package/dist/{Footer-HATEFXZP.js → Footer-LGIUINGS.js} +4 -4
- package/dist/{Footer-HATEFXZP.js.map → Footer-LGIUINGS.js.map} +1 -1
- package/dist/{Header-R2VM5EFR.js → Header-4TGYO6E4.js} +11 -11
- package/dist/{Header-R2VM5EFR.js.map → Header-4TGYO6E4.js.map} +1 -1
- package/dist/{LatestProducts-IOYD7Y4Z.js → LatestProducts-YYKQNL5N.js} +27 -27
- package/dist/{LatestProducts-IOYD7Y4Z.js.map → LatestProducts-YYKQNL5N.js.map} +1 -1
- package/dist/{LoyaltyPage-2JPXJ3DB.js → LoyaltyPage-MROFMZXV.js} +25 -25
- package/dist/{LoyaltyPage-2JPXJ3DB.js.map → LoyaltyPage-MROFMZXV.js.map} +1 -1
- package/dist/{LoyaltyPointsPage-B7EALH4Z.js → LoyaltyPointsPage-DVHJOAKP.js} +8 -8
- package/dist/{LoyaltyPointsPage-B7EALH4Z.js.map → LoyaltyPointsPage-DVHJOAKP.js.map} +1 -1
- package/dist/{MainMenu-BGVWE6TJ.js → MainMenu-GQO5KOTU.js} +7 -7
- package/dist/{MainMenu-BGVWE6TJ.js.map → MainMenu-GQO5KOTU.js.map} +1 -1
- package/dist/{MasterLayout-U33ZBIZO.js → MasterLayout-ZJBJ7EHM.js} +25 -25
- package/dist/{MasterLayout-U33ZBIZO.js.map → MasterLayout-ZJBJ7EHM.js.map} +1 -1
- package/dist/{MobileMenu-6OERFJSR.js → MobileMenu-TZSFYHPW.js} +26 -26
- package/dist/{MobileMenu-6OERFJSR.js.map → MobileMenu-TZSFYHPW.js.map} +1 -1
- package/dist/{NotificationsPage-YBFHEZYG.js → NotificationsPage-BX6OSIDY.js} +25 -25
- package/dist/{NotificationsPage-YBFHEZYG.js.map → NotificationsPage-BX6OSIDY.js.map} +1 -1
- package/dist/{OrderSinglePage-EPOX5KJG.js → OrderSinglePage-3RQ5TJDB.js} +26 -26
- package/dist/{OrderSinglePage-EPOX5KJG.js.map → OrderSinglePage-3RQ5TJDB.js.map} +1 -1
- package/dist/{OrdersPage-6RPTMFAL.js → OrdersPage-S4ECYNGI.js} +25 -25
- package/dist/{OrdersPage-6RPTMFAL.js.map → OrdersPage-S4ECYNGI.js.map} +1 -1
- package/dist/{PageSingle-CEFQDKOP.js → PageSingle-BZGDC4VE.js} +6 -6
- package/dist/{PageSingle-CEFQDKOP.js.map → PageSingle-BZGDC4VE.js.map} +1 -1
- package/dist/{ProductDetails-M6C6H3J4.js → ProductDetails-ZPRWPSVK.js} +7 -7
- package/dist/{ProductDetails-M6C6H3J4.js.map → ProductDetails-ZPRWPSVK.js.map} +1 -1
- package/dist/{ProfilePage-EJV2V46I.js → ProfilePage-SKAS6LFQ.js} +25 -25
- package/dist/{ProfilePage-EJV2V46I.js.map → ProfilePage-SKAS6LFQ.js.map} +1 -1
- package/dist/{ReviewsPage-5K4PEJVZ.js → ReviewsPage-NAZWXVXT.js} +3 -3
- package/dist/{ReviewsPage-5K4PEJVZ.js.map → ReviewsPage-NAZWXVXT.js.map} +1 -1
- package/dist/{SeoCartWidget-EQY6JIQR.js → SeoCartWidget-6NB6LT2Z.js} +25 -25
- package/dist/{SeoCartWidget-EQY6JIQR.js.map → SeoCartWidget-6NB6LT2Z.js.map} +1 -1
- package/dist/{SettingsPage-AXHVNXFO.js → SettingsPage-GZ2NJIUR.js} +25 -25
- package/dist/{SettingsPage-AXHVNXFO.js.map → SettingsPage-GZ2NJIUR.js.map} +1 -1
- package/dist/{StoreClosedNotification-W2ATH4WF.js → StoreClosedNotification-V72F7HE5.js} +26 -26
- package/dist/{StoreClosedNotification-W2ATH4WF.js.map → StoreClosedNotification-V72F7HE5.js.map} +1 -1
- package/dist/{TestimonialsPage-DYXOQOYG.js → TestimonialsPage-L6VBZFLT.js} +6 -6
- package/dist/{TestimonialsPage-DYXOQOYG.js.map → TestimonialsPage-L6VBZFLT.js.map} +1 -1
- package/dist/{ThankYouPage-NZVL7WLY.js → ThankYouPage-O5U3V6J4.js} +25 -25
- package/dist/{ThankYouPage-NZVL7WLY.js.map → ThankYouPage-O5U3V6J4.js.map} +1 -1
- package/dist/{WalletPage-6JUYGDBV.js → WalletPage-NJBBZIMM.js} +26 -26
- package/dist/{WalletPage-6JUYGDBV.js.map → WalletPage-NJBBZIMM.js.map} +1 -1
- package/dist/{WebMcpTools-5RGBTR7I.js → WebMcpTools-VAZH3S5G.js} +9 -9
- package/dist/{WebMcpTools-5RGBTR7I.js.map → WebMcpTools-VAZH3S5G.js.map} +1 -1
- package/dist/{WishlistPage-VVPNCLOP.js → WishlistPage-UKOGNFKB.js} +27 -27
- package/dist/{WishlistPage-VVPNCLOP.js.map → WishlistPage-UKOGNFKB.js.map} +1 -1
- package/dist/api/advertisement.js +4 -4
- package/dist/api/apps.js +4 -4
- package/dist/api/blog.js +6 -6
- package/dist/api/brands.js +6 -6
- package/dist/api/cart.js +6 -6
- package/dist/api/category.js +6 -6
- package/dist/api/client.js +3 -3
- package/dist/api/home.js +4 -4
- package/dist/api/loyalty.js +6 -6
- package/dist/api/menu.js +4 -4
- package/dist/api/notification.js +4 -4
- package/dist/api/order.js +6 -6
- package/dist/api/page.js +6 -6
- package/dist/api/product.js +6 -6
- package/dist/api/profile.js +3 -3
- package/dist/api/store.js +5 -5
- package/dist/api/translations.js +4 -4
- package/dist/api/user.js +4 -4
- package/dist/api/wallet.js +4 -4
- package/dist/api/wishlist.js +7 -7
- package/dist/{chunk-H2M2573Y.js → chunk-2CILV5ME.js} +5 -5
- package/dist/{chunk-H2M2573Y.js.map → chunk-2CILV5ME.js.map} +1 -1
- package/dist/{chunk-62IIZZPR.js → chunk-2HCODIC6.js} +4 -4
- package/dist/{chunk-62IIZZPR.js.map → chunk-2HCODIC6.js.map} +1 -1
- package/dist/{chunk-IQNTYZGF.js → chunk-2ZC5YGMI.js} +3 -3
- package/dist/{chunk-IQNTYZGF.js.map → chunk-2ZC5YGMI.js.map} +1 -1
- package/dist/{chunk-TJ3TISBF.js → chunk-34L65JGK.js} +4 -4
- package/dist/{chunk-TJ3TISBF.js.map → chunk-34L65JGK.js.map} +1 -1
- package/dist/{chunk-T2752RH7.js → chunk-4E6FD5W7.js} +60 -4
- package/dist/chunk-4E6FD5W7.js.map +1 -0
- package/dist/{chunk-M5WTY3EH.js → chunk-5EAISVPV.js} +3 -3
- package/dist/{chunk-M5WTY3EH.js.map → chunk-5EAISVPV.js.map} +1 -1
- package/dist/{chunk-E3Z3PQAP.js → chunk-5LI536P6.js} +5 -5
- package/dist/{chunk-E3Z3PQAP.js.map → chunk-5LI536P6.js.map} +1 -1
- package/dist/{chunk-6HUQL6WU.js → chunk-5M2AK5KE.js} +4 -4
- package/dist/{chunk-6HUQL6WU.js.map → chunk-5M2AK5KE.js.map} +1 -1
- package/dist/{chunk-EMNDPJRS.js → chunk-5NUCGUTE.js} +4 -4
- package/dist/{chunk-EMNDPJRS.js.map → chunk-5NUCGUTE.js.map} +1 -1
- package/dist/{chunk-CJTORCZE.js → chunk-5RBXCPG6.js} +3 -3
- package/dist/{chunk-CJTORCZE.js.map → chunk-5RBXCPG6.js.map} +1 -1
- package/dist/{chunk-MDZ7OUAW.js → chunk-5T4MJAUN.js} +3 -3
- package/dist/{chunk-MDZ7OUAW.js.map → chunk-5T4MJAUN.js.map} +1 -1
- package/dist/{chunk-4VDW24VN.js → chunk-6H6BVZBV.js} +3 -3
- package/dist/{chunk-4VDW24VN.js.map → chunk-6H6BVZBV.js.map} +1 -1
- package/dist/{chunk-D6OV66P2.js → chunk-6QIF6WJH.js} +3 -3
- package/dist/{chunk-D6OV66P2.js.map → chunk-6QIF6WJH.js.map} +1 -1
- package/dist/{chunk-SLBO4SEE.js → chunk-6YEE3VHL.js} +3 -3
- package/dist/{chunk-SLBO4SEE.js.map → chunk-6YEE3VHL.js.map} +1 -1
- package/dist/{chunk-XMRNYUQY.js → chunk-7XAGU6CT.js} +3 -3
- package/dist/{chunk-XMRNYUQY.js.map → chunk-7XAGU6CT.js.map} +1 -1
- package/dist/{chunk-SNTJYDYZ.js → chunk-AOQZHLZZ.js} +5 -5
- package/dist/{chunk-SNTJYDYZ.js.map → chunk-AOQZHLZZ.js.map} +1 -1
- package/dist/{chunk-H7LRGY7U.js → chunk-B57KIBQL.js} +3 -3
- package/dist/{chunk-H7LRGY7U.js.map → chunk-B57KIBQL.js.map} +1 -1
- package/dist/{chunk-QMIPHH5I.js → chunk-BYGVKW3M.js} +4 -4
- package/dist/{chunk-QMIPHH5I.js.map → chunk-BYGVKW3M.js.map} +1 -1
- package/dist/{chunk-5OMZ4GZ6.js → chunk-CAULDK3N.js} +6 -6
- package/dist/{chunk-5OMZ4GZ6.js.map → chunk-CAULDK3N.js.map} +1 -1
- package/dist/{chunk-EGI7F57E.js → chunk-DPQIVZ4T.js} +3 -3
- package/dist/{chunk-EGI7F57E.js.map → chunk-DPQIVZ4T.js.map} +1 -1
- package/dist/{chunk-HHJD2GGA.js → chunk-EMAAVDEK.js} +7 -7
- package/dist/{chunk-HHJD2GGA.js.map → chunk-EMAAVDEK.js.map} +1 -1
- package/dist/{chunk-LOXWQLSH.js → chunk-FCCGJ4DI.js} +7 -7
- package/dist/{chunk-LOXWQLSH.js.map → chunk-FCCGJ4DI.js.map} +1 -1
- package/dist/{chunk-IKCXJYYQ.js → chunk-FL3OK7AQ.js} +36 -16
- package/dist/chunk-FL3OK7AQ.js.map +1 -0
- package/dist/{chunk-DN3SKCOX.js → chunk-GLSRVHYJ.js} +4 -4
- package/dist/{chunk-DN3SKCOX.js.map → chunk-GLSRVHYJ.js.map} +1 -1
- package/dist/{chunk-2DM2EXRT.js → chunk-I2LK4IC2.js} +4 -4
- package/dist/{chunk-2DM2EXRT.js.map → chunk-I2LK4IC2.js.map} +1 -1
- package/dist/{chunk-ANVS7UYN.js → chunk-IEKP3HYS.js} +4 -4
- package/dist/{chunk-ANVS7UYN.js.map → chunk-IEKP3HYS.js.map} +1 -1
- package/dist/{chunk-IHOUADLX.js → chunk-JK45RUVV.js} +3 -3
- package/dist/{chunk-IHOUADLX.js.map → chunk-JK45RUVV.js.map} +1 -1
- package/dist/{chunk-ORLSTZ45.js → chunk-JSAWLWUN.js} +4 -4
- package/dist/{chunk-ORLSTZ45.js.map → chunk-JSAWLWUN.js.map} +1 -1
- package/dist/{chunk-ZN3RZJRX.js → chunk-KJ7NG3ZH.js} +3 -3
- package/dist/{chunk-ZN3RZJRX.js.map → chunk-KJ7NG3ZH.js.map} +1 -1
- package/dist/{chunk-VGZEPMXG.js → chunk-LBZNLTBM.js} +3 -3
- package/dist/{chunk-VGZEPMXG.js.map → chunk-LBZNLTBM.js.map} +1 -1
- package/dist/{chunk-5GMXXHV2.js → chunk-LWAJNEIM.js} +4 -4
- package/dist/{chunk-5GMXXHV2.js.map → chunk-LWAJNEIM.js.map} +1 -1
- package/dist/{chunk-4UGJ4VC3.js → chunk-O3XMYDNC.js} +5 -5
- package/dist/{chunk-4UGJ4VC3.js.map → chunk-O3XMYDNC.js.map} +1 -1
- package/dist/{chunk-2LXCSBJU.js → chunk-O63WBEAC.js} +22 -22
- package/dist/{chunk-2LXCSBJU.js.map → chunk-O63WBEAC.js.map} +1 -1
- package/dist/{chunk-WAVAK2RB.js → chunk-OOZQVX7C.js} +6 -6
- package/dist/{chunk-WAVAK2RB.js.map → chunk-OOZQVX7C.js.map} +1 -1
- package/dist/{chunk-MGG4XAJ5.js → chunk-P2PPBXHD.js} +3 -3
- package/dist/{chunk-MGG4XAJ5.js.map → chunk-P2PPBXHD.js.map} +1 -1
- package/dist/{chunk-KOR42MT5.js → chunk-PHPOMWQ4.js} +4 -4
- package/dist/{chunk-KOR42MT5.js.map → chunk-PHPOMWQ4.js.map} +1 -1
- package/dist/{chunk-MFTPNDEI.js → chunk-PPFD456V.js} +3 -3
- package/dist/{chunk-MFTPNDEI.js.map → chunk-PPFD456V.js.map} +1 -1
- package/dist/{chunk-NIPEIVU4.js → chunk-PVOJJ2BV.js} +5 -5
- package/dist/{chunk-NIPEIVU4.js.map → chunk-PVOJJ2BV.js.map} +1 -1
- package/dist/{chunk-A6Y33KCR.js → chunk-PYXAPLNB.js} +3 -3
- package/dist/{chunk-A6Y33KCR.js.map → chunk-PYXAPLNB.js.map} +1 -1
- package/dist/{chunk-WJVKBSKY.js → chunk-PZP3372I.js} +4 -4
- package/dist/{chunk-WJVKBSKY.js.map → chunk-PZP3372I.js.map} +1 -1
- package/dist/{chunk-TQEQECN7.js → chunk-Q7Z76F7N.js} +8 -8
- package/dist/{chunk-TQEQECN7.js.map → chunk-Q7Z76F7N.js.map} +1 -1
- package/dist/{chunk-FJWQ4PYX.js → chunk-QKKEBQ57.js} +6 -6
- package/dist/{chunk-FJWQ4PYX.js.map → chunk-QKKEBQ57.js.map} +1 -1
- package/dist/{chunk-QMWP2ZP6.js → chunk-R7QCNL62.js} +3 -3
- package/dist/{chunk-QMWP2ZP6.js.map → chunk-R7QCNL62.js.map} +1 -1
- package/dist/{chunk-WJJOFIBJ.js → chunk-RB7RHMKJ.js} +5 -5
- package/dist/{chunk-WJJOFIBJ.js.map → chunk-RB7RHMKJ.js.map} +1 -1
- package/dist/{chunk-F7RABDDP.js → chunk-RY6VPXG6.js} +3 -3
- package/dist/{chunk-F7RABDDP.js.map → chunk-RY6VPXG6.js.map} +1 -1
- package/dist/{chunk-R7VWIXFX.js → chunk-TEAYGNHT.js} +3 -3
- package/dist/{chunk-R7VWIXFX.js.map → chunk-TEAYGNHT.js.map} +1 -1
- package/dist/{chunk-XDA6N5GZ.js → chunk-TXYLHBUH.js} +3 -3
- package/dist/{chunk-XDA6N5GZ.js.map → chunk-TXYLHBUH.js.map} +1 -1
- package/dist/{chunk-6TFM3UTF.js → chunk-ULF4LPVA.js} +3 -3
- package/dist/{chunk-6TFM3UTF.js.map → chunk-ULF4LPVA.js.map} +1 -1
- package/dist/{chunk-FYL4GPXH.js → chunk-UUHLRFXB.js} +8 -8
- package/dist/{chunk-FYL4GPXH.js.map → chunk-UUHLRFXB.js.map} +1 -1
- package/dist/{chunk-ISW7G4IX.js → chunk-VJA4DVVT.js} +4 -4
- package/dist/{chunk-ISW7G4IX.js.map → chunk-VJA4DVVT.js.map} +1 -1
- package/dist/{chunk-JSHOX64U.js → chunk-W7CYFPGY.js} +6 -6
- package/dist/{chunk-JSHOX64U.js.map → chunk-W7CYFPGY.js.map} +1 -1
- package/dist/{chunk-5V4W3GBI.js → chunk-WAKCWE6P.js} +5 -5
- package/dist/{chunk-5V4W3GBI.js.map → chunk-WAKCWE6P.js.map} +1 -1
- package/dist/{chunk-EE7SB3QH.js → chunk-ZUVBDALM.js} +4 -4
- package/dist/{chunk-EE7SB3QH.js.map → chunk-ZUVBDALM.js.map} +1 -1
- package/dist/components/cart/index.js +1 -1
- package/dist/components/common/index.js +1 -1
- package/dist/components/drawer/index.js +23 -23
- package/dist/components/home/index.js +28 -28
- package/dist/components/layout/index.js +6 -6
- package/dist/components/product/index.js +25 -25
- package/dist/components/store/index.js +24 -24
- package/dist/components/toast/index.js +4 -4
- package/dist/dev/editor/index.js +2 -2
- package/dist/dev/index.js +2 -2
- package/dist/document-class-N7WF3WXG.js +33 -0
- package/dist/{document-class-FSNL65IJ.js.map → document-class-N7WF3WXG.js.map} +1 -1
- package/dist/hooks/index.js +23 -23
- package/dist/hooks/useComments.js +3 -3
- package/dist/hooks/useGtm.js +23 -23
- package/dist/hooks/useMoney.js +23 -23
- package/dist/hooks/useProduct.js +3 -3
- package/dist/hooks/useStore.js +23 -23
- package/dist/hooks/useUser.js +5 -5
- package/dist/hooks/useWishlist.js +3 -3
- package/dist/index.js +23 -23
- package/dist/native-app/index.js +3 -3
- package/dist/{navigation-CCGB3YEB.js → navigation-5DPDZQUU.js} +8 -8
- package/dist/{navigation-CCGB3YEB.js.map → navigation-5DPDZQUU.js.map} +1 -1
- package/dist/{navigation-I5H3HLZV.js → navigation-FRKMKNLK.js} +7 -7
- package/dist/{navigation-I5H3HLZV.js.map → navigation-FRKMKNLK.js.map} +1 -1
- package/dist/{not-found-SMNBZNFW.js → not-found-4U2TRCLF.js} +26 -26
- package/dist/{not-found-SMNBZNFW.js.map → not-found-4U2TRCLF.js.map} +1 -1
- package/dist/providers/index.js +23 -23
- package/dist/routes/account/orders.js +8 -8
- package/dist/routes/account.js +17 -17
- package/dist/routes/blog.js +12 -12
- package/dist/routes/brands.js +8 -8
- package/dist/routes/cart.js +32 -32
- package/dist/routes/home.js +29 -29
- package/dist/routes/index.js +6 -6
- package/dist/routes/loyalty.js +9 -9
- package/dist/routes/page.js +8 -8
- package/dist/routes/product-listing.js +33 -33
- package/dist/routes/product.js +28 -28
- package/dist/routes/root/beforeLoad.d.ts.map +1 -1
- package/dist/routes/seo-redirects.js +6 -6
- package/dist/routes/testimonials.js +4 -4
- package/dist/routes/thank-you.js +8 -8
- package/dist/skeleton.js +29 -29
- package/dist/{store-lookup-VFRN2MVI.js → store-lookup-S6JUSKNH.js} +11 -11
- package/dist/{store-lookup-VFRN2MVI.js.map → store-lookup-S6JUSKNH.js.map} +1 -1
- package/dist/tanstack.js +20 -20
- package/dist/utils/baseHead.js +2 -2
- package/dist/utils/index.js +6 -6
- package/dist/utils/shared-host-language.d.ts +5 -0
- package/dist/utils/shared-host-language.d.ts.map +1 -1
- package/dist/utils/store-base.d.ts +60 -0
- package/dist/utils/store-base.d.ts.map +1 -1
- package/dist/utils/store-identity.d.ts +14 -0
- package/dist/utils/store-identity.d.ts.map +1 -1
- package/dist/vite/index.js +3 -3
- package/package.json +1 -1
- package/tailwind/routes/root/beforeLoad.ts.txt +37 -3
- package/dist/chunk-IKCXJYYQ.js.map +0 -1
- package/dist/chunk-T2752RH7.js.map +0 -1
- package/dist/document-class-FSNL65IJ.js +0 -33
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/routes/home/loader.ts","../src/routes/home/HomePage.tsx","../src/routes/home/index.tsx"],"names":["HomeSkeleton","HomePage"],"mappings":"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","file":"chunk-JSHOX64U.js","sourcesContent":["import { getTwilightContext } from '../../twilight/context';\nimport { home } from '../../api/home';\nimport type { HomeComponentData } from '../../types';\nimport { RouteId } from '../../router/route-ids';\n\nexport interface HomeLoaderData {\n locale: string;\n components: HomeComponentData[];\n page: { slug: string };\n}\n\nexport async function homeLoader(ctx?: { locale?: string }): Promise<HomeLoaderData> {\n const { queryClient } = getTwilightContext();\n const components = await queryClient.ensureQueryData(home.queries.components());\n const result = {\n locale: ctx?.locale || 'ar',\n components: components.map((comp) => ({\n ...comp,\n path: comp.path?.replace('home.', '') || comp.path,\n })),\n page: { slug: RouteId.INDEX },\n };\n return result;\n}\n","import { memo, useCallback, useState } from 'react';\nimport { useDevHomeBlocks } from '../../dev/dev-settings-store';\nimport { HookSlot } from '../../hooks';\nimport { HomeComponentRenderer, ReorderProducts } from '../../components/home';\nimport { reorder, useLiveBlockMoves } from '../../components/live-editor/moves';\nimport type { HomePageProps } from './types';\nimport type { HomeComponentData } from '../../types';\nimport { Pulse } from '@salla.sa/twilight-components-react';\n\nexport const HomeSkeleton = memo(function HomeSkeleton() {\n return (\n <>\n <div className=\"s-block container skeleton-block-hero\">\n <Pulse className=\"h-64 sm:h-80 rounded-md\" />\n </div>\n <div className=\"s-block container skeleton-block-products\">\n <Pulse className=\"h-10 w-48 mb-4\" />\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-4\">\n {[1, 2, 3, 4].map((i) => (\n <Pulse key={i} className=\"h-56\" />\n ))}\n </div>\n </div>\n <div className=\"s-block container skeleton-block-products\">\n <Pulse className=\"h-10 w-48 mb-4\" />\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-4\">\n {[1, 2, 3, 4].map((i) => (\n <Pulse key={i} className=\"h-56\" />\n ))}\n </div>\n </div>\n </>\n );\n});\n\n/** As on Twig, a home page with no blocks lists the store's latest products instead. */\nconst LATEST_PRODUCTS: HomeComponentData = { path: 'latest-products' };\n\n/** The blocks' places in the store's order: 0, 1, 2… */\nconst storeOrder = (blocks: readonly unknown[]) => Array.from(blocks, (_, at) => at);\n\nexport const HomePage = memo(function HomePage({ components = [] }: HomePageProps) {\n // Dev-mode only: the dev editor's layout replaces the store's blocks while it\n // is on. No-op passthrough in production builds.\n const renderedComponents = useDevHomeBlocks(components);\n // The theme editor's preview moves blocks in place while the editor saves the\n // order; blocks from the server (a new page, a reload) start over from theirs.\n const [moved, setMoved] = useState<{ source: HomeComponentData[]; order: number[] } | null>(null);\n const order = moved?.source === renderedComponents ? moved.order : null;\n const onMove = useCallback(\n (from: number, to: number) =>\n setMoved((prev) => ({\n source: renderedComponents,\n order: reorder(\n prev?.source === renderedComponents ? prev.order : storeOrder(renderedComponents),\n from,\n to\n ),\n })),\n [renderedComponents]\n );\n useLiveBlockMoves(onMove);\n const placed = order ?? storeOrder(renderedComponents);\n\n return (\n <>\n <HookSlot name=\"home:start\" />\n <HookSlot name=\"home:content\" />\n {placed.map((at, index) => {\n const data = renderedComponents[at];\n // `data.key` is the twilight.json catalog id, shared by every placement\n // of that block. Platform blocks send null. The block's place in the\n // store's order is unique and stays with it when the preview moves it, so\n // a move keeps its state; a dev layout block keeps its own id.\n return <HomeComponentRenderer key={data.__dev_id ?? at} data={data} index={index} />;\n })}\n {!renderedComponents.length && (\n <HomeComponentRenderer data={LATEST_PRODUCTS} index={0} editable={false} />\n )}\n <HookSlot name=\"home:end\" />\n <ReorderProducts />\n </>\n );\n});\n\nexport { HomePage as default };\n","import type { HeadDescriptor } from '../../utils/head';\nimport { buildHreflangAlternates, storePageUrl } from '../../utils/baseHead';\nimport type { HomeLoaderData } from './loader';\nimport { homeLoader } from './loader';\nimport type { TwilightContext } from '../../twilight/context';\nimport { HomePage } from './HomePage';\nimport { RouteId } from '../../router/route-ids';\n\nexport { HomeSkeleton } from './HomePage';\nexport { registerHomeComponents, DefaultHomeComponents } from '../../components/home/register';\nexport { registerHomeComponentConfig } from '../../components/home';\nexport type { HomePageProps } from './types';\nexport type { HomeLoaderData } from './loader';\nexport type {\n HomeComponentsProps,\n AnyHomeComponent,\n HomeComponentConfig,\n} from '../../components/home';\n\nfunction loader(_ctx?: { locale?: string }): Promise<HomeLoaderData> {\n return homeLoader({ locale: _ctx?.locale });\n}\n\nfunction head(ctx: TwilightContext): HeadDescriptor {\n const store = ctx.settings?.store;\n if (!store) return {};\n\n const title = store.meta?.title ?? store.name;\n const description = store.meta?.description ?? store.description;\n const keywords = store.meta?.keywords;\n // `/ar`, like Twig, where store.url reads `/ar/`.\n const url = storePageUrl(ctx.settings, ctx.location.pathname) ?? store.url;\n\n return {\n title,\n description,\n keywords,\n canonical: url,\n openGraph: {\n type: 'website',\n title,\n description,\n images: store.logo,\n url,\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: store.logo,\n },\n alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname),\n };\n}\n\nexport const Home = { id: RouteId.INDEX, loader, head, Component: HomePage } as const;\n\nexport { homeLoader };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/routes/home/loader.ts","../src/routes/home/HomePage.tsx","../src/routes/home/index.tsx"],"names":["HomeSkeleton","HomePage"],"mappings":"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","file":"chunk-W7CYFPGY.js","sourcesContent":["import { getTwilightContext } from '../../twilight/context';\nimport { home } from '../../api/home';\nimport type { HomeComponentData } from '../../types';\nimport { RouteId } from '../../router/route-ids';\n\nexport interface HomeLoaderData {\n locale: string;\n components: HomeComponentData[];\n page: { slug: string };\n}\n\nexport async function homeLoader(ctx?: { locale?: string }): Promise<HomeLoaderData> {\n const { queryClient } = getTwilightContext();\n const components = await queryClient.ensureQueryData(home.queries.components());\n const result = {\n locale: ctx?.locale || 'ar',\n components: components.map((comp) => ({\n ...comp,\n path: comp.path?.replace('home.', '') || comp.path,\n })),\n page: { slug: RouteId.INDEX },\n };\n return result;\n}\n","import { memo, useCallback, useState } from 'react';\nimport { useDevHomeBlocks } from '../../dev/dev-settings-store';\nimport { HookSlot } from '../../hooks';\nimport { HomeComponentRenderer, ReorderProducts } from '../../components/home';\nimport { reorder, useLiveBlockMoves } from '../../components/live-editor/moves';\nimport type { HomePageProps } from './types';\nimport type { HomeComponentData } from '../../types';\nimport { Pulse } from '@salla.sa/twilight-components-react';\n\nexport const HomeSkeleton = memo(function HomeSkeleton() {\n return (\n <>\n <div className=\"s-block container skeleton-block-hero\">\n <Pulse className=\"h-64 sm:h-80 rounded-md\" />\n </div>\n <div className=\"s-block container skeleton-block-products\">\n <Pulse className=\"h-10 w-48 mb-4\" />\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-4\">\n {[1, 2, 3, 4].map((i) => (\n <Pulse key={i} className=\"h-56\" />\n ))}\n </div>\n </div>\n <div className=\"s-block container skeleton-block-products\">\n <Pulse className=\"h-10 w-48 mb-4\" />\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-4\">\n {[1, 2, 3, 4].map((i) => (\n <Pulse key={i} className=\"h-56\" />\n ))}\n </div>\n </div>\n </>\n );\n});\n\n/** As on Twig, a home page with no blocks lists the store's latest products instead. */\nconst LATEST_PRODUCTS: HomeComponentData = { path: 'latest-products' };\n\n/** The blocks' places in the store's order: 0, 1, 2… */\nconst storeOrder = (blocks: readonly unknown[]) => Array.from(blocks, (_, at) => at);\n\nexport const HomePage = memo(function HomePage({ components = [] }: HomePageProps) {\n // Dev-mode only: the dev editor's layout replaces the store's blocks while it\n // is on. No-op passthrough in production builds.\n const renderedComponents = useDevHomeBlocks(components);\n // The theme editor's preview moves blocks in place while the editor saves the\n // order; blocks from the server (a new page, a reload) start over from theirs.\n const [moved, setMoved] = useState<{ source: HomeComponentData[]; order: number[] } | null>(null);\n const order = moved?.source === renderedComponents ? moved.order : null;\n const onMove = useCallback(\n (from: number, to: number) =>\n setMoved((prev) => ({\n source: renderedComponents,\n order: reorder(\n prev?.source === renderedComponents ? prev.order : storeOrder(renderedComponents),\n from,\n to\n ),\n })),\n [renderedComponents]\n );\n useLiveBlockMoves(onMove);\n const placed = order ?? storeOrder(renderedComponents);\n\n return (\n <>\n <HookSlot name=\"home:start\" />\n <HookSlot name=\"home:content\" />\n {placed.map((at, index) => {\n const data = renderedComponents[at];\n // `data.key` is the twilight.json catalog id, shared by every placement\n // of that block. Platform blocks send null. The block's place in the\n // store's order is unique and stays with it when the preview moves it, so\n // a move keeps its state; a dev layout block keeps its own id.\n return <HomeComponentRenderer key={data.__dev_id ?? at} data={data} index={index} />;\n })}\n {!renderedComponents.length && (\n <HomeComponentRenderer data={LATEST_PRODUCTS} index={0} editable={false} />\n )}\n <HookSlot name=\"home:end\" />\n <ReorderProducts />\n </>\n );\n});\n\nexport { HomePage as default };\n","import type { HeadDescriptor } from '../../utils/head';\nimport { buildHreflangAlternates, storePageUrl } from '../../utils/baseHead';\nimport type { HomeLoaderData } from './loader';\nimport { homeLoader } from './loader';\nimport type { TwilightContext } from '../../twilight/context';\nimport { HomePage } from './HomePage';\nimport { RouteId } from '../../router/route-ids';\n\nexport { HomeSkeleton } from './HomePage';\nexport { registerHomeComponents, DefaultHomeComponents } from '../../components/home/register';\nexport { registerHomeComponentConfig } from '../../components/home';\nexport type { HomePageProps } from './types';\nexport type { HomeLoaderData } from './loader';\nexport type {\n HomeComponentsProps,\n AnyHomeComponent,\n HomeComponentConfig,\n} from '../../components/home';\n\nfunction loader(_ctx?: { locale?: string }): Promise<HomeLoaderData> {\n return homeLoader({ locale: _ctx?.locale });\n}\n\nfunction head(ctx: TwilightContext): HeadDescriptor {\n const store = ctx.settings?.store;\n if (!store) return {};\n\n const title = store.meta?.title ?? store.name;\n const description = store.meta?.description ?? store.description;\n const keywords = store.meta?.keywords;\n // `/ar`, like Twig, where store.url reads `/ar/`.\n const url = storePageUrl(ctx.settings, ctx.location.pathname) ?? store.url;\n\n return {\n title,\n description,\n keywords,\n canonical: url,\n openGraph: {\n type: 'website',\n title,\n description,\n images: store.logo,\n url,\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: store.logo,\n },\n alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname),\n };\n}\n\nexport const Home = { id: RouteId.INDEX, loader, head, Component: HomePage } as const;\n\nexport { homeLoader };\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ensureTwilightContextFromMatches } from './chunk-X55R4VVK.js';
|
|
2
|
-
import { renderThemeHookSlotsScript, renderAppScopeInstallScript } from './chunk-
|
|
2
|
+
import { renderThemeHookSlotsScript, renderAppScopeInstallScript } from './chunk-DPQIVZ4T.js';
|
|
3
3
|
import { resolveHead, mergeHead } from './chunk-GD26FI4J.js';
|
|
4
|
-
import { buildBaseHead } from './chunk-
|
|
5
|
-
import { readEnv, renderRuntimeEnvScript, escapeForInlineScript } from './chunk-
|
|
4
|
+
import { buildBaseHead } from './chunk-P2PPBXHD.js';
|
|
5
|
+
import { readEnv, renderRuntimeEnvScript, escapeForInlineScript } from './chunk-4E6FD5W7.js';
|
|
6
6
|
import { getTwilightContext, SettingsError } from './chunk-6K34BCUP.js';
|
|
7
7
|
import { FALLBACK_LOCALE } from './chunk-T72DAX7R.js';
|
|
8
8
|
|
|
@@ -492,5 +492,5 @@ function buildCustomJsScript(customJs, isUrl) {
|
|
|
492
492
|
}
|
|
493
493
|
|
|
494
494
|
export { TICKETING_SCRIPT_URL, needsDocumentLoad, resolveTwilightSdkUrl, rootHead, setSnippetPageTargets, subscribeSnippetPageTargets };
|
|
495
|
-
//# sourceMappingURL=chunk-
|
|
496
|
-
//# sourceMappingURL=chunk-
|
|
495
|
+
//# sourceMappingURL=chunk-WAKCWE6P.js.map
|
|
496
|
+
//# sourceMappingURL=chunk-WAKCWE6P.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/snippet-page-compat.ts","../src/routes/root/head.ts"],"names":[],"mappings":"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","file":"chunk-5V4W3GBI.js","sourcesContent":["/**\n * Compatibility mode for app snippets written for Twig, where every page is a full load.\n *\n * Such a snippet checks the page once, when it runs (`if (salla.url.is_page('product.single'))`),\n * and edits the DOM it finds. In the SPA it runs once per visit, on whatever page the shopper\n * landed on, so it never mounts on a later product page, and React replaces what it added when\n * the page changes. Until those apps move to the SDK's `page::view`, the engine loads the document fully\n * when a navigation enters or leaves a page one of them names, which is what Twig did. Only pages a\n * snippet names count: every other navigation stays in the browser.\n */\n\n/**\n * The start of a listener for SPA navigation, `on('page::view'` or `on('route::changed'`. The\n * page checks inside its arguments run on every navigation, so they need no full loads.\n */\nconst SPA_LISTENER = /\\bon\\s*\\(\\s*['\"](?:page::view|route::changed)['\"]/g;\n\n/** A `/` after one of these starts a regex literal, not a division. */\nconst BEFORE_REGEX = /[(,=:[!&|?{};+\\-*%<>~^]/;\n\n/** Index of the quote that ends the string opened at `start`, or -1. */\nfunction stringEnd(src: string, start: number): number {\n for (let i = start + 1; i < src.length; i++) {\n if (src[i] === '\\\\') i++;\n else if (src[i] === src[start]) return i;\n else if (src[i] === '\\n') return -1;\n }\n return -1;\n}\n\n/** Index of the `/` that ends the regex literal opened at `start`, or -1. */\nfunction regexEnd(src: string, start: number): number {\n let inClass = false;\n for (let i = start + 1; i < src.length; i++) {\n if (src[i] === '\\\\') i++;\n else if (src[i] === '[') inClass = true;\n else if (src[i] === ']') inClass = false;\n else if (src[i] === '/' && !inClass) return i;\n else if (src[i] === '\\n') return -1;\n }\n return -1;\n}\n\n/** From inside a template literal: the index of its closing backtick, or of the `{` of a `${`; -1 if neither. */\nfunction templatePartEnd(src: string, from: number): number {\n for (let i = from; i < src.length; i++) {\n if (src[i] === '\\\\') i++;\n else if (src[i] === '`') return i;\n else if (src[i] === '$' && src[i + 1] === '{') return i + 1;\n }\n return -1;\n}\n\n/**\n * The index just past the `)` that closes the `(` at `open`, or -1 when it never closes. Parens\n * in strings, template literals, comments and regex literals don't count: the snippet's own\n * `track('(')` must not end the call early and hide the code after it.\n */\nfunction closingParen(src: string, open: number): number {\n let depth = 0;\n let braces = 0;\n // Brace depth around each `${` the scan is inside, innermost last.\n const templates: number[] = [];\n let prev = '(';\n for (let i = open; i < src.length; i++) {\n const c = src[i];\n if (/\\s/.test(c)) continue;\n if (c === '/' && src[i + 1] === '/') {\n i = src.indexOf('\\n', i);\n if (i < 0) return -1;\n continue;\n }\n if (c === '/' && src[i + 1] === '*') {\n i = src.indexOf('*/', i + 2) + 1;\n if (i < 1) return -1;\n continue;\n }\n if (c === '\"' || c === \"'\") i = stringEnd(src, i);\n else if (c === '/' && BEFORE_REGEX.test(prev)) i = regexEnd(src, i);\n else if (c === '`' || (c === '}' && braces === 0 && templates.length)) {\n if (c === '}') braces = templates.pop() as number;\n i = templatePartEnd(src, i + 1);\n if (i >= 0 && src[i] === '{') {\n templates.push(braces);\n braces = 0;\n }\n } else if (c === '{') braces++;\n else if (c === '}') braces--;\n else if (c === '(') depth++;\n else if (c === ')' && --depth === 0) return i + 1;\n if (i < 0) return -1;\n prev = src[i];\n }\n return -1;\n}\n\n/**\n * `content` with each navigation listener's arguments cut out, up to the paren that closes the\n * call. What's left runs once, at load. A handler defined elsewhere and passed by name stays in,\n * and its checks still count: the scan can't tell where it runs, so it keeps the full load.\n */\nfunction stripNavigationListeners(content: string): string {\n let out = '';\n let from = 0;\n for (const match of content.matchAll(SPA_LISTENER)) {\n if (match.index < from) continue;\n const end = closingParen(content, content.indexOf('(', match.index));\n // Never closes, or the scan lost its place: keep the rest, so its checks still count.\n if (end < 0) break;\n out += content.slice(from, match.index);\n from = end;\n }\n return out + content.slice(from);\n}\n\n/** Index of the newline at or after `from`, or the end. */\nfunction lineEnd(src: string, from: number): number {\n const at = src.indexOf('\\n', from);\n return at < 0 ? src.length : at;\n}\n\n/** Whether `src` opens a comment at `i`. */\nconst isComment = (src: string, i: number) =>\n src[i] === '/' && (src[i + 1] === '/' || src[i + 1] === '*');\n\n/**\n * Index just past the comment, string or regex literal that opens at `i`, or -1 when code (or a\n * template literal, which holds code) starts there. `prev` is the last code character before it.\n */\nfunction literalEnd(src: string, i: number, prev: string): number {\n const c = src[i];\n if (isComment(src, i)) {\n if (src[i + 1] === '/') return lineEnd(src, i);\n const close = src.indexOf('*/', i + 2);\n return close < 0 ? src.length : close + 2;\n }\n if (c === '\"' || c === \"'\") {\n const close = stringEnd(src, i);\n return close < 0 ? lineEnd(src, i) : close + 1;\n }\n if (c === '/' && BEFORE_REGEX.test(prev)) {\n const close = regexEnd(src, i);\n return close < 0 ? -1 : close + 1;\n }\n return -1;\n}\n\n/**\n * Clears `code` over the template literal opened at `start`, all but the code inside its\n * `${…}`, which runs like any other. Returns the index of its closing backtick.\n */\nfunction maskTemplate(src: string, code: Uint8Array, start: number): number {\n code[start] = 0;\n for (let i = start + 1; i < src.length; i++) {\n code[i] = 0;\n if (src[i] === '\\\\') code[++i] = 0;\n else if (src[i] === '`') return i;\n else if (src[i] === '$' && src[i + 1] === '{') {\n code[i + 1] = 0;\n i = maskCode(src, code, i + 2, true);\n code[i] = 0;\n }\n }\n return src.length;\n}\n\n/**\n * Clears `code` over the comments and literals of the script from `from`. Inside a template's\n * `${…}` (`inExpression`), it stops at the `}` that closes it and returns that index.\n */\nfunction maskCode(src: string, code: Uint8Array, from: number, inExpression = false): number {\n let prev = '(';\n let braces = 0;\n for (let i = from; i < src.length; i++) {\n const c = src[i];\n if (/\\s/.test(c)) continue;\n const end = literalEnd(src, i, prev);\n if (end >= 0) {\n code.fill(0, i, end);\n // A literal is a value, so a `/` after it divides; a comment changes nothing.\n if (!isComment(src, i)) prev = 'a';\n i = end - 1;\n continue;\n }\n if (c === '`') {\n i = maskTemplate(src, code, i);\n prev = 'a';\n continue;\n }\n if (inExpression && c === '}' && braces-- === 0) return i;\n if (c === '{') braces++;\n prev = c;\n }\n return src.length;\n}\n\n/** Which characters of a script are code: not in a comment, string or template text. */\nfunction scriptMask(src: string): Uint8Array {\n const code = new Uint8Array(src.length).fill(1);\n maskCode(src, code, 0);\n return code;\n}\n\n/** A `type` the browser runs as JavaScript: none, `module`, or a JavaScript MIME type. */\nconst JS_TYPE = /^(?:|module|(?:text|application)\\/(?:x-)?(?:java|ecma)script)$/i;\n\n/**\n * The JavaScript an inline snippet runs: the text of its `<script>` elements, parsed by the\n * browser as `injectHtml` parses it, so attributes, quotes and the HTML around a script read as\n * they will on the page. A snippet with no `<script>` tag, or a scan with no DOM, reads whole.\n */\nfunction snippetScripts(snippet: string): string[] {\n if (!/<script\\b/i.test(snippet) || typeof document === 'undefined') return [snippet];\n const tpl = document.createElement('template');\n tpl.innerHTML = snippet;\n return Array.from(tpl.content.querySelectorAll('script'))\n .filter((script) => JS_TYPE.test(script.type.trim()))\n .map((script) => script.text);\n}\n\n/** `is_page('product.single')` with a literal slug. */\nconst IS_PAGE_LITERAL = /\\bis_page\\s*\\(\\s*['\"]([\\w.-]+)['\"]\\s*\\)/g;\n\n/**\n * A negated check, `!salla.url.is_page('cart')`, `!(is_page('cart'))` or\n * `is_page('cart') === false`: it acts on every page but the one it names, so that slug says\n * nothing about where it acts.\n */\n// Character classes for the `(` and `salla.url.` prefixes, not repeated groups: no nested\n// quantifier to backtrack on, as the snippet text is the app's.\nconst IS_PAGE_NEGATED =\n /![\\s(]*[\\w$.]*is_page\\s*\\(\\s*['\"][\\w.-]+['\"]\\s*\\)|\\bis_page\\s*\\(\\s*['\"][\\w.-]+['\"]\\s*\\)\\s*={2,3}\\s*false\\b/g;\n\n/**\n * The pages an inline snippet's code depends on: the slugs it passes to `is_page` as a literal,\n * or nothing when it doesn't care or reads the page only inside a `page::view` listener.\n *\n * Only a literal, positive check counts. A negated one, `page.slug`, `config.get('page')` or a\n * slug held in a variable would point at every page, and a full load on every navigation costs\n * the whole store its in-browser navigation (#513), so those snippets keep running once.\n */\nexport function snippetPageTargets(snippet: string): string[] {\n const slugs = new Set<string>();\n for (const script of snippetScripts(snippet)) {\n for (const slug of scriptPageTargets(script)) slugs.add(slug);\n }\n return [...slugs];\n}\n\n/** The slugs one script checks with a literal, positive `is_page`, in code that runs at load. */\nfunction scriptPageTargets(script: string): string[] {\n const content = stripNavigationListeners(script);\n const code = scriptMask(content);\n const negated = [...content.matchAll(IS_PAGE_NEGATED)].map(\n (m) => [m.index, m.index + m[0].length] as const\n );\n return [...content.matchAll(IS_PAGE_LITERAL)]\n .filter(\n ({ index }) => code[index] && !negated.some(([from, to]) => index >= from && index < to)\n )\n .map((m) => m[1]);\n}\n\n/** Pages that need a full load, across every installed app's inline snippets. */\nlet targets = new Set<string>();\n\n/** Told whether any page needs a full load, each time the snippets are recorded. */\ntype TargetsListener = (active: boolean) => void;\nconst listeners = new Set<TargetsListener>();\n\n/**\n * Calls `listener` now and whenever the snippets are recorded, with whether any page needs a full\n * load. The router installs its navigation blocker only while one does: a blocker makes every\n * history push wait a tick, which stores without such snippets shouldn't pay for.\n */\nexport function subscribeSnippetPageTargets(listener: TargetsListener): () => void {\n listeners.add(listener);\n listener(targets.size > 0);\n return () => listeners.delete(listener);\n}\n\n/**\n * Records the installed apps' inline snippets. CDN snippets are not scanned: their code is on\n * another origin. `AppsSnippets` calls this once the snippets are known.\n */\nexport function setSnippetPageTargets(\n snippets: ReadonlyArray<{ content: string; url?: string | null }>\n): void {\n const next = new Set<string>();\n for (const s of snippets) {\n if (s.url) continue;\n for (const slug of snippetPageTargets(s.content)) next.add(slug);\n }\n targets = next;\n listeners.forEach((listener) => listener(next.size > 0));\n if (next.size && typeof console !== 'undefined') {\n console.warn(\n '[salla] app snippets depend on the page; navigating to or from these pages reloads the document:',\n [...next]\n );\n }\n}\n\n/**\n * Whether going from the page `from` to the page `to` must load the document fully: when either\n * is a page some app snippet targets. Leaving one matters as much as entering: a widget an app\n * added to <body> for the product page would otherwise stay on the cart.\n */\nexport function needsDocumentLoad(from: string | undefined, to: string | undefined): boolean {\n if (!targets.size) return false;\n return (!!from && targets.has(from)) || (!!to && targets.has(to));\n}\n\n/** @internal Test-only. */\nexport function resetSnippetPageTargets(): void {\n targets = new Set();\n listeners.forEach((listener) => listener(false));\n}\n","import type { HeadDescriptor, HeadResult } from '../../utils/head';\nimport { mergeHead, resolveHead } from '../../utils/head';\nimport { buildBaseHead } from '../../utils/baseHead';\nimport { FALLBACK_LOCALE } from '../../providers/locale-constants';\nimport { getTwilightContext } from '../../twilight/context';\nimport type { TwilightContextMatch } from '../../twilight/ensure-context';\nimport { ensureTwilightContextFromMatches } from '../../twilight/ensure-context';\nimport type { StoreContext } from '../../api/store';\nimport type { AppSnippet } from '../../api/apps';\nimport { SettingsError } from '../../utils/errors';\nimport { renderAppScopeInstallScript } from '../../utils/app-scope';\nimport { renderThemeHookSlotsScript } from '../../utils/theme-hook-slots';\nimport { escapeForInlineScript } from '../../utils/inline-script';\nimport { readEnv, renderRuntimeEnvScript } from '../../utils/runtime-env';\n\nconst SALLA_ICONS_CSS_URL = 'https://cdn.assets.salla.network/static/fonts/sallaicons.css?v=2.0.5';\nconst LIT_VERSION = '3.3.3';\nconst LIT_CDN_BASE = `https://cdn.assets.salla.network/static/lit/${LIT_VERSION}`;\n\n/** Bare-specifier map for the lit build the engine's `<salla-*>` web components resolve against. */\nconst LIT_IMPORTS: Record<string, string> = {\n lit: `${LIT_CDN_BASE}/lit.js`,\n 'lit/': `${LIT_CDN_BASE}/`,\n 'lit-html': `${LIT_CDN_BASE}/lit-html/lit-html.js`,\n 'lit-html/': `${LIT_CDN_BASE}/lit-html/`,\n 'lit-element': `${LIT_CDN_BASE}/lit-element/lit-element.js`,\n 'lit-element/': `${LIT_CDN_BASE}/lit-element/`,\n '@lit/reactive-element': `${LIT_CDN_BASE}/reactive-element/reactive-element.js`,\n '@lit/reactive-element/': `${LIT_CDN_BASE}/reactive-element/`,\n};\n\nexport const TICKETING_SCRIPT_URL =\n 'https://cdn.assets.salla.network/latest/@salla.sa/ui-store-ticketing-system/ticketing-system.es.js';\n\nconst TWILIGHT_RELEASE_CDN = 'https://cdn.salla.network/js/twilight';\nconst TWILIGHT_DEV_CDN = 'https://cdn.assets.salla.network/dev/@salla.sa/twilight';\n// The oldest Twilight release this engine works with. Raise it whenever the engine\n// starts relying on something newer; the reason lives in that commit. Today's floor:\n// components ship their own CSS, which themes no longer compile (SallaApp/twilight#2107).\nconst MIN_TWILIGHT_VERSION = '2.14.538';\n// Last resort when no override and no platform pin, and the substitute for a pin below the floor.\nconst DEFAULT_TWILIGHT_VERSION = '2.14.584';\nconst releaseUrl = (version: string): string =>\n `${TWILIGHT_RELEASE_CDN}/${version}/twilight.esm.js`;\n// The head is built more than once per request (early hints, then the page); say it once.\nconst warnedPins = new Set<string>();\n\n/** `x.y.z` release pins only; dev shas and other strings are loaded as given. */\nfunction belowMinimum(version: string): boolean {\n return (\n /^\\d+\\.\\d+\\.\\d+$/.test(version) &&\n version.localeCompare(MIN_TWILIGHT_VERSION, undefined, { numeric: true }) < 0\n );\n}\n\n/** The `x.y.z` release segment of a release-CDN `.../twilight.esm.js` URL, if present. */\nfunction releaseVersionInUrl(url: string): string | null {\n const match = url.match(/\\/(\\d+\\.\\d+\\.\\d+)\\/twilight\\.esm\\.js(?:[?#]|$)/);\n return match ? match[1] : null;\n}\n\n/**\n * `VITE_TWILIGHT_URL`/`VITE_TWILIGHT_VERSION` outrank everything below, including\n * `theme.twilight.version`'s own `belowMinimum` guard — a stale override wins\n * silently otherwise (TD-16375: a scaffold-time pin outlived the engine raising\n * MIN_TWILIGHT_VERSION, so every new theme rendered without component CSS and\n * nothing said why). Only a dev-mode nudge, not a swap: an env override is a\n * deliberate choice, so unlike the settings-pin path below this never substitutes\n * the engine default underneath the developer.\n */\nfunction warnIfOverrideBelowMinimum(source: string, version: string): void {\n // Worker logs in production should stay quiet -- this is a developer-directed nudge,\n // not a user-facing or production-monitored signal. import.meta.env.DEV is a static\n // false in production builds, so this branch (and the console.warn below) is\n // tree-shaken out entirely, same as DevSettingsWidget / dev-settings-store.ts.\n if (!import.meta.env.DEV) return;\n if (!belowMinimum(version)) return;\n const key = `${source}:${version}`;\n if (warnedPins.has(key)) return;\n warnedPins.add(key);\n console.warn(\n `[twilight] ${source}=${version} is below the engine minimum ${MIN_TWILIGHT_VERSION} — components may load without their CSS (SallaApp/twilight#2107). Unset it or bump it to ${MIN_TWILIGHT_VERSION}+.`\n );\n}\n\n/**\n * Which twilight.esm.js the storefront loads, in priority order:\n * 1. `VITE_TWILIGHT_URL` — full local/deployment override.\n * 2. `VITE_TWILIGHT_VERSION` — dev-CDN build override.\n * 3. `theme.twilight.version` from the settings endpoint — the platform-pinned\n * release used when no environment override is configured.\n * 4. The engine's default release, also used when the pin is below the engine minimum.\n */\nexport function resolveTwilightSdkUrl(settings?: StoreContext): string {\n const urlOverride = readEnv('VITE_TWILIGHT_URL');\n if (urlOverride) {\n const version = releaseVersionInUrl(urlOverride);\n if (version) warnIfOverrideBelowMinimum('VITE_TWILIGHT_URL', version);\n return urlOverride;\n }\n\n const versionOverride = readEnv('VITE_TWILIGHT_VERSION');\n if (versionOverride) {\n warnIfOverrideBelowMinimum('VITE_TWILIGHT_VERSION', versionOverride);\n return `${TWILIGHT_DEV_CDN}/${versionOverride}/twilight.esm.js`;\n }\n\n const pinnedVersion = settings?.theme?.twilight?.version;\n if (pinnedVersion && belowMinimum(pinnedVersion)) {\n if (!warnedPins.has(pinnedVersion)) {\n warnedPins.add(pinnedVersion);\n console.warn(\n `[twilight] theme.twilight.version ${pinnedVersion} is below the engine minimum ${MIN_TWILIGHT_VERSION}; loading ${DEFAULT_TWILIGHT_VERSION} instead`\n );\n }\n return releaseUrl(DEFAULT_TWILIGHT_VERSION);\n }\n if (pinnedVersion) return releaseUrl(pinnedVersion);\n\n return releaseUrl(DEFAULT_TWILIGHT_VERSION);\n}\n\n// On a page that preloads its LCP image, the icon font (~270 KB) applies once the first screen's\n// priority images have painted, so it doesn't compete with them; other pages swap on load.\nconst MEDIA_SWAP_SCRIPT = `\n(function(){var d=document,s=function(l){if(l.sheet||\"all\"===l.media)l.media=\"all\";else l.onload=function(){this.media=\"all\"}},f=d.getElementById(\"salla-theme-font\"),i=d.getElementById(\"salla-icons-css\");f&&s(f);if(!i)return;if(!d.querySelector('link[rel=\"preload\"][as=\"image\"]'))return s(i);var g=function(){g=function(){};s(i)},p=function(){requestAnimationFrame(function(){setTimeout(function(){g()})});setTimeout(function(){g()},100)};d.addEventListener(\"DOMContentLoaded\",function(){var m=[].filter.call(d.querySelectorAll('img[fetchpriority=\"high\"]'),function(x){return!x.complete}),n=m.length;if(!n)return p();m.forEach(function(x){var o=function(){--n||p()};x.addEventListener(\"load\",o,{once:!0});x.addEventListener(\"error\",o,{once:!0})});setTimeout(function(){g()},2500)})})();\n`.trim();\n\nconst LOADING_CSS = `\n.loading-overlay{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:#fff;z-index:9999}\n.loading-spinner{animation:spin 1s linear infinite;border-radius:9999px;height:3rem;width:3rem;border-bottom:2px solid var(--color-primary,#000)}\n@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}\nhtml,body{margin:0;padding:0;height:100%}\n`.trim();\n\nconst SALLA_INIT_SCRIPT = `\nwindow.salla = window.Salla = window.Salla || window.salla || {};\nwindow.Salla.onReady = window.Salla.onReady || function(callback) {\n return new Promise(function(resolve) {\n if (window.Salla.status === 'ready') {\n var config = window.salla && window.salla.config && window.salla.config.all();\n resolve(callback ? callback(config) : config);\n } else {\n window.addEventListener('twilight::initiated', function(event) {\n resolve(callback ? callback(event.detail) : event.detail);\n }, { once: true });\n }\n });\n};\n`.trim();\n\n/**\n * Distinct snippet-host origins to `preconnect` (warm DNS/TCP/TLS during parse). From the real\n * URLs (dev/prod-correct), deduped and capped at 4. No `crossOrigin`: snippets are no-cors fetches.\n */\nexport function snippetPreconnectOrigins(snippets: readonly AppSnippet[] | undefined): string[] {\n if (!snippets?.length) return [];\n const origins = new Set<string>();\n for (const app of snippets) {\n if (app.status !== 'enabled') continue;\n for (const s of app.snippets) {\n if (!s.url) continue;\n try {\n origins.add(new URL(s.url).origin);\n } catch {\n /* skip a malformed snippet url rather than breaking the head */\n }\n if (origins.size >= 4) return [...origins];\n }\n }\n return [...origins];\n}\n\nexport function rootHead(ctx: {\n params: Record<string, string>;\n matches?: readonly TwilightContextMatch[];\n}): HeadResult {\n // Re-run on the client during hydration, where the twilight module store may\n // still be empty. Recover it from the resolved match context so the head is\n // built from real settings instead of falling through to 'Store Unavailable'.\n ensureTwilightContextFromMatches(ctx.matches);\n\n let settings: StoreContext | undefined;\n try {\n settings = getTwilightContext().settings;\n } catch (e) {\n if (e instanceof SettingsError) {\n return resolveHead({\n title: 'Store Unavailable',\n });\n }\n throw e;\n }\n const locale = ctx.params.locale || FALLBACK_LOCALE;\n const parts = deriveHeadParts(settings);\n\n return resolveHead(\n mergeHead(buildBaseHead(settings, locale), {\n meta: buildRootMeta(parts),\n links: buildRootLinks(parts),\n styles: buildRootStyles(parts),\n importMap: [{ imports: LIT_IMPORTS }],\n scripts: buildRootScripts(parts),\n })\n );\n}\n\n/** Everything the root head's tag builders read, derived once from the store settings. */\ninterface RootHeadParts {\n store: StoreContext['store'] | undefined;\n favicon?: string;\n primaryColor?: string;\n fontUrl?: string;\n fontUrlWithDisplay?: string;\n isGoogleFont?: boolean;\n fontFamilyName?: string;\n customJs?: string;\n customCss?: string;\n isCustomCssUrl?: boolean;\n isCustomJsUrl?: boolean;\n twilightSdkUrl: string;\n /** The visitor gets the maintenance page, which loads no SDK and no app snippets. */\n maintenance: boolean;\n snippetPreconnects: Array<{ rel: 'preconnect'; href: string }>;\n appScopeInstallScript: string;\n themeHookSlotsScript: string | null;\n runtimeEnvScript: string | null;\n}\n\n/** Google Fonts only honours `display=swap` as a query param; other hosts get the @font-face\n * override instead (see buildRootStyles). */\nfunction deriveFontParts(theme?: StoreContext['theme']) {\n const font = theme?.font;\n const fontUrl = font?.url || font?.path;\n const isGoogleFont = fontUrl?.includes('fonts.googleapis.com');\n const needsDisplay = Boolean(isGoogleFont && fontUrl && !fontUrl.includes('display='));\n const separator = fontUrl?.includes('?') ? '&' : '?';\n\n return {\n fontUrl,\n isGoogleFont,\n fontFamilyName: font?.family_name,\n fontUrlWithDisplay: needsDisplay ? `${fontUrl}${separator}display=swap` : fontUrl,\n };\n}\n\n/** Theme customization JS/CSS, each either a URL to load or an inline blob to embed. */\nfunction deriveCustomizationParts(theme?: StoreContext['theme']) {\n const customization = theme?.customization;\n const customJs = customization?.js?.trim();\n const customCss = customization?.css?.trim();\n const isUrl = (value?: string): boolean =>\n Boolean(value?.startsWith('http') || value?.startsWith('//'));\n\n return {\n customJs,\n customCss,\n isCustomCssUrl: isUrl(customCss),\n isCustomJsUrl: isUrl(customJs),\n };\n}\n\nfunction deriveHeadParts(settings?: StoreContext): RootHeadParts {\n const store = settings?.store;\n\n return {\n store,\n favicon: store?.icon,\n primaryColor: settings?.theme?.color?.primary,\n ...deriveFontParts(settings?.theme),\n ...deriveCustomizationParts(settings?.theme),\n twilightSdkUrl: resolveTwilightSdkUrl(settings),\n maintenance: getTwilightContext().maintenance,\n // Warm the connection to the snippet host(s) during head parse, so the body's deferred\n // `<script src>` snippet tags fetch off an already-open socket instead of DNS+TCP+TLS.\n snippetPreconnects: snippetPreconnectOrigins(getTwilightContext().appsSnippets).map((href) => ({\n rel: 'preconnect' as const,\n href,\n })),\n // Install `Salla.appScope` inline at parse time, before the SDK is ready — else a snippet's\n // onReady callback calls it too early and throws. Always emitted, even when the settings\n // prefetch failed: the CDN snippet tags ship regardless (they come from the *snippets*\n // endpoint), so the factory has to exist for them. `installAppScope` then seeds the real\n // buckets into this install once the client query resolves.\n appScopeInstallScript: renderAppScopeInstallScript(\n getTwilightContext().appsSettings ?? { apps: {} }\n ),\n // Whitelist the theme's own hook slots at parse time too, for the same reason: apps register\n // their `onReady` callbacks from parser-inserted snippet tags, long before React hydrates.\n themeHookSlotsScript: renderThemeHookSlotsScript(),\n // Env this render resolved (worker `vars` live in server-only `process.env`), handed to the\n // client so it doesn't silently fall back to the production defaults. Re-rendered on the\n // client during hydration, where it resolves to the same values or to nothing.\n runtimeEnvScript: renderRuntimeEnvScript(),\n };\n}\n\nfunction buildRootMeta(p: RootHeadParts): NonNullable<HeadDescriptor['meta']> {\n return [\n { name: 'robots', content: 'index, follow' },\n { name: 'msapplication-TileColor', content: '#ffffff' },\n ...(p.favicon ? [{ name: 'msapplication-TileImage', content: p.favicon }] : []),\n ...(p.primaryColor\n ? [\n { name: 'theme-color', content: p.primaryColor },\n { name: 'msapplication-navbutton-color', content: p.primaryColor },\n { name: 'apple-mobile-web-app-status-bar-style', content: p.primaryColor },\n ]\n : []),\n ];\n}\n\nfunction buildRootLinks(p: RootHeadParts): NonNullable<HeadDescriptor['links']> {\n return [\n { rel: 'preconnect', href: 'https://api.salla.dev' },\n { rel: 'preconnect', href: 'https://cdn.salla.sa' },\n { rel: 'preconnect', href: 'https://cdn.assets.salla.network', crossOrigin: 'anonymous' },\n // Warm the installed apps' CDN snippet host(s) — see snippetPreconnectOrigins.\n // Not on the maintenance page: it renders neither the snippets nor the SDK.\n ...(p.maintenance ? [] : p.snippetPreconnects),\n ...(p.isGoogleFont\n ? [\n {\n rel: 'preconnect' as const,\n href: 'https://fonts.gstatic.com',\n crossOrigin: 'anonymous' as const,\n },\n ]\n : []),\n ...(p.maintenance ? [] : [{ rel: 'modulepreload' as const, href: p.twilightSdkUrl }]),\n ...(p.fontUrlWithDisplay\n ? [\n {\n id: 'salla-theme-font',\n rel: 'stylesheet',\n href: p.fontUrlWithDisplay,\n media: 'print',\n },\n ]\n : []),\n ...(p.fontUrlWithDisplay && !p.isGoogleFont && p.fontFamilyName\n ? [\n {\n id: 'salla-font-display-override',\n rel: 'preload',\n as: 'style',\n href: p.fontUrlWithDisplay,\n },\n ]\n : []),\n ...(p.favicon ? [{ rel: 'icon', href: p.favicon }] : []),\n ...(p.favicon\n ? [{ id: 'salla-apple-icon', rel: 'apple-touch-icon-precomposed', href: p.favicon }]\n : []),\n ...(p.isCustomCssUrl && p.customCss\n ? [{ id: 'salla-custom-css', rel: 'stylesheet', href: p.customCss }]\n : []),\n {\n id: 'salla-icons-css',\n rel: 'stylesheet',\n href: SALLA_ICONS_CSS_URL,\n media: 'print',\n },\n // {\n // id: 'intl-tel-input-css',\n // rel: 'stylesheet',\n // href: 'https://cdn.jsdelivr.net/npm/intl-tel-input@26.8.0/build/css/intlTelInput.css',\n // },\n ...(p.isCustomJsUrl && p.customJs\n ? [{ id: 'salla-custom-js-preload', rel: 'preload', as: 'script', href: p.customJs }]\n : []),\n ];\n}\n\n// Hoistable (href + precedence): the web components insert their own <style> near the top of\n// <head> before hydration, which a positionally hydrated <style> would be matched against.\nconst hoisted = (id: string, children: string) => ({\n id,\n href: id,\n precedence: 'default',\n children,\n});\n\nfunction buildRootStyles(p: RootHeadParts): NonNullable<HeadDescriptor['styles']> {\n return [\n hoisted('twilight-loading', LOADING_CSS),\n ...(!p.isGoogleFont && p.fontFamilyName\n ? [\n hoisted(\n 'salla-font-display-swap',\n `@font-face{font-family:\"${p.fontFamilyName}\";font-display:swap;src:local(\"${p.fontFamilyName}\")}`\n ),\n ]\n : []),\n ...(!p.isCustomCssUrl && p.customCss ? [hoisted('salla-custom-css', p.customCss)] : []),\n ];\n}\n\nfunction buildRootScripts(p: RootHeadParts): NonNullable<HeadDescriptor['scripts']> {\n return [\n // First: the API base / store identifier this render used, so the hydrated client\n // resolves the same ones (worker `vars` never reach the browser bundle on their own).\n ...(p.runtimeEnvScript ? [{ id: 'salla-runtime-env', children: p.runtimeEnvScript }] : []),\n { id: 'twilight-init', children: SALLA_INIT_SCRIPT },\n // After twilight-init (which defines window.Salla) and before the SDK module, so the\n // appScope factory exists ahead of any snippet's onReady callback firing.\n { id: 'salla-app-scope', children: p.appScopeInstallScript },\n // Arms the hook-slot whitelist push here, so its `twilight::initiated` listener is\n // registered before any app snippet's — listeners fire in registration order.\n ...(p.themeHookSlotsScript\n ? [{ id: 'salla-theme-hook-slots', children: p.themeHookSlotsScript }]\n : []),\n { id: 'salla-async-css', children: MEDIA_SWAP_SCRIPT },\n // The SDK and ticketing modules are rendered at the end of <body> (SallaSdkScripts).\n ...(p.customJs ? [buildCustomJsScript(p.customJs, Boolean(p.isCustomJsUrl))] : []),\n ];\n}\n\n/** A URL customization is loaded after SDK init; an inline one is wrapped so a syntax/runtime\n * error in partner JS warns instead of taking the page down. */\nfunction buildCustomJsScript(customJs: string, isUrl: boolean) {\n return {\n id: 'salla-custom-js',\n children: isUrl\n ? `window.addEventListener('twilight::initiated',function(){var s=document.createElement('script');s.src=${escapeForInlineScript(JSON.stringify(customJs))};s.async=true;document.head.appendChild(s)},{once:true});`\n : `try { ${customJs} } catch(e) { console.warn(\"[ThemeCustomization] Custom JS error:\", e); }`,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/snippet-page-compat.ts","../src/routes/root/head.ts"],"names":[],"mappings":"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","file":"chunk-WAKCWE6P.js","sourcesContent":["/**\n * Compatibility mode for app snippets written for Twig, where every page is a full load.\n *\n * Such a snippet checks the page once, when it runs (`if (salla.url.is_page('product.single'))`),\n * and edits the DOM it finds. In the SPA it runs once per visit, on whatever page the shopper\n * landed on, so it never mounts on a later product page, and React replaces what it added when\n * the page changes. Until those apps move to the SDK's `page::view`, the engine loads the document fully\n * when a navigation enters or leaves a page one of them names, which is what Twig did. Only pages a\n * snippet names count: every other navigation stays in the browser.\n */\n\n/**\n * The start of a listener for SPA navigation, `on('page::view'` or `on('route::changed'`. The\n * page checks inside its arguments run on every navigation, so they need no full loads.\n */\nconst SPA_LISTENER = /\\bon\\s*\\(\\s*['\"](?:page::view|route::changed)['\"]/g;\n\n/** A `/` after one of these starts a regex literal, not a division. */\nconst BEFORE_REGEX = /[(,=:[!&|?{};+\\-*%<>~^]/;\n\n/** Index of the quote that ends the string opened at `start`, or -1. */\nfunction stringEnd(src: string, start: number): number {\n for (let i = start + 1; i < src.length; i++) {\n if (src[i] === '\\\\') i++;\n else if (src[i] === src[start]) return i;\n else if (src[i] === '\\n') return -1;\n }\n return -1;\n}\n\n/** Index of the `/` that ends the regex literal opened at `start`, or -1. */\nfunction regexEnd(src: string, start: number): number {\n let inClass = false;\n for (let i = start + 1; i < src.length; i++) {\n if (src[i] === '\\\\') i++;\n else if (src[i] === '[') inClass = true;\n else if (src[i] === ']') inClass = false;\n else if (src[i] === '/' && !inClass) return i;\n else if (src[i] === '\\n') return -1;\n }\n return -1;\n}\n\n/** From inside a template literal: the index of its closing backtick, or of the `{` of a `${`; -1 if neither. */\nfunction templatePartEnd(src: string, from: number): number {\n for (let i = from; i < src.length; i++) {\n if (src[i] === '\\\\') i++;\n else if (src[i] === '`') return i;\n else if (src[i] === '$' && src[i + 1] === '{') return i + 1;\n }\n return -1;\n}\n\n/**\n * The index just past the `)` that closes the `(` at `open`, or -1 when it never closes. Parens\n * in strings, template literals, comments and regex literals don't count: the snippet's own\n * `track('(')` must not end the call early and hide the code after it.\n */\nfunction closingParen(src: string, open: number): number {\n let depth = 0;\n let braces = 0;\n // Brace depth around each `${` the scan is inside, innermost last.\n const templates: number[] = [];\n let prev = '(';\n for (let i = open; i < src.length; i++) {\n const c = src[i];\n if (/\\s/.test(c)) continue;\n if (c === '/' && src[i + 1] === '/') {\n i = src.indexOf('\\n', i);\n if (i < 0) return -1;\n continue;\n }\n if (c === '/' && src[i + 1] === '*') {\n i = src.indexOf('*/', i + 2) + 1;\n if (i < 1) return -1;\n continue;\n }\n if (c === '\"' || c === \"'\") i = stringEnd(src, i);\n else if (c === '/' && BEFORE_REGEX.test(prev)) i = regexEnd(src, i);\n else if (c === '`' || (c === '}' && braces === 0 && templates.length)) {\n if (c === '}') braces = templates.pop() as number;\n i = templatePartEnd(src, i + 1);\n if (i >= 0 && src[i] === '{') {\n templates.push(braces);\n braces = 0;\n }\n } else if (c === '{') braces++;\n else if (c === '}') braces--;\n else if (c === '(') depth++;\n else if (c === ')' && --depth === 0) return i + 1;\n if (i < 0) return -1;\n prev = src[i];\n }\n return -1;\n}\n\n/**\n * `content` with each navigation listener's arguments cut out, up to the paren that closes the\n * call. What's left runs once, at load. A handler defined elsewhere and passed by name stays in,\n * and its checks still count: the scan can't tell where it runs, so it keeps the full load.\n */\nfunction stripNavigationListeners(content: string): string {\n let out = '';\n let from = 0;\n for (const match of content.matchAll(SPA_LISTENER)) {\n if (match.index < from) continue;\n const end = closingParen(content, content.indexOf('(', match.index));\n // Never closes, or the scan lost its place: keep the rest, so its checks still count.\n if (end < 0) break;\n out += content.slice(from, match.index);\n from = end;\n }\n return out + content.slice(from);\n}\n\n/** Index of the newline at or after `from`, or the end. */\nfunction lineEnd(src: string, from: number): number {\n const at = src.indexOf('\\n', from);\n return at < 0 ? src.length : at;\n}\n\n/** Whether `src` opens a comment at `i`. */\nconst isComment = (src: string, i: number) =>\n src[i] === '/' && (src[i + 1] === '/' || src[i + 1] === '*');\n\n/**\n * Index just past the comment, string or regex literal that opens at `i`, or -1 when code (or a\n * template literal, which holds code) starts there. `prev` is the last code character before it.\n */\nfunction literalEnd(src: string, i: number, prev: string): number {\n const c = src[i];\n if (isComment(src, i)) {\n if (src[i + 1] === '/') return lineEnd(src, i);\n const close = src.indexOf('*/', i + 2);\n return close < 0 ? src.length : close + 2;\n }\n if (c === '\"' || c === \"'\") {\n const close = stringEnd(src, i);\n return close < 0 ? lineEnd(src, i) : close + 1;\n }\n if (c === '/' && BEFORE_REGEX.test(prev)) {\n const close = regexEnd(src, i);\n return close < 0 ? -1 : close + 1;\n }\n return -1;\n}\n\n/**\n * Clears `code` over the template literal opened at `start`, all but the code inside its\n * `${…}`, which runs like any other. Returns the index of its closing backtick.\n */\nfunction maskTemplate(src: string, code: Uint8Array, start: number): number {\n code[start] = 0;\n for (let i = start + 1; i < src.length; i++) {\n code[i] = 0;\n if (src[i] === '\\\\') code[++i] = 0;\n else if (src[i] === '`') return i;\n else if (src[i] === '$' && src[i + 1] === '{') {\n code[i + 1] = 0;\n i = maskCode(src, code, i + 2, true);\n code[i] = 0;\n }\n }\n return src.length;\n}\n\n/**\n * Clears `code` over the comments and literals of the script from `from`. Inside a template's\n * `${…}` (`inExpression`), it stops at the `}` that closes it and returns that index.\n */\nfunction maskCode(src: string, code: Uint8Array, from: number, inExpression = false): number {\n let prev = '(';\n let braces = 0;\n for (let i = from; i < src.length; i++) {\n const c = src[i];\n if (/\\s/.test(c)) continue;\n const end = literalEnd(src, i, prev);\n if (end >= 0) {\n code.fill(0, i, end);\n // A literal is a value, so a `/` after it divides; a comment changes nothing.\n if (!isComment(src, i)) prev = 'a';\n i = end - 1;\n continue;\n }\n if (c === '`') {\n i = maskTemplate(src, code, i);\n prev = 'a';\n continue;\n }\n if (inExpression && c === '}' && braces-- === 0) return i;\n if (c === '{') braces++;\n prev = c;\n }\n return src.length;\n}\n\n/** Which characters of a script are code: not in a comment, string or template text. */\nfunction scriptMask(src: string): Uint8Array {\n const code = new Uint8Array(src.length).fill(1);\n maskCode(src, code, 0);\n return code;\n}\n\n/** A `type` the browser runs as JavaScript: none, `module`, or a JavaScript MIME type. */\nconst JS_TYPE = /^(?:|module|(?:text|application)\\/(?:x-)?(?:java|ecma)script)$/i;\n\n/**\n * The JavaScript an inline snippet runs: the text of its `<script>` elements, parsed by the\n * browser as `injectHtml` parses it, so attributes, quotes and the HTML around a script read as\n * they will on the page. A snippet with no `<script>` tag, or a scan with no DOM, reads whole.\n */\nfunction snippetScripts(snippet: string): string[] {\n if (!/<script\\b/i.test(snippet) || typeof document === 'undefined') return [snippet];\n const tpl = document.createElement('template');\n tpl.innerHTML = snippet;\n return Array.from(tpl.content.querySelectorAll('script'))\n .filter((script) => JS_TYPE.test(script.type.trim()))\n .map((script) => script.text);\n}\n\n/** `is_page('product.single')` with a literal slug. */\nconst IS_PAGE_LITERAL = /\\bis_page\\s*\\(\\s*['\"]([\\w.-]+)['\"]\\s*\\)/g;\n\n/**\n * A negated check, `!salla.url.is_page('cart')`, `!(is_page('cart'))` or\n * `is_page('cart') === false`: it acts on every page but the one it names, so that slug says\n * nothing about where it acts.\n */\n// Character classes for the `(` and `salla.url.` prefixes, not repeated groups: no nested\n// quantifier to backtrack on, as the snippet text is the app's.\nconst IS_PAGE_NEGATED =\n /![\\s(]*[\\w$.]*is_page\\s*\\(\\s*['\"][\\w.-]+['\"]\\s*\\)|\\bis_page\\s*\\(\\s*['\"][\\w.-]+['\"]\\s*\\)\\s*={2,3}\\s*false\\b/g;\n\n/**\n * The pages an inline snippet's code depends on: the slugs it passes to `is_page` as a literal,\n * or nothing when it doesn't care or reads the page only inside a `page::view` listener.\n *\n * Only a literal, positive check counts. A negated one, `page.slug`, `config.get('page')` or a\n * slug held in a variable would point at every page, and a full load on every navigation costs\n * the whole store its in-browser navigation (#513), so those snippets keep running once.\n */\nexport function snippetPageTargets(snippet: string): string[] {\n const slugs = new Set<string>();\n for (const script of snippetScripts(snippet)) {\n for (const slug of scriptPageTargets(script)) slugs.add(slug);\n }\n return [...slugs];\n}\n\n/** The slugs one script checks with a literal, positive `is_page`, in code that runs at load. */\nfunction scriptPageTargets(script: string): string[] {\n const content = stripNavigationListeners(script);\n const code = scriptMask(content);\n const negated = [...content.matchAll(IS_PAGE_NEGATED)].map(\n (m) => [m.index, m.index + m[0].length] as const\n );\n return [...content.matchAll(IS_PAGE_LITERAL)]\n .filter(\n ({ index }) => code[index] && !negated.some(([from, to]) => index >= from && index < to)\n )\n .map((m) => m[1]);\n}\n\n/** Pages that need a full load, across every installed app's inline snippets. */\nlet targets = new Set<string>();\n\n/** Told whether any page needs a full load, each time the snippets are recorded. */\ntype TargetsListener = (active: boolean) => void;\nconst listeners = new Set<TargetsListener>();\n\n/**\n * Calls `listener` now and whenever the snippets are recorded, with whether any page needs a full\n * load. The router installs its navigation blocker only while one does: a blocker makes every\n * history push wait a tick, which stores without such snippets shouldn't pay for.\n */\nexport function subscribeSnippetPageTargets(listener: TargetsListener): () => void {\n listeners.add(listener);\n listener(targets.size > 0);\n return () => listeners.delete(listener);\n}\n\n/**\n * Records the installed apps' inline snippets. CDN snippets are not scanned: their code is on\n * another origin. `AppsSnippets` calls this once the snippets are known.\n */\nexport function setSnippetPageTargets(\n snippets: ReadonlyArray<{ content: string; url?: string | null }>\n): void {\n const next = new Set<string>();\n for (const s of snippets) {\n if (s.url) continue;\n for (const slug of snippetPageTargets(s.content)) next.add(slug);\n }\n targets = next;\n listeners.forEach((listener) => listener(next.size > 0));\n if (next.size && typeof console !== 'undefined') {\n console.warn(\n '[salla] app snippets depend on the page; navigating to or from these pages reloads the document:',\n [...next]\n );\n }\n}\n\n/**\n * Whether going from the page `from` to the page `to` must load the document fully: when either\n * is a page some app snippet targets. Leaving one matters as much as entering: a widget an app\n * added to <body> for the product page would otherwise stay on the cart.\n */\nexport function needsDocumentLoad(from: string | undefined, to: string | undefined): boolean {\n if (!targets.size) return false;\n return (!!from && targets.has(from)) || (!!to && targets.has(to));\n}\n\n/** @internal Test-only. */\nexport function resetSnippetPageTargets(): void {\n targets = new Set();\n listeners.forEach((listener) => listener(false));\n}\n","import type { HeadDescriptor, HeadResult } from '../../utils/head';\nimport { mergeHead, resolveHead } from '../../utils/head';\nimport { buildBaseHead } from '../../utils/baseHead';\nimport { FALLBACK_LOCALE } from '../../providers/locale-constants';\nimport { getTwilightContext } from '../../twilight/context';\nimport type { TwilightContextMatch } from '../../twilight/ensure-context';\nimport { ensureTwilightContextFromMatches } from '../../twilight/ensure-context';\nimport type { StoreContext } from '../../api/store';\nimport type { AppSnippet } from '../../api/apps';\nimport { SettingsError } from '../../utils/errors';\nimport { renderAppScopeInstallScript } from '../../utils/app-scope';\nimport { renderThemeHookSlotsScript } from '../../utils/theme-hook-slots';\nimport { escapeForInlineScript } from '../../utils/inline-script';\nimport { readEnv, renderRuntimeEnvScript } from '../../utils/runtime-env';\n\nconst SALLA_ICONS_CSS_URL = 'https://cdn.assets.salla.network/static/fonts/sallaicons.css?v=2.0.5';\nconst LIT_VERSION = '3.3.3';\nconst LIT_CDN_BASE = `https://cdn.assets.salla.network/static/lit/${LIT_VERSION}`;\n\n/** Bare-specifier map for the lit build the engine's `<salla-*>` web components resolve against. */\nconst LIT_IMPORTS: Record<string, string> = {\n lit: `${LIT_CDN_BASE}/lit.js`,\n 'lit/': `${LIT_CDN_BASE}/`,\n 'lit-html': `${LIT_CDN_BASE}/lit-html/lit-html.js`,\n 'lit-html/': `${LIT_CDN_BASE}/lit-html/`,\n 'lit-element': `${LIT_CDN_BASE}/lit-element/lit-element.js`,\n 'lit-element/': `${LIT_CDN_BASE}/lit-element/`,\n '@lit/reactive-element': `${LIT_CDN_BASE}/reactive-element/reactive-element.js`,\n '@lit/reactive-element/': `${LIT_CDN_BASE}/reactive-element/`,\n};\n\nexport const TICKETING_SCRIPT_URL =\n 'https://cdn.assets.salla.network/latest/@salla.sa/ui-store-ticketing-system/ticketing-system.es.js';\n\nconst TWILIGHT_RELEASE_CDN = 'https://cdn.salla.network/js/twilight';\nconst TWILIGHT_DEV_CDN = 'https://cdn.assets.salla.network/dev/@salla.sa/twilight';\n// The oldest Twilight release this engine works with. Raise it whenever the engine\n// starts relying on something newer; the reason lives in that commit. Today's floor:\n// components ship their own CSS, which themes no longer compile (SallaApp/twilight#2107).\nconst MIN_TWILIGHT_VERSION = '2.14.538';\n// Last resort when no override and no platform pin, and the substitute for a pin below the floor.\nconst DEFAULT_TWILIGHT_VERSION = '2.14.584';\nconst releaseUrl = (version: string): string =>\n `${TWILIGHT_RELEASE_CDN}/${version}/twilight.esm.js`;\n// The head is built more than once per request (early hints, then the page); say it once.\nconst warnedPins = new Set<string>();\n\n/** `x.y.z` release pins only; dev shas and other strings are loaded as given. */\nfunction belowMinimum(version: string): boolean {\n return (\n /^\\d+\\.\\d+\\.\\d+$/.test(version) &&\n version.localeCompare(MIN_TWILIGHT_VERSION, undefined, { numeric: true }) < 0\n );\n}\n\n/** The `x.y.z` release segment of a release-CDN `.../twilight.esm.js` URL, if present. */\nfunction releaseVersionInUrl(url: string): string | null {\n const match = url.match(/\\/(\\d+\\.\\d+\\.\\d+)\\/twilight\\.esm\\.js(?:[?#]|$)/);\n return match ? match[1] : null;\n}\n\n/**\n * `VITE_TWILIGHT_URL`/`VITE_TWILIGHT_VERSION` outrank everything below, including\n * `theme.twilight.version`'s own `belowMinimum` guard — a stale override wins\n * silently otherwise (TD-16375: a scaffold-time pin outlived the engine raising\n * MIN_TWILIGHT_VERSION, so every new theme rendered without component CSS and\n * nothing said why). Only a dev-mode nudge, not a swap: an env override is a\n * deliberate choice, so unlike the settings-pin path below this never substitutes\n * the engine default underneath the developer.\n */\nfunction warnIfOverrideBelowMinimum(source: string, version: string): void {\n // Worker logs in production should stay quiet -- this is a developer-directed nudge,\n // not a user-facing or production-monitored signal. import.meta.env.DEV is a static\n // false in production builds, so this branch (and the console.warn below) is\n // tree-shaken out entirely, same as DevSettingsWidget / dev-settings-store.ts.\n if (!import.meta.env.DEV) return;\n if (!belowMinimum(version)) return;\n const key = `${source}:${version}`;\n if (warnedPins.has(key)) return;\n warnedPins.add(key);\n console.warn(\n `[twilight] ${source}=${version} is below the engine minimum ${MIN_TWILIGHT_VERSION} — components may load without their CSS (SallaApp/twilight#2107). Unset it or bump it to ${MIN_TWILIGHT_VERSION}+.`\n );\n}\n\n/**\n * Which twilight.esm.js the storefront loads, in priority order:\n * 1. `VITE_TWILIGHT_URL` — full local/deployment override.\n * 2. `VITE_TWILIGHT_VERSION` — dev-CDN build override.\n * 3. `theme.twilight.version` from the settings endpoint — the platform-pinned\n * release used when no environment override is configured.\n * 4. The engine's default release, also used when the pin is below the engine minimum.\n */\nexport function resolveTwilightSdkUrl(settings?: StoreContext): string {\n const urlOverride = readEnv('VITE_TWILIGHT_URL');\n if (urlOverride) {\n const version = releaseVersionInUrl(urlOverride);\n if (version) warnIfOverrideBelowMinimum('VITE_TWILIGHT_URL', version);\n return urlOverride;\n }\n\n const versionOverride = readEnv('VITE_TWILIGHT_VERSION');\n if (versionOverride) {\n warnIfOverrideBelowMinimum('VITE_TWILIGHT_VERSION', versionOverride);\n return `${TWILIGHT_DEV_CDN}/${versionOverride}/twilight.esm.js`;\n }\n\n const pinnedVersion = settings?.theme?.twilight?.version;\n if (pinnedVersion && belowMinimum(pinnedVersion)) {\n if (!warnedPins.has(pinnedVersion)) {\n warnedPins.add(pinnedVersion);\n console.warn(\n `[twilight] theme.twilight.version ${pinnedVersion} is below the engine minimum ${MIN_TWILIGHT_VERSION}; loading ${DEFAULT_TWILIGHT_VERSION} instead`\n );\n }\n return releaseUrl(DEFAULT_TWILIGHT_VERSION);\n }\n if (pinnedVersion) return releaseUrl(pinnedVersion);\n\n return releaseUrl(DEFAULT_TWILIGHT_VERSION);\n}\n\n// On a page that preloads its LCP image, the icon font (~270 KB) applies once the first screen's\n// priority images have painted, so it doesn't compete with them; other pages swap on load.\nconst MEDIA_SWAP_SCRIPT = `\n(function(){var d=document,s=function(l){if(l.sheet||\"all\"===l.media)l.media=\"all\";else l.onload=function(){this.media=\"all\"}},f=d.getElementById(\"salla-theme-font\"),i=d.getElementById(\"salla-icons-css\");f&&s(f);if(!i)return;if(!d.querySelector('link[rel=\"preload\"][as=\"image\"]'))return s(i);var g=function(){g=function(){};s(i)},p=function(){requestAnimationFrame(function(){setTimeout(function(){g()})});setTimeout(function(){g()},100)};d.addEventListener(\"DOMContentLoaded\",function(){var m=[].filter.call(d.querySelectorAll('img[fetchpriority=\"high\"]'),function(x){return!x.complete}),n=m.length;if(!n)return p();m.forEach(function(x){var o=function(){--n||p()};x.addEventListener(\"load\",o,{once:!0});x.addEventListener(\"error\",o,{once:!0})});setTimeout(function(){g()},2500)})})();\n`.trim();\n\nconst LOADING_CSS = `\n.loading-overlay{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:#fff;z-index:9999}\n.loading-spinner{animation:spin 1s linear infinite;border-radius:9999px;height:3rem;width:3rem;border-bottom:2px solid var(--color-primary,#000)}\n@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}\nhtml,body{margin:0;padding:0;height:100%}\n`.trim();\n\nconst SALLA_INIT_SCRIPT = `\nwindow.salla = window.Salla = window.Salla || window.salla || {};\nwindow.Salla.onReady = window.Salla.onReady || function(callback) {\n return new Promise(function(resolve) {\n if (window.Salla.status === 'ready') {\n var config = window.salla && window.salla.config && window.salla.config.all();\n resolve(callback ? callback(config) : config);\n } else {\n window.addEventListener('twilight::initiated', function(event) {\n resolve(callback ? callback(event.detail) : event.detail);\n }, { once: true });\n }\n });\n};\n`.trim();\n\n/**\n * Distinct snippet-host origins to `preconnect` (warm DNS/TCP/TLS during parse). From the real\n * URLs (dev/prod-correct), deduped and capped at 4. No `crossOrigin`: snippets are no-cors fetches.\n */\nexport function snippetPreconnectOrigins(snippets: readonly AppSnippet[] | undefined): string[] {\n if (!snippets?.length) return [];\n const origins = new Set<string>();\n for (const app of snippets) {\n if (app.status !== 'enabled') continue;\n for (const s of app.snippets) {\n if (!s.url) continue;\n try {\n origins.add(new URL(s.url).origin);\n } catch {\n /* skip a malformed snippet url rather than breaking the head */\n }\n if (origins.size >= 4) return [...origins];\n }\n }\n return [...origins];\n}\n\nexport function rootHead(ctx: {\n params: Record<string, string>;\n matches?: readonly TwilightContextMatch[];\n}): HeadResult {\n // Re-run on the client during hydration, where the twilight module store may\n // still be empty. Recover it from the resolved match context so the head is\n // built from real settings instead of falling through to 'Store Unavailable'.\n ensureTwilightContextFromMatches(ctx.matches);\n\n let settings: StoreContext | undefined;\n try {\n settings = getTwilightContext().settings;\n } catch (e) {\n if (e instanceof SettingsError) {\n return resolveHead({\n title: 'Store Unavailable',\n });\n }\n throw e;\n }\n const locale = ctx.params.locale || FALLBACK_LOCALE;\n const parts = deriveHeadParts(settings);\n\n return resolveHead(\n mergeHead(buildBaseHead(settings, locale), {\n meta: buildRootMeta(parts),\n links: buildRootLinks(parts),\n styles: buildRootStyles(parts),\n importMap: [{ imports: LIT_IMPORTS }],\n scripts: buildRootScripts(parts),\n })\n );\n}\n\n/** Everything the root head's tag builders read, derived once from the store settings. */\ninterface RootHeadParts {\n store: StoreContext['store'] | undefined;\n favicon?: string;\n primaryColor?: string;\n fontUrl?: string;\n fontUrlWithDisplay?: string;\n isGoogleFont?: boolean;\n fontFamilyName?: string;\n customJs?: string;\n customCss?: string;\n isCustomCssUrl?: boolean;\n isCustomJsUrl?: boolean;\n twilightSdkUrl: string;\n /** The visitor gets the maintenance page, which loads no SDK and no app snippets. */\n maintenance: boolean;\n snippetPreconnects: Array<{ rel: 'preconnect'; href: string }>;\n appScopeInstallScript: string;\n themeHookSlotsScript: string | null;\n runtimeEnvScript: string | null;\n}\n\n/** Google Fonts only honours `display=swap` as a query param; other hosts get the @font-face\n * override instead (see buildRootStyles). */\nfunction deriveFontParts(theme?: StoreContext['theme']) {\n const font = theme?.font;\n const fontUrl = font?.url || font?.path;\n const isGoogleFont = fontUrl?.includes('fonts.googleapis.com');\n const needsDisplay = Boolean(isGoogleFont && fontUrl && !fontUrl.includes('display='));\n const separator = fontUrl?.includes('?') ? '&' : '?';\n\n return {\n fontUrl,\n isGoogleFont,\n fontFamilyName: font?.family_name,\n fontUrlWithDisplay: needsDisplay ? `${fontUrl}${separator}display=swap` : fontUrl,\n };\n}\n\n/** Theme customization JS/CSS, each either a URL to load or an inline blob to embed. */\nfunction deriveCustomizationParts(theme?: StoreContext['theme']) {\n const customization = theme?.customization;\n const customJs = customization?.js?.trim();\n const customCss = customization?.css?.trim();\n const isUrl = (value?: string): boolean =>\n Boolean(value?.startsWith('http') || value?.startsWith('//'));\n\n return {\n customJs,\n customCss,\n isCustomCssUrl: isUrl(customCss),\n isCustomJsUrl: isUrl(customJs),\n };\n}\n\nfunction deriveHeadParts(settings?: StoreContext): RootHeadParts {\n const store = settings?.store;\n\n return {\n store,\n favicon: store?.icon,\n primaryColor: settings?.theme?.color?.primary,\n ...deriveFontParts(settings?.theme),\n ...deriveCustomizationParts(settings?.theme),\n twilightSdkUrl: resolveTwilightSdkUrl(settings),\n maintenance: getTwilightContext().maintenance,\n // Warm the connection to the snippet host(s) during head parse, so the body's deferred\n // `<script src>` snippet tags fetch off an already-open socket instead of DNS+TCP+TLS.\n snippetPreconnects: snippetPreconnectOrigins(getTwilightContext().appsSnippets).map((href) => ({\n rel: 'preconnect' as const,\n href,\n })),\n // Install `Salla.appScope` inline at parse time, before the SDK is ready — else a snippet's\n // onReady callback calls it too early and throws. Always emitted, even when the settings\n // prefetch failed: the CDN snippet tags ship regardless (they come from the *snippets*\n // endpoint), so the factory has to exist for them. `installAppScope` then seeds the real\n // buckets into this install once the client query resolves.\n appScopeInstallScript: renderAppScopeInstallScript(\n getTwilightContext().appsSettings ?? { apps: {} }\n ),\n // Whitelist the theme's own hook slots at parse time too, for the same reason: apps register\n // their `onReady` callbacks from parser-inserted snippet tags, long before React hydrates.\n themeHookSlotsScript: renderThemeHookSlotsScript(),\n // Env this render resolved (worker `vars` live in server-only `process.env`), handed to the\n // client so it doesn't silently fall back to the production defaults. Re-rendered on the\n // client during hydration, where it resolves to the same values or to nothing.\n runtimeEnvScript: renderRuntimeEnvScript(),\n };\n}\n\nfunction buildRootMeta(p: RootHeadParts): NonNullable<HeadDescriptor['meta']> {\n return [\n { name: 'robots', content: 'index, follow' },\n { name: 'msapplication-TileColor', content: '#ffffff' },\n ...(p.favicon ? [{ name: 'msapplication-TileImage', content: p.favicon }] : []),\n ...(p.primaryColor\n ? [\n { name: 'theme-color', content: p.primaryColor },\n { name: 'msapplication-navbutton-color', content: p.primaryColor },\n { name: 'apple-mobile-web-app-status-bar-style', content: p.primaryColor },\n ]\n : []),\n ];\n}\n\nfunction buildRootLinks(p: RootHeadParts): NonNullable<HeadDescriptor['links']> {\n return [\n { rel: 'preconnect', href: 'https://api.salla.dev' },\n { rel: 'preconnect', href: 'https://cdn.salla.sa' },\n { rel: 'preconnect', href: 'https://cdn.assets.salla.network', crossOrigin: 'anonymous' },\n // Warm the installed apps' CDN snippet host(s) — see snippetPreconnectOrigins.\n // Not on the maintenance page: it renders neither the snippets nor the SDK.\n ...(p.maintenance ? [] : p.snippetPreconnects),\n ...(p.isGoogleFont\n ? [\n {\n rel: 'preconnect' as const,\n href: 'https://fonts.gstatic.com',\n crossOrigin: 'anonymous' as const,\n },\n ]\n : []),\n ...(p.maintenance ? [] : [{ rel: 'modulepreload' as const, href: p.twilightSdkUrl }]),\n ...(p.fontUrlWithDisplay\n ? [\n {\n id: 'salla-theme-font',\n rel: 'stylesheet',\n href: p.fontUrlWithDisplay,\n media: 'print',\n },\n ]\n : []),\n ...(p.fontUrlWithDisplay && !p.isGoogleFont && p.fontFamilyName\n ? [\n {\n id: 'salla-font-display-override',\n rel: 'preload',\n as: 'style',\n href: p.fontUrlWithDisplay,\n },\n ]\n : []),\n ...(p.favicon ? [{ rel: 'icon', href: p.favicon }] : []),\n ...(p.favicon\n ? [{ id: 'salla-apple-icon', rel: 'apple-touch-icon-precomposed', href: p.favicon }]\n : []),\n ...(p.isCustomCssUrl && p.customCss\n ? [{ id: 'salla-custom-css', rel: 'stylesheet', href: p.customCss }]\n : []),\n {\n id: 'salla-icons-css',\n rel: 'stylesheet',\n href: SALLA_ICONS_CSS_URL,\n media: 'print',\n },\n // {\n // id: 'intl-tel-input-css',\n // rel: 'stylesheet',\n // href: 'https://cdn.jsdelivr.net/npm/intl-tel-input@26.8.0/build/css/intlTelInput.css',\n // },\n ...(p.isCustomJsUrl && p.customJs\n ? [{ id: 'salla-custom-js-preload', rel: 'preload', as: 'script', href: p.customJs }]\n : []),\n ];\n}\n\n// Hoistable (href + precedence): the web components insert their own <style> near the top of\n// <head> before hydration, which a positionally hydrated <style> would be matched against.\nconst hoisted = (id: string, children: string) => ({\n id,\n href: id,\n precedence: 'default',\n children,\n});\n\nfunction buildRootStyles(p: RootHeadParts): NonNullable<HeadDescriptor['styles']> {\n return [\n hoisted('twilight-loading', LOADING_CSS),\n ...(!p.isGoogleFont && p.fontFamilyName\n ? [\n hoisted(\n 'salla-font-display-swap',\n `@font-face{font-family:\"${p.fontFamilyName}\";font-display:swap;src:local(\"${p.fontFamilyName}\")}`\n ),\n ]\n : []),\n ...(!p.isCustomCssUrl && p.customCss ? [hoisted('salla-custom-css', p.customCss)] : []),\n ];\n}\n\nfunction buildRootScripts(p: RootHeadParts): NonNullable<HeadDescriptor['scripts']> {\n return [\n // First: the API base / store identifier this render used, so the hydrated client\n // resolves the same ones (worker `vars` never reach the browser bundle on their own).\n ...(p.runtimeEnvScript ? [{ id: 'salla-runtime-env', children: p.runtimeEnvScript }] : []),\n { id: 'twilight-init', children: SALLA_INIT_SCRIPT },\n // After twilight-init (which defines window.Salla) and before the SDK module, so the\n // appScope factory exists ahead of any snippet's onReady callback firing.\n { id: 'salla-app-scope', children: p.appScopeInstallScript },\n // Arms the hook-slot whitelist push here, so its `twilight::initiated` listener is\n // registered before any app snippet's — listeners fire in registration order.\n ...(p.themeHookSlotsScript\n ? [{ id: 'salla-theme-hook-slots', children: p.themeHookSlotsScript }]\n : []),\n { id: 'salla-async-css', children: MEDIA_SWAP_SCRIPT },\n // The SDK and ticketing modules are rendered at the end of <body> (SallaSdkScripts).\n ...(p.customJs ? [buildCustomJsScript(p.customJs, Boolean(p.isCustomJsUrl))] : []),\n ];\n}\n\n/** A URL customization is loaded after SDK init; an inline one is wrapped so a syntax/runtime\n * error in partner JS warns instead of taking the page down. */\nfunction buildCustomJsScript(customJs: string, isUrl: boolean) {\n return {\n id: 'salla-custom-js',\n children: isUrl\n ? `window.addEventListener('twilight::initiated',function(){var s=document.createElement('script');s.src=${escapeForInlineScript(JSON.stringify(customJs))};s.async=true;document.head.appendChild(s)},{once:true});`\n : `try { ${customJs} } catch(e) { console.warn(\"[ThemeCustomization] Custom JS error:\", e); }`,\n };\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { orThrow } from './chunk-
|
|
2
|
-
import { getActiveScope, api } from './chunk-
|
|
1
|
+
import { orThrow } from './chunk-O3XMYDNC.js';
|
|
2
|
+
import { getActiveScope, api } from './chunk-RB7RHMKJ.js';
|
|
3
3
|
import { getTwilightContext } from './chunk-6K34BCUP.js';
|
|
4
4
|
import { defaultShouldDehydrateQuery, queryOptions } from '@tanstack/react-query';
|
|
5
5
|
|
|
@@ -215,5 +215,5 @@ var product = {
|
|
|
215
215
|
};
|
|
216
216
|
|
|
217
217
|
export { getProductPreview, isProductPreviewQuery, parseNextPageToken, product, productDetailQueryKey, productPreviewQueryKey, rememberProductPreview, shouldDehydrateQuery };
|
|
218
|
-
//# sourceMappingURL=chunk-
|
|
219
|
-
//# sourceMappingURL=chunk-
|
|
218
|
+
//# sourceMappingURL=chunk-ZUVBDALM.js.map
|
|
219
|
+
//# sourceMappingURL=chunk-ZUVBDALM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/product.ts"],"names":["product"],"mappings":"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","file":"chunk-EE7SB3QH.js","sourcesContent":["import { queryOptions, defaultShouldDehydrateQuery } from '@tanstack/react-query';\nimport { api, getActiveScope } from './client';\nimport type { Product } from '../types';\nimport type { Pagination, PaginatedResult } from './types';\nimport { orThrow } from '../providers/NavigationProvider';\nimport { getTwilightContext } from '../twilight/context';\nimport type { ActiveScope } from '../utils/cookies';\n\n// ===== Filter Types =====\n\nexport interface FilterValue {\n key?: string;\n count?: number;\n value?: string;\n from?: number | '*';\n to?: number | '*';\n}\n\nexport interface Filter {\n key?: string;\n label?: string;\n type?: string;\n values?: FilterValue[];\n max?: number;\n min?: number;\n}\n\n// ===== Product List Types =====\n\nexport type ProductsListSource =\n | 'brands'\n | 'categories'\n | 'json'\n | 'landing-page'\n | 'latest'\n | 'offers'\n | 'recently'\n | 'related'\n | 'selected'\n | 'tags'\n | 'top-rated'\n | 'wishlist'\n | 'search'\n | 'sales'\n | 'reorder'\n | 'best_selling';\n\nexport interface ProductsListParams {\n /** Source type (wishlist, latest, brands, etc.) */\n source: ProductsListSource;\n /**\n * The ids the source reads, as an array: category, brand, tag or product ids\n * (`sourceValue: [708738657]`). Sent as `source_value[]`.\n */\n sourceValue?: string | number | number[] | null;\n /** The search words when `source` is `'search'`. Sent as `keyword`; other sources ignore it. */\n keyword?: string;\n /** Page number for offset-based pagination */\n page?: number;\n /** Cursor for cursor-based pagination (from previous response) */\n cursor?: string | null;\n /** Items per page (default: 15) */\n perPage?: number;\n /** Sort option */\n sort?: string;\n /** Enable filters on the response */\n filterable?: boolean;\n /** Applied `<salla-filters>` selection (the `salla-filters::changed` payload). */\n filters?: ProductListFilters;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n}\n\n/** One `<salla-filters>` value: a scalar, a list, or a nested `{ sub-key: value }` (variants). */\nexport type ProductListFilterValue =\n string | number | Array<string | number> | { [key: string]: ProductListFilterValue };\n\n/** A `<salla-filters>` selection, i.e. the `salla-filters::changed` payload. */\nexport type ProductListFilters = Record<string, ProductListFilterValue>;\n\nexport type ProductsListResult = PaginatedResult<Product> & {\n filters?: Filter[];\n};\n\nexport interface ProductsListResponse {\n data: Product[];\n cursor?: Pagination;\n filters?: Filter[];\n}\n\n// ===== List-card preview cache =====\n// List payloads are a subset of details (one `image`, no `options` / `images[]`).\n// They live on a separate query key so they can paint a sheet/quick-view without\n// being treated as a successful `products/{id}/details` fetch.\n\nfunction queryClientOrNull() {\n try {\n const queryClient = getTwilightContext().queryClient;\n return queryClient && typeof queryClient.setQueryData === 'function' ? queryClient : null;\n } catch {\n return null;\n }\n}\n\nexport function productPreviewQueryKey(id: string) {\n return ['products', 'preview', String(id), { scope: getActiveScope() }] as const;\n}\n\nexport function productDetailQueryKey(id: string) {\n return ['products', 'detail', id, { scope: getActiveScope() }] as const;\n}\n\n/** True when this query is a list-card stand-in — skip it when dehydrating SSR. */\nexport function isProductPreviewQuery(query: { queryKey: readonly unknown[] }): boolean {\n return query.queryKey[0] === 'products' && query.queryKey[1] === 'preview';\n}\n\n/**\n * Default dehydrate policy (success) plus pending SSR-stream queries, minus\n * list-card stand-ins. Replacing the default wholesale would ship error states.\n */\nexport function shouldDehydrateQuery(\n query: Parameters<typeof defaultShouldDehydrateQuery>[0]\n): boolean {\n return (\n !isProductPreviewQuery(query) &&\n (defaultShouldDehydrateQuery(query) || query.state.status === 'pending')\n );\n}\n\n/**\n * Remember a list/card product so `product.queries.detail(id)` can use it as\n * `placeholderData` while details load. No-op if details for this id are already\n * cached. Themes that fetch products outside `product.list` should call this.\n */\nexport function rememberProductPreview(product: Product): void {\n const queryClient = queryClientOrNull();\n if (!queryClient || product?.id == null) return;\n const id = String(product.id);\n if (queryClient.getQueryState(productDetailQueryKey(id))?.status === 'success') return;\n queryClient.setQueryData(productPreviewQueryKey(id), product);\n}\n\nfunction scopeFromQueryKey(queryKey: readonly unknown[]): ActiveScope | null | undefined {\n const last = queryKey[queryKey.length - 1];\n if (last == null || typeof last !== 'object' || !('scope' in last)) return undefined;\n return (last as { scope: ActiveScope | null }).scope;\n}\n\nfunction isSameScope(a: ActiveScope | null | undefined, b: ActiveScope | null): boolean {\n if (a === undefined) return false;\n if (a === b) return true;\n if (a == null || b == null) return a == null && b == null;\n return (\n a.id === b.id &&\n a.type === b.type &&\n a.allocation_id === b.allocation_id &&\n a.allocation_type === b.allocation_type\n );\n}\n\nconst LIST_QUERY_PREFIXES = [\n ['products', 'list'],\n ['wishlist', 'list'],\n] as const;\n\n/**\n * Rebuild the scoped preview index from hydrated list/wishlist queries (SSR\n * dehydrate drops preview keys). Subsequent lookups hit `productPreviewQueryKey`.\n */\nfunction findProductInScopedLists(\n queryClient: NonNullable<ReturnType<typeof queryClientOrNull>>,\n id: string\n): Product | undefined {\n const scope = getActiveScope();\n let found: Product | undefined;\n for (const prefix of LIST_QUERY_PREFIXES) {\n for (const [queryKey, data] of queryClient.getQueriesData<ProductsListResult>({\n queryKey: prefix,\n })) {\n if (!isSameScope(scopeFromQueryKey(queryKey), scope)) continue;\n for (const item of data?.items ?? []) {\n if (item?.id == null) continue;\n rememberProductPreview(item);\n if (!found && String(item.id) === id) found = item;\n }\n }\n }\n return found;\n}\n\n/**\n * List-card product for `placeholderData`. Prefers the preview key; if that was\n * dropped on SSR dehydrate, rebuilds it from the current-scope list/wishlist.\n */\nexport function getProductPreview(id: string): Product | undefined {\n const queryClient = queryClientOrNull();\n if (!queryClient) return undefined;\n const key = String(id);\n return (\n queryClient.getQueryData(productPreviewQueryKey(key)) ??\n findProductInScopedLists(queryClient, key)\n );\n}\n\nfunction rememberProductPreviews(items: Product[]): void {\n for (const item of items) rememberProductPreview(item);\n}\n\n/**\n * Search sends its words as `keyword` (a `sourceValue` string is still read there, as before);\n * every other source sends its ids as `source_value[]`, which the API requires as an array.\n */\nfunction appendSourceParams(\n searchParams: URLSearchParams,\n { source, sourceValue, keyword }: Pick<ProductsListParams, 'source' | 'sourceValue' | 'keyword'>\n): void {\n if (source === 'search') {\n const words = keyword ?? sourceValue;\n if (words !== undefined) searchParams.set('keyword', String(words));\n } else if (Array.isArray(sourceValue)) {\n sourceValue.forEach((val) => searchParams.append('source_value[]', String(val)));\n } else if (sourceValue !== undefined) {\n searchParams.append('source_value[]', String(sourceValue));\n }\n}\n\n/**\n * Sends an applied filter selection the way the SDK's `<salla-products-list>` does:\n * `filters[key]=v`, `filters[key][]=v` or `filters[key][sub]=v`.\n */\nfunction appendFilterParams(\n searchParams: URLSearchParams,\n filters?: Record<string, ProductListFilterValue>,\n parentKey = 'filters'\n): void {\n if (!filters) return;\n for (const [key, value] of Object.entries(filters)) {\n const fullKey = `${parentKey}[${key}]`;\n if (Array.isArray(value)) {\n value.forEach((item) => searchParams.append(`${fullKey}[]`, String(item)));\n } else if (value !== null && typeof value === 'object') {\n appendFilterParams(searchParams, value, fullKey);\n } else if (value !== undefined && value !== null) {\n searchParams.append(fullKey, String(value));\n }\n }\n}\n\n/** A `category_id` filter replaces the page's category as the list source (as in the SDK). */\n// The API sends these four filter titles in Arabic whatever the language (the values are\n// translated). Twig's `<salla-filters>` swaps them for its own translations when the list\n// reaches it through `filters::fetched`; a list handed over as data, the loader's or a\n// theme's own query, is swapped here instead, with the keys the component uses.\nconst FILTER_TITLES: Record<string, [key: string, fallback: string]> = {\n category_id: ['common.titles.categories', 'Categories'],\n brand_id: ['common.titles.brands', 'Brands'],\n price: ['pages.categories.filter_price', 'Price'],\n rating: ['pages.categories.filter_rating', 'Rating'],\n};\n\nfunction titledFilters(filters?: Filter[]): Filter[] | undefined {\n const t = getTwilightContext().i18n?.t;\n if (!filters || !t) return filters;\n return filters.map((filter) => {\n const title = filter.key && FILTER_TITLES[filter.key];\n return title ? { ...filter, label: t(title[0], title[1]) } : filter;\n });\n}\n\nfunction categoryFilterIds(filters?: ProductListFilters): number[] | null {\n const raw = filters?.category_id;\n if (raw === undefined || raw === null) return null;\n const ids = Array.isArray(raw) ? raw : typeof raw === 'object' ? Object.values(raw) : [raw];\n return ids.map(Number);\n}\n\n// ===== Pagination =====\n\n/**\n * The API's own `cursor.next` (the previous page's response) is usually a\n * bare opaque cursor token, but for sources that don't support true\n * cursor-based pagination (observed: `source=offers`) it's instead a full\n * next-page URL carrying its own `page=N` — and no `cursor=` param at all.\n *\n * Passing that whole URL straight through as `list()`'s own `cursor` used to\n * smuggle its embedded `source` / `per_page` / `sort` into the request on\n * top of the ones `list()` already sets unconditionally, producing a\n * doubled query string (`source=offers&source=offers&...`) the API can't\n * paginate from correctly — every subsequent scroll re-fetched the exact\n * same first page instead of advancing. Pulling just the `page` number back\n * out here, the same way an actual `cursor=` is already pulled out, keeps\n * `list()`'s request to the one copy of each param it's supposed to have.\n */\nexport function parseNextPageToken(nextUrl: string | null | undefined): {\n cursor?: string;\n page?: number;\n} {\n if (!nextUrl) return {};\n\n const cursorMatch = nextUrl.match(/[?&]cursor=([^&]+)/);\n if (cursorMatch) return { cursor: decodeURIComponent(cursorMatch[1]) };\n\n const pageMatch = nextUrl.match(/[?&]page=([^&]+)/);\n if (pageMatch) {\n const page = Number(decodeURIComponent(pageMatch[1]));\n if (Number.isFinite(page)) return { page };\n }\n\n // Neither pattern matched: not a URL at all, just the bare opaque token itself.\n return { cursor: nextUrl };\n}\n\n// ===== API Functions =====\n\nexport const product = {\n find: async (id: string): Promise<Product> => {\n const endpoint = `products/${id}/details?with[]=images&with[]=category&with[]=rating&with[]=notify_availability&with[]=tags&with[]=brand&with[]=options&with[]=skus&with[]=skus_availability&with[]=included_products&with[]=bundle&with[]=sold_quantity`;\n const { data } = await api.get(endpoint).json<{ data: Product }>();\n return data;\n },\n\n findOrThrow: (id: string): Promise<Product> => orThrow(product.find(id)),\n\n /** A tag's name. The list endpoint returns every product for an unknown tag; this one answers 410. */\n tag: async (id: string): Promise<{ id: number; name: string }> => {\n const { tag } = await api\n .get(`products/tags/${id}`)\n .json<{ tag: { id: number; name: string } }>();\n return tag;\n },\n\n /**\n * Fetch products list with pagination support\n * Used by native ProductsList component for SSR loaders\n *\n * API pattern: GET /products?source=wishlist&page=1\n */\n list: async (params: ProductsListParams): Promise<ProductsListResult> => {\n const {\n source,\n sourceValue,\n keyword,\n page,\n cursor,\n perPage = 16,\n sort,\n filterable,\n filters,\n signal,\n } = params;\n\n // Build URL with query parameters\n const searchParams = new URLSearchParams();\n searchParams.set('source', source);\n // Only send page when explicitly provided — cursor-based callers omit it entirely\n if (page !== undefined) searchParams.set('page', String(page));\n searchParams.set('per_page', String(perPage));\n\n appendSourceParams(searchParams, {\n source,\n sourceValue: (source === 'categories' && categoryFilterIds(filters)) || sourceValue,\n keyword,\n });\n appendFilterParams(searchParams, filters);\n\n // Add filterable parameter\n if (filterable !== undefined) {\n searchParams.set('filterable', filterable ? '1' : '0');\n }\n\n // Add sort parameter\n if (sort) {\n searchParams.set('sort', sort);\n }\n\n // Add cursor for cursor-based pagination\n if (cursor) {\n searchParams.set('cursor', cursor);\n }\n\n // Make the request\n const options: Record<string, unknown> = {};\n if (signal) options.signal = signal;\n\n const response = await api\n .get(`products?${searchParams.toString()}`, options as any)\n .json<ProductsListResponse>();\n\n const items = response.data ?? [];\n rememberProductPreviews(items);\n\n return {\n items,\n next: response.cursor?.next ?? null,\n filters: titledFilters(response.filters),\n };\n },\n\n queries: {\n detail: (id: string) =>\n queryOptions({\n // Stock and availability are resolved per branch allocation — same as the list.\n queryKey: productDetailQueryKey(id),\n queryFn: () => product.find(id),\n // List-card product, if one was remembered. Not written as the detail\n // cache entry — `queryFn` still hits products/{id}/details.\n placeholderData: () => getProductPreview(id),\n }),\n tag: (id: string) =>\n queryOptions({\n queryKey: ['products', 'tag', id],\n queryFn: () => product.tag(id),\n }),\n list: (params: Omit<ProductsListParams, 'signal'>) =>\n queryOptions({\n // Scope (branch) varies product availability, and the locale the names and the\n // filter titles (a same-store link can switch language without a page load) — the\n // key must include both.\n queryKey: [\n 'products',\n 'list',\n params,\n { scope: getActiveScope(), locale: getTwilightContext().locale },\n ],\n queryFn: ({ signal }) => product.list({ ...params, signal }),\n }),\n },\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/api/product.ts"],"names":["product"],"mappings":"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","file":"chunk-ZUVBDALM.js","sourcesContent":["import { queryOptions, defaultShouldDehydrateQuery } from '@tanstack/react-query';\nimport { api, getActiveScope } from './client';\nimport type { Product } from '../types';\nimport type { Pagination, PaginatedResult } from './types';\nimport { orThrow } from '../providers/NavigationProvider';\nimport { getTwilightContext } from '../twilight/context';\nimport type { ActiveScope } from '../utils/cookies';\n\n// ===== Filter Types =====\n\nexport interface FilterValue {\n key?: string;\n count?: number;\n value?: string;\n from?: number | '*';\n to?: number | '*';\n}\n\nexport interface Filter {\n key?: string;\n label?: string;\n type?: string;\n values?: FilterValue[];\n max?: number;\n min?: number;\n}\n\n// ===== Product List Types =====\n\nexport type ProductsListSource =\n | 'brands'\n | 'categories'\n | 'json'\n | 'landing-page'\n | 'latest'\n | 'offers'\n | 'recently'\n | 'related'\n | 'selected'\n | 'tags'\n | 'top-rated'\n | 'wishlist'\n | 'search'\n | 'sales'\n | 'reorder'\n | 'best_selling';\n\nexport interface ProductsListParams {\n /** Source type (wishlist, latest, brands, etc.) */\n source: ProductsListSource;\n /**\n * The ids the source reads, as an array: category, brand, tag or product ids\n * (`sourceValue: [708738657]`). Sent as `source_value[]`.\n */\n sourceValue?: string | number | number[] | null;\n /** The search words when `source` is `'search'`. Sent as `keyword`; other sources ignore it. */\n keyword?: string;\n /** Page number for offset-based pagination */\n page?: number;\n /** Cursor for cursor-based pagination (from previous response) */\n cursor?: string | null;\n /** Items per page (default: 15) */\n perPage?: number;\n /** Sort option */\n sort?: string;\n /** Enable filters on the response */\n filterable?: boolean;\n /** Applied `<salla-filters>` selection (the `salla-filters::changed` payload). */\n filters?: ProductListFilters;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n}\n\n/** One `<salla-filters>` value: a scalar, a list, or a nested `{ sub-key: value }` (variants). */\nexport type ProductListFilterValue =\n string | number | Array<string | number> | { [key: string]: ProductListFilterValue };\n\n/** A `<salla-filters>` selection, i.e. the `salla-filters::changed` payload. */\nexport type ProductListFilters = Record<string, ProductListFilterValue>;\n\nexport type ProductsListResult = PaginatedResult<Product> & {\n filters?: Filter[];\n};\n\nexport interface ProductsListResponse {\n data: Product[];\n cursor?: Pagination;\n filters?: Filter[];\n}\n\n// ===== List-card preview cache =====\n// List payloads are a subset of details (one `image`, no `options` / `images[]`).\n// They live on a separate query key so they can paint a sheet/quick-view without\n// being treated as a successful `products/{id}/details` fetch.\n\nfunction queryClientOrNull() {\n try {\n const queryClient = getTwilightContext().queryClient;\n return queryClient && typeof queryClient.setQueryData === 'function' ? queryClient : null;\n } catch {\n return null;\n }\n}\n\nexport function productPreviewQueryKey(id: string) {\n return ['products', 'preview', String(id), { scope: getActiveScope() }] as const;\n}\n\nexport function productDetailQueryKey(id: string) {\n return ['products', 'detail', id, { scope: getActiveScope() }] as const;\n}\n\n/** True when this query is a list-card stand-in — skip it when dehydrating SSR. */\nexport function isProductPreviewQuery(query: { queryKey: readonly unknown[] }): boolean {\n return query.queryKey[0] === 'products' && query.queryKey[1] === 'preview';\n}\n\n/**\n * Default dehydrate policy (success) plus pending SSR-stream queries, minus\n * list-card stand-ins. Replacing the default wholesale would ship error states.\n */\nexport function shouldDehydrateQuery(\n query: Parameters<typeof defaultShouldDehydrateQuery>[0]\n): boolean {\n return (\n !isProductPreviewQuery(query) &&\n (defaultShouldDehydrateQuery(query) || query.state.status === 'pending')\n );\n}\n\n/**\n * Remember a list/card product so `product.queries.detail(id)` can use it as\n * `placeholderData` while details load. No-op if details for this id are already\n * cached. Themes that fetch products outside `product.list` should call this.\n */\nexport function rememberProductPreview(product: Product): void {\n const queryClient = queryClientOrNull();\n if (!queryClient || product?.id == null) return;\n const id = String(product.id);\n if (queryClient.getQueryState(productDetailQueryKey(id))?.status === 'success') return;\n queryClient.setQueryData(productPreviewQueryKey(id), product);\n}\n\nfunction scopeFromQueryKey(queryKey: readonly unknown[]): ActiveScope | null | undefined {\n const last = queryKey[queryKey.length - 1];\n if (last == null || typeof last !== 'object' || !('scope' in last)) return undefined;\n return (last as { scope: ActiveScope | null }).scope;\n}\n\nfunction isSameScope(a: ActiveScope | null | undefined, b: ActiveScope | null): boolean {\n if (a === undefined) return false;\n if (a === b) return true;\n if (a == null || b == null) return a == null && b == null;\n return (\n a.id === b.id &&\n a.type === b.type &&\n a.allocation_id === b.allocation_id &&\n a.allocation_type === b.allocation_type\n );\n}\n\nconst LIST_QUERY_PREFIXES = [\n ['products', 'list'],\n ['wishlist', 'list'],\n] as const;\n\n/**\n * Rebuild the scoped preview index from hydrated list/wishlist queries (SSR\n * dehydrate drops preview keys). Subsequent lookups hit `productPreviewQueryKey`.\n */\nfunction findProductInScopedLists(\n queryClient: NonNullable<ReturnType<typeof queryClientOrNull>>,\n id: string\n): Product | undefined {\n const scope = getActiveScope();\n let found: Product | undefined;\n for (const prefix of LIST_QUERY_PREFIXES) {\n for (const [queryKey, data] of queryClient.getQueriesData<ProductsListResult>({\n queryKey: prefix,\n })) {\n if (!isSameScope(scopeFromQueryKey(queryKey), scope)) continue;\n for (const item of data?.items ?? []) {\n if (item?.id == null) continue;\n rememberProductPreview(item);\n if (!found && String(item.id) === id) found = item;\n }\n }\n }\n return found;\n}\n\n/**\n * List-card product for `placeholderData`. Prefers the preview key; if that was\n * dropped on SSR dehydrate, rebuilds it from the current-scope list/wishlist.\n */\nexport function getProductPreview(id: string): Product | undefined {\n const queryClient = queryClientOrNull();\n if (!queryClient) return undefined;\n const key = String(id);\n return (\n queryClient.getQueryData(productPreviewQueryKey(key)) ??\n findProductInScopedLists(queryClient, key)\n );\n}\n\nfunction rememberProductPreviews(items: Product[]): void {\n for (const item of items) rememberProductPreview(item);\n}\n\n/**\n * Search sends its words as `keyword` (a `sourceValue` string is still read there, as before);\n * every other source sends its ids as `source_value[]`, which the API requires as an array.\n */\nfunction appendSourceParams(\n searchParams: URLSearchParams,\n { source, sourceValue, keyword }: Pick<ProductsListParams, 'source' | 'sourceValue' | 'keyword'>\n): void {\n if (source === 'search') {\n const words = keyword ?? sourceValue;\n if (words !== undefined) searchParams.set('keyword', String(words));\n } else if (Array.isArray(sourceValue)) {\n sourceValue.forEach((val) => searchParams.append('source_value[]', String(val)));\n } else if (sourceValue !== undefined) {\n searchParams.append('source_value[]', String(sourceValue));\n }\n}\n\n/**\n * Sends an applied filter selection the way the SDK's `<salla-products-list>` does:\n * `filters[key]=v`, `filters[key][]=v` or `filters[key][sub]=v`.\n */\nfunction appendFilterParams(\n searchParams: URLSearchParams,\n filters?: Record<string, ProductListFilterValue>,\n parentKey = 'filters'\n): void {\n if (!filters) return;\n for (const [key, value] of Object.entries(filters)) {\n const fullKey = `${parentKey}[${key}]`;\n if (Array.isArray(value)) {\n value.forEach((item) => searchParams.append(`${fullKey}[]`, String(item)));\n } else if (value !== null && typeof value === 'object') {\n appendFilterParams(searchParams, value, fullKey);\n } else if (value !== undefined && value !== null) {\n searchParams.append(fullKey, String(value));\n }\n }\n}\n\n/** A `category_id` filter replaces the page's category as the list source (as in the SDK). */\n// The API sends these four filter titles in Arabic whatever the language (the values are\n// translated). Twig's `<salla-filters>` swaps them for its own translations when the list\n// reaches it through `filters::fetched`; a list handed over as data, the loader's or a\n// theme's own query, is swapped here instead, with the keys the component uses.\nconst FILTER_TITLES: Record<string, [key: string, fallback: string]> = {\n category_id: ['common.titles.categories', 'Categories'],\n brand_id: ['common.titles.brands', 'Brands'],\n price: ['pages.categories.filter_price', 'Price'],\n rating: ['pages.categories.filter_rating', 'Rating'],\n};\n\nfunction titledFilters(filters?: Filter[]): Filter[] | undefined {\n const t = getTwilightContext().i18n?.t;\n if (!filters || !t) return filters;\n return filters.map((filter) => {\n const title = filter.key && FILTER_TITLES[filter.key];\n return title ? { ...filter, label: t(title[0], title[1]) } : filter;\n });\n}\n\nfunction categoryFilterIds(filters?: ProductListFilters): number[] | null {\n const raw = filters?.category_id;\n if (raw === undefined || raw === null) return null;\n const ids = Array.isArray(raw) ? raw : typeof raw === 'object' ? Object.values(raw) : [raw];\n return ids.map(Number);\n}\n\n// ===== Pagination =====\n\n/**\n * The API's own `cursor.next` (the previous page's response) is usually a\n * bare opaque cursor token, but for sources that don't support true\n * cursor-based pagination (observed: `source=offers`) it's instead a full\n * next-page URL carrying its own `page=N` — and no `cursor=` param at all.\n *\n * Passing that whole URL straight through as `list()`'s own `cursor` used to\n * smuggle its embedded `source` / `per_page` / `sort` into the request on\n * top of the ones `list()` already sets unconditionally, producing a\n * doubled query string (`source=offers&source=offers&...`) the API can't\n * paginate from correctly — every subsequent scroll re-fetched the exact\n * same first page instead of advancing. Pulling just the `page` number back\n * out here, the same way an actual `cursor=` is already pulled out, keeps\n * `list()`'s request to the one copy of each param it's supposed to have.\n */\nexport function parseNextPageToken(nextUrl: string | null | undefined): {\n cursor?: string;\n page?: number;\n} {\n if (!nextUrl) return {};\n\n const cursorMatch = nextUrl.match(/[?&]cursor=([^&]+)/);\n if (cursorMatch) return { cursor: decodeURIComponent(cursorMatch[1]) };\n\n const pageMatch = nextUrl.match(/[?&]page=([^&]+)/);\n if (pageMatch) {\n const page = Number(decodeURIComponent(pageMatch[1]));\n if (Number.isFinite(page)) return { page };\n }\n\n // Neither pattern matched: not a URL at all, just the bare opaque token itself.\n return { cursor: nextUrl };\n}\n\n// ===== API Functions =====\n\nexport const product = {\n find: async (id: string): Promise<Product> => {\n const endpoint = `products/${id}/details?with[]=images&with[]=category&with[]=rating&with[]=notify_availability&with[]=tags&with[]=brand&with[]=options&with[]=skus&with[]=skus_availability&with[]=included_products&with[]=bundle&with[]=sold_quantity`;\n const { data } = await api.get(endpoint).json<{ data: Product }>();\n return data;\n },\n\n findOrThrow: (id: string): Promise<Product> => orThrow(product.find(id)),\n\n /** A tag's name. The list endpoint returns every product for an unknown tag; this one answers 410. */\n tag: async (id: string): Promise<{ id: number; name: string }> => {\n const { tag } = await api\n .get(`products/tags/${id}`)\n .json<{ tag: { id: number; name: string } }>();\n return tag;\n },\n\n /**\n * Fetch products list with pagination support\n * Used by native ProductsList component for SSR loaders\n *\n * API pattern: GET /products?source=wishlist&page=1\n */\n list: async (params: ProductsListParams): Promise<ProductsListResult> => {\n const {\n source,\n sourceValue,\n keyword,\n page,\n cursor,\n perPage = 16,\n sort,\n filterable,\n filters,\n signal,\n } = params;\n\n // Build URL with query parameters\n const searchParams = new URLSearchParams();\n searchParams.set('source', source);\n // Only send page when explicitly provided — cursor-based callers omit it entirely\n if (page !== undefined) searchParams.set('page', String(page));\n searchParams.set('per_page', String(perPage));\n\n appendSourceParams(searchParams, {\n source,\n sourceValue: (source === 'categories' && categoryFilterIds(filters)) || sourceValue,\n keyword,\n });\n appendFilterParams(searchParams, filters);\n\n // Add filterable parameter\n if (filterable !== undefined) {\n searchParams.set('filterable', filterable ? '1' : '0');\n }\n\n // Add sort parameter\n if (sort) {\n searchParams.set('sort', sort);\n }\n\n // Add cursor for cursor-based pagination\n if (cursor) {\n searchParams.set('cursor', cursor);\n }\n\n // Make the request\n const options: Record<string, unknown> = {};\n if (signal) options.signal = signal;\n\n const response = await api\n .get(`products?${searchParams.toString()}`, options as any)\n .json<ProductsListResponse>();\n\n const items = response.data ?? [];\n rememberProductPreviews(items);\n\n return {\n items,\n next: response.cursor?.next ?? null,\n filters: titledFilters(response.filters),\n };\n },\n\n queries: {\n detail: (id: string) =>\n queryOptions({\n // Stock and availability are resolved per branch allocation — same as the list.\n queryKey: productDetailQueryKey(id),\n queryFn: () => product.find(id),\n // List-card product, if one was remembered. Not written as the detail\n // cache entry — `queryFn` still hits products/{id}/details.\n placeholderData: () => getProductPreview(id),\n }),\n tag: (id: string) =>\n queryOptions({\n queryKey: ['products', 'tag', id],\n queryFn: () => product.tag(id),\n }),\n list: (params: Omit<ProductsListParams, 'signal'>) =>\n queryOptions({\n // Scope (branch) varies product availability, and the locale the names and the\n // filter titles (a same-store link can switch language without a page load) — the\n // key must include both.\n queryKey: [\n 'products',\n 'list',\n params,\n { scope: getActiveScope(), locale: getTwilightContext().locale },\n ],\n queryFn: ({ signal }) => product.list({ ...params, signal }),\n }),\n },\n};\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { LazyCartItem as CartItem, LazyCartSummary as CartSummary, LazySeoCartWidget as SeoCartWidget } from '../../chunk-
|
|
1
|
+
export { LazyCartItem as CartItem, LazyCartSummary as CartSummary, LazySeoCartWidget as SeoCartWidget } from '../../chunk-2CILV5ME.js';
|
|
2
2
|
import '../../chunk-VYGA5AT5.js';
|
|
3
3
|
import '../../chunk-DGUM43GV.js';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { BlogSkeleton, LazyBreadcrumb as Breadcrumb, BreadcrumbSkeleton, LazyCurrencySymbol as CurrencySymbol, CustomerLayoutSkeleton, CustomerPageSkeleton, DeferredData, LazyErrorPage as ErrorPage, Image, LazyNoContent as NoContent, PageSkeleton, ProductCardSkeleton, ProductDetailSkeleton, ProductGridSkeleton, LazyRenderWhenVisible as RenderWhenVisible, SkeletonPulse, resolveDeferred } from '../../chunk-
|
|
1
|
+
export { BlogSkeleton, LazyBreadcrumb as Breadcrumb, BreadcrumbSkeleton, LazyCurrencySymbol as CurrencySymbol, CustomerLayoutSkeleton, CustomerPageSkeleton, DeferredData, LazyErrorPage as ErrorPage, Image, LazyNoContent as NoContent, PageSkeleton, ProductCardSkeleton, ProductDetailSkeleton, ProductGridSkeleton, LazyRenderWhenVisible as RenderWhenVisible, SkeletonPulse, resolveDeferred } from '../../chunk-LBZNLTBM.js';
|
|
2
2
|
export { Link } from '../../chunk-AXW67SY7.js';
|
|
3
3
|
import '../../chunk-BYMOPN2S.js';
|
|
4
4
|
import '../../chunk-SKLEJJ6M.js';
|
|
@@ -1,45 +1,45 @@
|
|
|
1
1
|
export { Drawer } from '../../chunk-6TKIUG5C.js';
|
|
2
|
-
import '../../chunk-
|
|
2
|
+
import '../../chunk-O63WBEAC.js';
|
|
3
3
|
import '../../chunk-Q77J3D2W.js';
|
|
4
|
-
import '../../chunk-
|
|
5
|
-
import '../../chunk-
|
|
6
|
-
import '../../chunk-
|
|
4
|
+
import '../../chunk-EMAAVDEK.js';
|
|
5
|
+
import '../../chunk-5T4MJAUN.js';
|
|
6
|
+
import '../../chunk-WAKCWE6P.js';
|
|
7
7
|
import '../../chunk-X55R4VVK.js';
|
|
8
8
|
import '../../chunk-YL6X3ZMG.js';
|
|
9
|
-
import '../../chunk-
|
|
9
|
+
import '../../chunk-IEKP3HYS.js';
|
|
10
10
|
import '../../chunk-OXMUPNMH.js';
|
|
11
|
-
import '../../chunk-
|
|
11
|
+
import '../../chunk-5RBXCPG6.js';
|
|
12
12
|
import '../../chunk-VVZNW5CB.js';
|
|
13
|
-
import '../../chunk-
|
|
13
|
+
import '../../chunk-DPQIVZ4T.js';
|
|
14
14
|
import '../../chunk-GD26FI4J.js';
|
|
15
|
-
import '../../chunk-
|
|
16
|
-
import '../../chunk-
|
|
17
|
-
import '../../chunk-
|
|
15
|
+
import '../../chunk-6YEE3VHL.js';
|
|
16
|
+
import '../../chunk-P2PPBXHD.js';
|
|
17
|
+
import '../../chunk-O3XMYDNC.js';
|
|
18
18
|
import '../../chunk-OUW6WESU.js';
|
|
19
|
-
import '../../chunk-
|
|
19
|
+
import '../../chunk-JK45RUVV.js';
|
|
20
20
|
import '../../chunk-HI5V5X3S.js';
|
|
21
|
-
import '../../chunk-
|
|
22
|
-
import '../../chunk-
|
|
21
|
+
import '../../chunk-2ZC5YGMI.js';
|
|
22
|
+
import '../../chunk-PYXAPLNB.js';
|
|
23
23
|
import '../../chunk-6T55LXJL.js';
|
|
24
24
|
import '../../chunk-Z653O7MX.js';
|
|
25
25
|
import '../../chunk-ZCH7W7DZ.js';
|
|
26
|
-
import '../../chunk-
|
|
26
|
+
import '../../chunk-B57KIBQL.js';
|
|
27
27
|
import '../../chunk-JWXJPJBO.js';
|
|
28
28
|
import '../../chunk-CW625T2E.js';
|
|
29
29
|
import '../../chunk-7V36I5GT.js';
|
|
30
30
|
import '../../chunk-6WI7R2BD.js';
|
|
31
|
-
import '../../chunk-
|
|
31
|
+
import '../../chunk-5EAISVPV.js';
|
|
32
32
|
import '../../chunk-OAMIDZKW.js';
|
|
33
|
-
import '../../chunk-
|
|
33
|
+
import '../../chunk-BYGVKW3M.js';
|
|
34
34
|
import '../../chunk-OQIIJRAS.js';
|
|
35
35
|
import '../../chunk-V2ZDTY6H.js';
|
|
36
|
-
import '../../chunk-
|
|
36
|
+
import '../../chunk-PPFD456V.js';
|
|
37
37
|
import '../../chunk-5XDPAKF5.js';
|
|
38
38
|
import '../../chunk-GCPEMNSU.js';
|
|
39
|
-
import '../../chunk-
|
|
39
|
+
import '../../chunk-RB7RHMKJ.js';
|
|
40
40
|
import '../../chunk-Z5M4YYWT.js';
|
|
41
41
|
import '../../chunk-TYNZ5B2B.js';
|
|
42
|
-
import '../../chunk-
|
|
42
|
+
import '../../chunk-LBZNLTBM.js';
|
|
43
43
|
import '../../chunk-AXW67SY7.js';
|
|
44
44
|
import '../../chunk-BYMOPN2S.js';
|
|
45
45
|
import '../../chunk-SKLEJJ6M.js';
|
|
@@ -47,10 +47,10 @@ import '../../chunk-6BZ5TKEV.js';
|
|
|
47
47
|
import '../../chunk-FZKRSGLP.js';
|
|
48
48
|
import '../../chunk-KYMWEUN2.js';
|
|
49
49
|
import '../../chunk-YA6ABQB7.js';
|
|
50
|
-
import '../../chunk-
|
|
51
|
-
import '../../chunk-
|
|
52
|
-
import '../../chunk-
|
|
53
|
-
import '../../chunk-
|
|
50
|
+
import '../../chunk-R7QCNL62.js';
|
|
51
|
+
import '../../chunk-ULF4LPVA.js';
|
|
52
|
+
import '../../chunk-7XAGU6CT.js';
|
|
53
|
+
import '../../chunk-4E6FD5W7.js';
|
|
54
54
|
import '../../chunk-6K34BCUP.js';
|
|
55
55
|
import '../../chunk-T72DAX7R.js';
|
|
56
56
|
import '../../chunk-DF6FBKDN.js';
|