@riverbankcms/sdk 0.143.0 → 0.145.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/dist/{PreviewEditorSidebar-DROGfMKi.mjs → PreviewEditorSidebar-O-V6Pl5a.mjs} +20 -26
  2. package/dist/{PreviewEditorUI-BaRjhFu-.mjs → PreviewEditorUI-1UlX_9cw.mjs} +3 -3
  3. package/dist/{PreviewQueryProvider-BCYICImX.mjs → PreviewQueryProvider-BxGwdOCV.mjs} +1 -1
  4. package/dist/{SdkPreviewModeRuntime-OIABYLES.mjs → SdkPreviewModeRuntime-DYbA_4iv.mjs} +431 -351
  5. package/dist/{SiteChromeCustomizeContext-ohjTvZbc.mjs → SiteChromeCustomizeContext-CNTKQ9nx.mjs} +3989 -2769
  6. package/dist/_dts/ai/src/contracts/proposals.d.ts +4719 -66
  7. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +429 -6
  8. package/dist/_dts/api/src/appointmentEndpointDefinitions.d.ts +49 -0
  9. package/dist/_dts/api/src/appointmentServiceCategoryEndpoints.d.ts +75 -0
  10. package/dist/_dts/api/src/appointmentServiceContracts.d.ts +80 -0
  11. package/dist/_dts/api/src/appointmentSetup.d.ts +8 -1
  12. package/dist/_dts/api/src/billing.d.ts +1 -1
  13. package/dist/_dts/api/src/billingEndpointTypes.d.ts +8 -2
  14. package/dist/_dts/api/src/bookingConfig.d.ts +3 -1
  15. package/dist/_dts/api/src/bookingManagementEndpoints.d.ts +2 -12
  16. package/dist/_dts/api/src/communications.d.ts +14 -22
  17. package/dist/_dts/api/src/contentRuntime.d.ts +2 -0
  18. package/dist/_dts/api/src/endpoints.d.ts +105 -58
  19. package/dist/_dts/api/src/index.d.ts +1 -1
  20. package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -1
  21. package/dist/_dts/api/src/launchReadiness.d.ts +2 -0
  22. package/dist/_dts/api/src/navigation/dashboardBookingsNav.d.ts +4 -4
  23. package/dist/_dts/api/src/newsletterEndpointDefinitions.d.ts +0 -23
  24. package/dist/_dts/api/src/onboarding/confirmationResend.d.ts +3 -0
  25. package/dist/_dts/api/src/publicBookingService.d.ts +35 -1
  26. package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +1 -0
  27. package/dist/_dts/api/src/publicExperience/newsletterEndpoints.d.ts +13 -0
  28. package/dist/_dts/api/src/publicNewsletterEndpointDefinitions.d.ts +58 -0
  29. package/dist/_dts/api/src/schemas/admin-observability-logs.d.ts +3 -3
  30. package/dist/_dts/api/src/sdkContracts.d.ts +1 -1
  31. package/dist/_dts/api/src/sdkSettingsContracts.d.ts +8 -0
  32. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +2 -6
  33. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +2 -8
  34. package/dist/_dts/api/src/siteSettings.d.ts +17 -7
  35. package/dist/_dts/api/src/types.d.ts +2 -1
  36. package/dist/_dts/billing/src/membership/index.d.ts +3 -0
  37. package/dist/_dts/block-form/src/backend/types.d.ts +14 -0
  38. package/dist/_dts/block-form/src/client/index.d.ts +1 -0
  39. package/dist/_dts/block-form/src/context/RepeaterHostActionsContext.d.ts +30 -0
  40. package/dist/_dts/block-form/src/context/index.d.ts +1 -0
  41. package/dist/_dts/block-form/src/index.d.ts +1 -0
  42. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterList.d.ts +4 -1
  43. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterRow.d.ts +5 -2
  44. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterRowActions.d.ts +11 -1
  45. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/index.d.ts +1 -0
  46. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/useEmptyStateFocusAfterRemoval.d.ts +8 -0
  47. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/buildSummary.d.ts +15 -1
  48. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/repeaterRowActionsDomain.d.ts +5 -2
  49. package/dist/_dts/blocks/src/PageRenderer.d.ts +4 -4
  50. package/dist/_dts/blocks/src/bindings/index.d.ts +2 -2
  51. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +58 -10
  52. package/dist/_dts/blocks/src/index.d.ts +1 -1
  53. package/dist/_dts/blocks/src/pageRenderJoins.d.ts +68 -0
  54. package/dist/_dts/blocks/src/pageRenderPlan.d.ts +8 -27
  55. package/dist/_dts/blocks/src/pageRenderPreparation.d.ts +7 -4
  56. package/dist/_dts/blocks/src/pageRendererBoundaries.d.ts +40 -23
  57. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +3 -0
  58. package/dist/_dts/blocks/src/server.d.ts +1 -1
  59. package/dist/_dts/blocks/src/system/blocks/appointment-services.d.ts +2 -0
  60. package/dist/_dts/blocks/src/system/blocks/events/eventSelectionFields.d.ts +2 -2
  61. package/dist/_dts/blocks/src/system/blocks/events/shared/calendarWindow.d.ts +1 -1
  62. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +2 -2
  63. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +47 -47
  64. package/dist/_dts/blocks/src/system/constants/events.d.ts +10 -0
  65. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +29 -3
  66. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +5 -0
  67. package/dist/_dts/blocks/src/system/runtime/api/context.d.ts +3 -3
  68. package/dist/_dts/blocks/src/system/runtime/api/endpoints.d.ts +10 -0
  69. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +3 -2
  70. package/dist/_dts/blocks/src/system/runtime/api/readAuthority.d.ts +11 -0
  71. package/dist/_dts/blocks/src/system/runtime/api/types/core.d.ts +9 -0
  72. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +7 -13
  73. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +3 -6
  74. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.d.ts +9 -4
  75. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +0 -1
  76. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.d.ts +1 -3
  77. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.d.ts +8 -1
  78. package/dist/_dts/blocks/src/system/runtime/nodes/appointment-services.d.ts +22 -2
  79. package/dist/_dts/blocks/src/system/runtime/nodes/basic.d.ts +7 -24
  80. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +3 -1
  81. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.interactive.d.ts +57 -2
  82. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.service-categories.d.ts +29 -0
  83. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.service-choices.d.ts +13 -0
  84. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.state.d.ts +3 -3
  85. package/dist/_dts/blocks/src/system/runtime/nodes/booking-runtime-sources.d.ts +13 -1
  86. package/dist/_dts/blocks/src/system/runtime/nodes/cart.server.d.ts +1 -0
  87. package/dist/_dts/blocks/src/system/runtime/nodes/checkout.server.d.ts +1 -0
  88. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationBookingLayer.d.ts +2 -1
  89. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +2 -1
  90. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationWizardActions.d.ts +2 -1
  91. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +2 -0
  92. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.override.d.ts +2 -1
  93. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.d.ts +1 -1
  94. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +2 -2
  95. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +8 -0
  96. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +4 -5
  97. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +7 -2
  98. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +7 -5
  99. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.interactive.d.ts +5 -6
  100. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +6 -4
  101. package/dist/_dts/blocks/src/system/runtime/nodes/header-control.d.ts +10 -0
  102. package/dist/_dts/blocks/src/system/runtime/nodes/layout.d.ts +6 -21
  103. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.submission.d.ts +20 -1
  104. package/dist/_dts/blocks/src/system/runtime/nodes/product-detail.server.d.ts +1 -0
  105. package/dist/_dts/blocks/src/system/runtime/nodes/product-list.server.d.ts +1 -0
  106. package/dist/_dts/blocks/src/system/runtime/nodes/shop.interactive.d.ts +13 -0
  107. package/dist/_dts/blocks/src/system/runtime/nodes/shop.server.d.ts +1 -0
  108. package/dist/_dts/blocks/src/system/runtime/shared/components/ThemedButton.d.ts +58 -0
  109. package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +2 -0
  110. package/dist/_dts/blocks/src/system/transforms/registry/chromeLogo.d.ts +23 -0
  111. package/dist/_dts/blocks/src/system/transforms/registry/index.d.ts +2 -1
  112. package/dist/_dts/blocks/src/system/transforms/registry/layout.d.ts +3 -1
  113. package/dist/_dts/blocks/src/system/transforms/typed.d.ts +4 -1
  114. package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +2 -0
  115. package/dist/_dts/content-model/src/content-types/schema.d.ts +1 -1
  116. package/dist/_dts/core/src/appointment-service-categories.d.ts +108 -0
  117. package/dist/_dts/core/src/editor-state.d.ts +6 -0
  118. package/dist/_dts/core/src/event-catalogue.d.ts +27 -0
  119. package/dist/_dts/core/src/event-preset-vocabulary.d.ts +7 -0
  120. package/dist/_dts/core/src/index.d.ts +3 -0
  121. package/dist/_dts/core/src/public-profile.d.ts +9 -0
  122. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +676 -241
  123. package/dist/_dts/db/src/schemas/forms.d.ts +286 -2
  124. package/dist/_dts/editor-blocks/src/block-editor/{BlockCardHeader.d.ts → BlockCardFrame.d.ts} +11 -3
  125. package/dist/_dts/editor-blocks/src/block-editor/types.d.ts +6 -0
  126. package/dist/_dts/editor-blocks/src/widgets/site-option-picker/loaders.d.ts +16 -1
  127. package/dist/_dts/editor-blocks/src/widgets/site-option-picker/types.d.ts +13 -0
  128. package/dist/_dts/editor-blocks/src/widgets/site-option-picker/utils.d.ts +29 -0
  129. package/dist/_dts/logger/src/console.d.ts +3 -0
  130. package/dist/_dts/preview-next/src/client/blocks/BoundaryControl.d.ts +7 -2
  131. package/dist/_dts/preview-next/src/client/blocks/composer/mergeDrafts.d.ts +1 -1
  132. package/dist/_dts/preview-next/src/client/blocks/composer/types.d.ts +1 -0
  133. package/dist/_dts/preview-next/src/client/blocks/previewProjection/applyPreviewProjections.d.ts +1 -3
  134. package/dist/_dts/preview-next/src/client/blocks/previewProjection/runtimeContentDecoration.d.ts +2 -2
  135. package/dist/_dts/preview-next/src/client/blocks/previewProjection/types.d.ts +2 -2
  136. package/dist/_dts/preview-next/src/client/preview/PreviewEntryControllerProvider.d.ts +1 -0
  137. package/dist/_dts/sdk/src/client/publicEventReadOperations.d.ts +1 -0
  138. package/dist/_dts/sdk/src/client/runtimeCacheKeys.d.ts +8 -0
  139. package/dist/_dts/sdk/src/client/types.d.ts +4 -1
  140. package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
  141. package/dist/_dts/sdk/src/contracts/page.d.ts +7 -2
  142. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +5 -0
  143. package/dist/_dts/sdk/src/manifest/passes/pass1-fields.d.ts +2 -2
  144. package/dist/_dts/sdk/src/navigation/index.d.ts +27 -0
  145. package/dist/_dts/sdk/src/public-api/contracts.d.ts +21 -15
  146. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +3 -2
  147. package/dist/_dts/sdk/src/rendering/client.d.ts +1 -0
  148. package/dist/_dts/sdk/src/rendering/components/Block.shared.d.ts +1 -0
  149. package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +7 -1
  150. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +4 -2
  151. package/dist/_dts/sdk/src/rendering/helpers/loadContent.d.ts +1 -1
  152. package/dist/_dts/sdk/src/rendering/hooks/useContent.d.ts +1 -1
  153. package/dist/_dts/sdk/src/rendering/islands/enhancers/routeIslandApiConfig.d.ts +3 -2
  154. package/dist/_dts/sdk/src/rendering/islands/enhancers/shopShared.d.ts +2 -0
  155. package/dist/_dts/sdk/src/rendering/overrides.d.ts +1 -0
  156. package/dist/_dts/sdk/src/version.d.ts +1 -1
  157. package/dist/_dts/surfaces/src/index.d.ts +1 -0
  158. package/dist/_dts/theme-core/src/buttons/affordanceSuppression.d.ts +1 -1
  159. package/dist/_dts/theme-core/src/buttons/classNames.d.ts +3 -13
  160. package/dist/_dts/theme-core/src/customCss/index.d.ts +1 -1
  161. package/dist/_dts/theme-core/src/customCss/patch.d.ts +0 -5
  162. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  163. package/dist/_dts/theme-core/src/layout/boundaryCss.d.ts +3 -0
  164. package/dist/_dts/theme-core/src/site-styles/compositionBudget.d.ts +8 -0
  165. package/dist/_dts/theme-core/src/site-styles/contentTemplateRuntimeCompiler.d.ts +3 -2
  166. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +1 -3
  167. package/dist/_dts/theme-core/src/site-styles/generatedDesignPipeline.d.ts +3 -0
  168. package/dist/_dts/theme-core/src/site-styles/index.d.ts +3 -0
  169. package/dist/_dts/theme-core/src/site-styles/joinTreatment.d.ts +132 -0
  170. package/dist/_dts/theme-core/src/site-styles/pageDesignEditorBoundaries.d.ts +31 -0
  171. package/dist/_dts/theme-core/src/site-styles/pageDesignEditorModel.d.ts +33 -29
  172. package/dist/_dts/theme-core/src/site-styles/pageDesignIntent.d.ts +4 -4
  173. package/dist/_dts/theme-core/src/site-styles/pageFlowPresets.d.ts +36 -0
  174. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +4 -10
  175. package/dist/_dts/theme-core/src/site-styles/rawStyleFields.d.ts +17 -4
  176. package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +20 -74
  177. package/dist/_dts/theme-core/src/site-styles/sectionBoundaryComposition.d.ts +95 -0
  178. package/dist/_dts/theme-core/src/site-styles/sectionTransitions.d.ts +80 -518
  179. package/dist/_dts/theme-core/src/site-styles/siteStyleBlockPolicies.d.ts +9 -4
  180. package/dist/_dts/theme-core/src/site-styles/transitionCatalogue.d.ts +320 -0
  181. package/dist/_dts/theme-core/src/site-styles/types.d.ts +3 -18
  182. package/dist/_dts/theme-core/src/surfaces/index.d.ts +1 -0
  183. package/dist/_dts/theme-core/src/surfaces/logoVariant.d.ts +26 -0
  184. package/dist/_dts/theme-core/src/utils/colorStyles.d.ts +10 -0
  185. package/dist/_dts/ui/src/editor-item-card.d.ts +116 -0
  186. package/dist/_dts/ui/src/index.d.ts +1 -0
  187. package/dist/client/{BookingConsentAgreement-BoCtvzzu.mjs → BookingConsentAgreement-DlVOmpW4.mjs} +4 -55
  188. package/dist/client/{DiscountCodeDisclosure-B5S30nZk.mjs → DiscountCodeDisclosure-T9q623PQ.mjs} +27 -17
  189. package/dist/client/{EventCombined.client-CeZ2-zSt.mjs → EventCombined.client-DnsUeONl.mjs} +54 -46
  190. package/dist/client/{EventListing.client-DJN3j8B3.mjs → EventListing.client-CNBFqJS4.mjs} +3 -4
  191. package/dist/client/{LeafletStaticMap-RjtGzDQT.mjs → LeafletStaticMap-C7higg52.mjs} +1 -1
  192. package/dist/client/ThemedButton-LAJTNrS8.mjs +412 -0
  193. package/dist/client/{accordion-DOmnDoyg.mjs → accordion-BcNF9TjX.mjs} +1 -1
  194. package/dist/client/{bookingForm-C0vk7pgS.mjs → bookingForm-BUaQ3S03.mjs} +161 -75
  195. package/dist/client/bookings.mjs +392 -182
  196. package/dist/client/{carousel-BZJ7pno3.mjs → carousel-CTdF6e0V.mjs} +2 -2
  197. package/dist/client/{carousel.client-DQTjCVQT.mjs → carousel.client-jahpU9Vz.mjs} +1 -1
  198. package/dist/client/{cart-CaeVAHJl.mjs → cart-pGtyf_XU.mjs} +3 -3
  199. package/dist/client/{checkout-7wmoNDtG.mjs → checkout-Da9WSn7Y.mjs} +3 -3
  200. package/dist/client/{checkoutUrls-FL6lRkrt.mjs → checkoutUrls-CW3-78uu.mjs} +1 -1
  201. package/dist/client/client.mjs +3819 -2717
  202. package/dist/client/{colorStyles-3013aRAY.mjs → colorStyles-CuJBiS-1.mjs} +16 -4
  203. package/dist/client/{context-BOimxE3U.mjs → context-BFeY_Wbm.mjs} +24 -8
  204. package/dist/client/{dates-BnzVksi4.mjs → dates-BhwVSxDg.mjs} +2 -2
  205. package/dist/client/{eventCalendar-l-fpaslC.mjs → eventCalendar-BAtdnR4s.mjs} +39 -50
  206. package/dist/client/{eventCombined-DGGvssK6.mjs → eventCombined-RksA3tRC.mjs} +5 -4
  207. package/dist/client/{eventDetails-DRiCm_hL.mjs → eventDetails-BB9hB4wR.mjs} +4 -4
  208. package/dist/client/{eventListing-dph8loYX.mjs → eventListing-BpJBkviM.mjs} +5 -4
  209. package/dist/client/{eventRegistration-ClBohmbY.mjs → eventRegistration-B18jFq_o.mjs} +83 -68
  210. package/dist/client/{form-BLVVAnd3.mjs → form-Dodt8Y8t.mjs} +9 -10
  211. package/dist/client/{headerSection-DHy4C8Ix.mjs → headerSection-B0qj9ttg.mjs} +23 -30
  212. package/dist/client/hooks.mjs +807 -162
  213. package/dist/client/{locationMap-6HuS28ck.mjs → locationMap-gn-iMk7a.mjs} +9 -10
  214. package/dist/client/{media-DHpfFwd3.mjs → media-BtJ37tzS.mjs} +1 -1
  215. package/dist/client/{newsletterForm-xOdcOhZP.mjs → newsletterForm-oByLdFkr.mjs} +31 -11
  216. package/dist/client/{pricing-ChinRYFt.mjs → pricing-BOU0_Hai.mjs} +1 -1
  217. package/dist/client/{productDetail-0chA5gbK.mjs → productDetail-D9v1zH2j.mjs} +3 -3
  218. package/dist/client/{productList-OoINA0h1.mjs → productList-D-mItx1n.mjs} +3 -3
  219. package/dist/client/{propsDecoder-CIZ-hbIG.mjs → propsDecoder-C3TP_z4x.mjs} +158 -61
  220. package/dist/client/rendering/client.mjs +2785 -2000
  221. package/dist/client/rendering/islands.mjs +19 -19
  222. package/dist/client/rendering.mjs +3855 -2694
  223. package/dist/client/{routeIslandApiConfig-UNsfPcYq.mjs → routeIslandApiConfig-DzN1W0sq.mjs} +8 -1
  224. package/dist/client/{scrollToBlock-BPZl0gPZ.mjs → scrollToBlock-CWs8EIdo.mjs} +1 -1
  225. package/dist/client/{shop-CLJFqNIq.mjs → shop-Dufw7N7o.mjs} +45 -58
  226. package/dist/client/{shop-commerce-PpANg5wB.mjs → shop-commerce-gklw_hLF.mjs} +42 -55
  227. package/dist/client/{shop-commerce-store-TA_Kz2ku.mjs → shop-commerce-store-Sf1eyTaZ.mjs} +1 -1
  228. package/dist/client/{shopShared-DzcFcA5g.mjs → shopShared-B5nyA41S.mjs} +6 -5
  229. package/dist/client/{useEventFilters-CFU21QZo.mjs → useEventFilters-CLL829vy.mjs} +66 -355
  230. package/dist/preview-next/before-render.mjs +147 -77
  231. package/dist/preview-next/client/runtime.mjs +4 -4
  232. package/dist/preview-next/editor-chrome.css +8 -0
  233. package/dist/preview-next/keepAlive.mjs +147 -77
  234. package/dist/preview-next/middleware.mjs +147 -77
  235. package/dist/{previewAuthStore-JA6-I_sL.mjs → previewAuthStore-BxAFlu-j.mjs} +147 -77
  236. package/dist/{sdk-runtime-CDKl0Fr7.mjs → sdk-runtime-D0uZFev7.mjs} +2 -2
  237. package/dist/{separator-BTp96X32.mjs → separator-EvdCAn4V.mjs} +1 -1
  238. package/dist/server/components.mjs +2548 -1607
  239. package/dist/server/config-validation.mjs +794 -160
  240. package/dist/server/config.mjs +794 -160
  241. package/dist/server/data.mjs +806 -161
  242. package/dist/server/index.mjs +167 -85
  243. package/dist/server/navigation.mjs +28 -1
  244. package/dist/server/next.mjs +14930 -14036
  245. package/dist/server/page-converter.mjs +494 -113
  246. package/dist/server/prebuild.mjs +1 -1
  247. package/dist/server/rendering/server.mjs +2537 -1590
  248. package/dist/server/rendering.mjs +2571 -1618
  249. package/dist/server/routing.mjs +918 -200
  250. package/dist/server/server.mjs +819 -205
  251. package/dist/server/theme-bridge.mjs +1232 -28
  252. package/dist/server/theme.mjs +6 -4
  253. package/dist/styles/index.css +6 -0
  254. package/package.json +2 -1
@@ -1,7 +1,7 @@
1
1
  "use client";
2
- import { $i as mapCurrentValueForSelect, $n as coerceLinkedContentEntriesPayload, $r as runTransforms, An as containerResponsiveThemeCss, Ar as compileTransitionRuntime, At as RichTextField, Ba as Button, Bi as parseThemeForPersistence, Bn as compileManifestContentContract, Bt as getBlockManifestFromSdkConfig, Ca as Dialog, Ci as isRecord$13, Cn as deriveLaunchReadiness, Cr as retargetCompiledRuntimeFieldsForContentAdjacency, Ct as ButtonVariantField, Da as DialogHeader, Di as asDesignBlockId, Dn as useApiMediaUploader, Dt as ReferenceField, Ea as DialogFooter, Ei as pageDesignEditorBackgroundOverrideOwner, En as useMediaEditorOptional, Er as componentRuntimeRulesForTheme, Et as MediaField, Fn as SITE_CHROME_VISIBLE_HEADER_SELECTOR, Fr as gradientToCss, Ft as LinkWidgetProvider, G as confirmAutosaveBatch, Gi as paletteModeSchema, Gn as escapeStyleContent, Gr as backgroundAppearanceColorTokenNames, Gt as canRedoHistory, Ha as cn, Hn as buildThemeRuntime, Hr as sectionTransitionFamilies, Ht as useEditorUiStore, In as SITE_OVERLAY_HEADER_CLEARANCE_CSS_VAR, Ir as GRADIENT_PRESETS, J as idleEditorTransactionQueueState, Ji as getFieldIntent, Jn as defaultTransforms, Jr as ctaButton, Jt as pushHistoryEntry, K as deriveTransactionCapabilities, Ki as resolveSdkFooterMode, Kn as readBlockComposition, Kr as backgroundAppearanceQuickColorTokenNames, Kt as canUndoHistory, Li as textColorStyle, Ln as planSiteOverlayHeaderClearance, Lr as GRADIENT_PRESET_IDS, Lt as hideThemeV2RawStyleFields, Mn as makeDefaultBlockComponent, Mt as EditorProvider, Nn as getBlockDefinition, Nt as useEditor, Oa as DialogTitle, Oi as assertNever$1, On as isSupportedLoaderEndpoint, Or as designRuntimeRulesForTheme, Ot as ReferenceWidgetProvider, Pn as projectRecurringSchedule, Pt as LinkField, Q as resolvePreviewSidebarTab, Qi as hasEmptyOption, Qn as LINKED_CONTENT_ENTRY_META_KEY, Qr as parseBackgroundContent, Qt as recordsEqual, Ri as defaultThemeTokens, Rn as visibleHeaderClearancePx, Rr as getGradientPreset, Rt as prepareBlockEditorManifest, Sa as TabsTrigger, Si as isObjectRecord, Sn as DEFAULT_LAUNCH_READINESS_INPUT, Sr as retargetCompiledBoundaryRuntimeForContentAdjacency, St as EntryPickerWidgetProvider, Ta as DialogDescription, Ti as isThemeV2NormalEditorRawStyleFieldName, Tn as MediaEditorContextProvider, Tr as planPageDesignLayoutLookCompatibility, Tt as FileField, Ua as X, Un as DEFAULT_THEME_RESPONSIVE_MODE, Ur as sectionTransitionFamilyForBoundaryOptionId, Ut as useEditorUiStoreInstance, Vi as ORDINARY_TEXT_MIN_CONTRAST_RATIO, Vn as validateManifestDraft, Vr as defaultSectionTransitionVariantForFamily, W as beginAutosaveBatch, Wa as Upload, Wi as paletteColorsSchema, Wn as getResponsiveScopeSpec, Wr as sectionTransitionVariantForBoundaryOptionId, Wt as useOptionalEditorUiStoreInstance, Xi as SdkConfigProvider, Xn as resolvePageRouteTarget, Xt as undoHistory, Y as rejectAutosaveBatch, Yi as isHeaderField, Yn as resolveEntryRouteTarget, Yr as bindingSchema, Yt as redoHistory, Za as RotateCcw, Zi as useSdkConfig, Zn as resolveRouteTarget, Zr as planSiteChromePlacement, Zt as unsafeAsLinkedContentEntryId, _ as reportPreviewDesignError, _i as BlockApiProvider, _n as MediaEditor, _o as expectParsedBrandedId, _r as heroCopyFragment, _t as loadMailingListAuthoringContext, ai as coerceInlineTextWithFallback, an as parseReferenceKind, ao as Image, ar as cardFragment, at as useUISelector, ba as TabsContent, bi as eventCalendarListLayoutOptions, bo as __exportAll, br as applyCompiledRuntimeFieldsToContent, bt as IconPickerField, ca as SelectContent, ci as Text$1, cr as blogFeaturedPostFragment, d as PreviewDesignCoordinatorProvider, da as SelectValue, di as getCurrentResolveImageUrlContext, dr as formCopyFragment, dt as createSiteOptionWidgetAdapters, ea as mapOptionValueForSelect, ei as parseBlockIconValue, en as useDebouncedLatestSave, er as getLinkedContentEntryMeta, et as renderSiteChromeBlock, fi as resolveImageUrlWithContext, fn as createManifestFormAdapter, fr as testimonialsCarouselFragment, ft as SiteOptionPickerField, g as PREVIEW_DESIGN_SAVE_ERROR_MESSAGE, gi as siblingPath, gn as createStoreBackend, go as assertNever$2, gr as ctaRowFragment, gt as MailingListTargetingField, h as PREVIEW_DESIGN_LOAD_ERROR_MESSAGE, hi as getAtPath, hn as evaluateVisibility, ho as unsafeAsEditorBlockValues, hr as heroCtaRowFragment, ht as OfferingsPreviewWidgetProvider, i as usePreviewDesignHistoryOrder, ii as logger, ir as headingFragment, jn as createCustomBlockRegistry, jr as surfaceResolutionContextFromTheme, jt as RichTextWidgetProvider, ki as makeBoundaryId, kn as ThemeScope, kt as useRichTextImagePicker, la as SelectItem, li as RichText$1, ln as PaletteProvider, lo as ChevronRight, lr as singleButtonFragment, lt as useEntryEditorController, m as usePreviewThemeOverlay, mi as SECTION_BACKGROUND_MIN_SOURCE_WIDTH, mn as FormRenderer, mo as unsafeAsEditorBlockId, mr as ctaCopyFragment, mt as OfferingsPreviewGroupOrderField, n as useSiteChromeCustomizeOptional, na as FieldFrame, ni as parseGeneratedIconSetId, nn as createSnapshotFromPageRecord, nr as ImageResolveContextProvider, nt as PreviewInlineTextEditor, oi as inlineTextToPlainText, oo as GripVertical, or as faqAccordionFragment, ot as EditableBlockProvider, p as PreviewThemeOverlayProvider, pi as setContextResolveImageUrlContext, po as parseFooterModuleId, pr as testimonialsHeadingFragment, pt as SiteOptionWidgetProvider, q as enqueueTransaction, qi as attachRenderableMediaAssetFields, qn as getDefaultComponentRegistry, qr as parseBackgroundAppearanceColorToken, qt as createHistoryState, r as PreviewDesignHistoryOrderProvider, ra as useField, ri as renderInlineText, rn as BUILT_IN_REFERENCE_KINDS, rr as richTextFragment, rt as PreviewTextEditor, sa as Select, si as isInlineTextEmpty, sr as faqHeadingFragment, st as EntryControllerProvider, t as SiteChromeCustomizeProvider, ta as unmapValueFromSelect, ti as parseGeneratedIconAssetId, tn as createRoutingHelpers, tr as clientComponentRegistry, tt as PreviewRichTextEditor, ua as SelectTrigger, ui as buildResolveImageUrlContext, un as usePalette, uo as ChevronLeft, ur as formEmbedFragment, ut as createSiteOptionApiLoader, vi as calendarWindowQuerySchema, vn as applyPageDesignEditorAction, vo as parseMediaAssetId, vr as bodyCopyFragment, vt as MailingListTargetingProvider, wa as DialogContent, wi as corners, wn as AMBIENT_BACKGROUND_ROLES, wr as formatSiteChromeBackgroundTokenLabel, wt as ButtonWidgetProvider, xa as TabsList, xi as bookingConsentCarrierSchema, xn as decodePublicProductCategorySelectorQuery, xr as compileEditorModelRuntime, xt as EntryPickerField, ya as Tabs, yi as eventCalendarListLayoutCompatibleDisplayModeValues, yn as getPageDesignEditorState, yo as parseSiteId, yr as defineFragment, yt as InlineTextField, zn as resolveVariantKey, zr as parseGradientPresetId, zt as stripTopLevelRoutingUi } from "./SiteChromeCustomizeContext-ohjTvZbc.mjs";
3
- import { i as useOptionalPreviewLayout, t as PreviewQueryProvider } from "./PreviewQueryProvider-BCYICImX.mjs";
4
- import { _ as API_ENDPOINTS, a as usePreviewToken, c as createBearerAPIClient, d as unwrapResponse, g as resolveSurfaceDocumentAttributes, h as SURFACE_IDS, i as usePreviewAuthFetch, m as SURFACE_DOCUMENT_DATA_ATTRIBUTE, n as markPreviewAuthExpired, o as isPreviewRuntimeSessionEditable, r as usePreviewAuth, s as ApiRequestError, t as initPreviewAuth } from "./previewAuthStore-JA6-I_sL.mjs";
2
+ import { $i as attachRenderableMediaAssetFields, $n as LINKED_CONTENT_ENTRY_META_KEY, $r as ctaButton, Aa as DialogContent, Ai as corners, An as containerResponsiveThemeCss, Ar as surfaceResolutionContextFromTheme, At as RichTextField, Bn as compileManifestContentContract, Br as autoDesignChoice, Bt as getBlockManifestFromSdkConfig, Ci as BlockApiProvider, Cn as deriveLaunchReadiness, Co as expectParsedBrandedId, Cr as formatSiteChromeBackgroundTokenLabel, Ct as ButtonVariantField, Da as TabsList, Di as bookingConsentCarrierSchema, Dn as useApiMediaUploader, Dt as ReferenceField, Ea as TabsContent, Ei as eventCalendarListLayoutOptions, En as useMediaEditorOptional, Eo as __exportAll, Er as componentRuntimeRulesForTheme, Et as MediaField, Fi as assertNever$1, Fn as SITE_CHROME_VISIBLE_HEADER_SELECTOR, Fr as GRADIENT_PRESETS, Ft as LinkWidgetProvider, G as confirmAutosaveBatch, Gi as defaultThemeTokens, Gn as escapeStyleContent, Gr as boundaryTreatmentForBoundaryOptionId, Gt as canRedoHistory, Hn as buildThemeRuntime, Hr as boundaryLayout, Ht as useEditorUiStore, Ii as makeBoundaryId, In as SITE_OVERLAY_HEADER_CLEARANCE_CSS_VAR, Ir as GRADIENT_PRESET_IDS, J as idleEditorTransactionQueueState, Ja as cn, Jn as getDefaultComponentRegistry, Jr as sectionTransitionFamilyForBoundaryOptionId, Jt as pushHistoryEntry, K as deriveTransactionCapabilities, Ka as Button, Ki as parseThemeForPersistence, Kn as mergeContentWithBlockStyleOverrides, Kr as defaultSectionTransitionVariantForFamily, Kt as canUndoHistory, Ln as planSiteOverlayHeaderClearance, Lr as getGradientPreset, Lt as hideThemeV2RawStyleFields, Ma as DialogFooter, Mi as pageDesignEditorBackgroundOverrideOwner, Mn as makeDefaultBlockComponent, Mt as EditorProvider, Na as DialogHeader, Ni as stripStaleTransitionStyleGroup, Nn as getBlockDefinition, Nt as useEditor, Oa as TabsTrigger, Oi as isObjectRecord, On as isSupportedLoaderEndpoint, Or as designRuntimeRulesForTheme, Ot as ReferenceWidgetProvider, Pa as DialogTitle, Pi as asDesignBlockId, Pn as projectRecurringSchedule, Pr as gradientToCss, Pt as LinkField, Q as resolvePreviewSidebarTab, Qi as resolveSdkFooterMode, Qn as resolveRouteTarget, Qr as parseBackgroundAppearanceColorToken, Qt as recordsEqual, Rn as visibleHeaderClearancePx, Rr as parseGradientPresetId, Rt as prepareBlockEditorManifest, Si as siblingPath, Sn as DEFAULT_LAUNCH_READINESS_INPUT, So as assertNever$2, Sr as compileEditorModelRuntime, St as EntryPickerWidgetProvider, Ta as Tabs, Ti as eventCalendarListLayoutCompatibleDisplayModeValues, Tn as MediaEditorContextProvider, To as parseSiteId, Tr as resolvePageDesignEditorBoundaryForChoice, Tt as FileField, Un as DEFAULT_THEME_RESPONSIVE_MODE, Ur as composeBoundary, Ut as useEditorUiStoreInstance, Vn as validateManifestDraft, Vr as userPinnedDesignChoice, W as beginAutosaveBatch, Wi as textColorStyle, Wn as getResponsiveScopeSpec, Wr as sectionFactsForContent, Wt as useOptionalEditorUiStoreInstance, Xa as Upload, Xi as paletteColorsSchema, Xn as resolveEntryRouteTarget, Xr as backgroundAppearanceColorTokenNames, Xt as undoHistory, Y as rejectAutosaveBatch, Ya as X, Yn as defaultTransforms, Yr as sectionTransitionVariantForBoundaryOptionId, Yt as redoHistory, Zi as paletteModeSchema, Zn as resolvePageRouteTarget, Zr as backgroundAppearanceQuickColorTokenNames, Zt as unsafeAsLinkedContentEntryId, _ as reportPreviewDesignError, _a as SelectValue, _i as getCurrentResolveImageUrlContext, _n as MediaEditor, _r as ctaRowFragment, _t as loadMailingListAuthoringContext, aa as mapCurrentValueForSelect, ai as parseBlockIconValue, an as parseReferenceKind, ar as headingFragment, at as useUISelector, bi as SECTION_BACKGROUND_MIN_SOURCE_WIDTH, bo as unsafeAsEditorBlockId, br as defineFragment, bt as IconPickerField, ca as FieldFrame, cr as faqHeadingFragment, d as PreviewDesignCoordinatorProvider, di as coerceInlineTextWithFallback, do as Image, dr as formEmbedFragment, dt as createSiteOptionWidgetAdapters, ea as getFieldIntent, ei as bindingSchema, en as useDebouncedLatestSave, er as coerceLinkedContentEntriesPayload, et as renderSiteChromeBlock, fi as inlineTextToPlainText, fn as createManifestFormAdapter, fo as GripVertical, fr as formCopyFragment, ft as SiteOptionPickerField, g as PREVIEW_DESIGN_SAVE_ERROR_MESSAGE, ga as SelectTrigger, gi as buildResolveImageUrlContext, gn as createStoreBackend, go as ChevronLeft, gr as heroCtaRowFragment, gt as MailingListTargetingField, h as PREVIEW_DESIGN_LOAD_ERROR_MESSAGE, ha as SelectItem, hi as RichText$1, hn as evaluateVisibility, ho as ChevronRight, hr as ctaCopyFragment, ht as OfferingsPreviewWidgetProvider, i as usePreviewDesignHistoryOrder, ia as hasEmptyOption, ii as runTransforms, ir as richTextFragment, ja as DialogDescription, ji as isThemeV2NormalEditorRawStyleFieldName, jn as createCustomBlockRegistry, jt as RichTextWidgetProvider, ka as Dialog, ki as isRecord$11, kn as ThemeScope, kt as useRichTextImagePicker, la as useField, li as renderInlineText, ln as PaletteProvider, lr as blogFeaturedPostFragment, lt as useEntryEditorController, m as usePreviewThemeOverlay, ma as SelectContent, mi as Text$1, mn as FormRenderer, mr as testimonialsHeadingFragment, mt as OfferingsPreviewGroupOrderField, n as useSiteChromeCustomizeOptional, na as SdkConfigProvider, ni as planSiteChromePlacement, nn as createSnapshotFromPageRecord, nr as clientComponentRegistry, nt as PreviewInlineTextEditor, oa as mapOptionValueForSelect, oi as parseGeneratedIconAssetId, or as cardFragment, ot as EditableBlockProvider, p as PreviewThemeOverlayProvider, pa as Select, pi as isInlineTextEmpty, pr as testimonialsCarouselFragment, pt as SiteOptionWidgetProvider, q as enqueueTransaction, qi as ORDINARY_TEXT_MIN_CONTRAST_RATIO, qn as readBlockComposition, qr as sectionTransitionFamilies, qt as createHistoryState, r as PreviewDesignHistoryOrderProvider, ra as useSdkConfig, ri as parseBackgroundContent, rn as BUILT_IN_REFERENCE_KINDS, ro as RotateCcw, rr as ImageResolveContextProvider, rt as PreviewTextEditor, sa as unmapValueFromSelect, si as parseGeneratedIconSetId, sr as faqAccordionFragment, st as EntryControllerProvider, t as SiteChromeCustomizeProvider, ta as isHeaderField, tn as createRoutingHelpers, tr as getLinkedContentEntryMeta, tt as PreviewRichTextEditor, ui as logger, un as usePalette, ur as singleButtonFragment, ut as createSiteOptionApiLoader, vi as resolveImageUrlWithContext, vn as applyPageDesignEditorAction, vr as heroCopyFragment, vt as MailingListTargetingProvider, wi as calendarWindowQuerySchema, wn as AMBIENT_BACKGROUND_ROLES, wo as parseMediaAssetId, wr as planPageDesignLayoutLookCompatibility, wt as ButtonWidgetProvider, xi as getAtPath, xn as decodePublicProductCategorySelectorQuery, xo as unsafeAsEditorBlockValues, xr as applyCompiledRuntimeFieldsToContent, xt as EntryPickerField, yi as setContextResolveImageUrlContext, yn as getPageDesignEditorState, yo as parseFooterModuleId, yr as bodyCopyFragment, yt as InlineTextField, zn as resolveVariantKey, zt as stripTopLevelRoutingUi } from "./SiteChromeCustomizeContext-CNTKQ9nx.mjs";
3
+ import { i as useOptionalPreviewLayout, t as PreviewQueryProvider } from "./PreviewQueryProvider-BxGwdOCV.mjs";
4
+ import { _ as API_ENDPOINTS, a as usePreviewToken, c as createBearerAPIClient, d as unwrapResponse, g as resolveSurfaceDocumentAttributes, h as SURFACE_IDS, i as usePreviewAuthFetch, m as SURFACE_DOCUMENT_DATA_ATTRIBUTE, n as markPreviewAuthExpired, o as isPreviewRuntimeSessionEditable, r as usePreviewAuth, s as ApiRequestError, t as initPreviewAuth } from "./previewAuthStore-BxAFlu-j.mjs";
5
5
  import * as React$1 from "react";
6
6
  import React, { Children, Fragment, cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useReducer, useRef, useState } from "react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -175,7 +175,7 @@ function ResizableSplitPane({ left, right, defaultSplit = 40, minLeftWidth = 300
175
175
  }
176
176
  //#endregion
177
177
  //#region ../blocks/src/system/icons/generatedAssets.ts
178
- function isRecord$12(value) {
178
+ function isRecord$10(value) {
179
179
  return typeof value === "object" && value !== null && !Array.isArray(value);
180
180
  }
181
181
  function generatedIconAssetRefKey(ref) {
@@ -185,11 +185,11 @@ function collectGeneratedIconAssetRefs(page) {
185
185
  const blocks = [];
186
186
  for (const block of page.blocks) {
187
187
  if (block.kind !== "block.feature-cards" || typeof block.id !== "string") continue;
188
- const content = isRecord$12(block.draftContent) ? block.draftContent : isRecord$12(block.content) ? block.content : null;
188
+ const content = isRecord$10(block.draftContent) ? block.draftContent : isRecord$10(block.content) ? block.content : null;
189
189
  const cards = Array.isArray(content?.cards) ? content.cards : [];
190
190
  const refs = /* @__PURE__ */ new Map();
191
191
  for (const card of cards) {
192
- if (!isRecord$12(card)) continue;
192
+ if (!isRecord$10(card)) continue;
193
193
  const icon = parseBlockIconValue(card.icon);
194
194
  if (icon.kind !== "generated") continue;
195
195
  const ref = {
@@ -386,70 +386,171 @@ function requireThemeResources(resources, blockKind) {
386
386
  return resources;
387
387
  }
388
388
  //#endregion
389
- //#region ../blocks/src/pageRendererBoundaries.tsx
390
- const boundaryKey = (previousBlockId, nextBlockId) => `${previousBlockId}\u0000${nextBlockId}`;
391
- function isSiteStyleTransitionStyleGroup(value) {
392
- return value?.startsWith("site-style-transition-") === true;
389
+ //#region ../blocks/src/pageRenderJoins.ts
390
+ /**
391
+ * Re-points joins across omitted blocks. Pure over joins.
392
+ *
393
+ * Joins are keyed by adjacent block-id pairs, so dropping B from [A, B, C]
394
+ * removes the A→C join as well as B's own, because no A→C join was ever
395
+ * resolved. For each surviving pair the original join is kept when the pair
396
+ * was already adjacent. Across a gap, the treatment comes from the join
397
+ * entering the omitted run (A→first omitted), falling back to the one leaving
398
+ * it (last omitted→C). Nothing visual is carried: the survivors are composed
399
+ * from their own content afterwards.
400
+ *
401
+ * `survivors` are compared by identity against `originalBlocks`.
402
+ */
403
+ function retargetJoinsAcrossOmissions(input) {
404
+ const { joins, originalBlocks, survivingBlocks } = input;
405
+ if (joins.length === 0) return joins;
406
+ if (originalBlocks.every((block) => survivingBlocks.has(block))) return joins;
407
+ const byPair = joinsByPair(joins);
408
+ const retargeted = [];
409
+ let previousSurvivor = null;
410
+ let run = [];
411
+ for (const block of originalBlocks) {
412
+ if (!survivingBlocks.has(block)) {
413
+ run.push(block);
414
+ continue;
415
+ }
416
+ if (previousSurvivor?.id && block.id) {
417
+ const join = run.length === 0 ? byPair.get(pairKey(previousSurvivor.id, block.id)) : joinAcrossRun(byPair, previousSurvivor.id, block.id, run);
418
+ if (join) retargeted.push(join);
419
+ }
420
+ previousSurvivor = block;
421
+ run = [];
422
+ }
423
+ return retargeted;
393
424
  }
394
- function boundaryMapForAdjacentBlockIds(boundaries) {
395
- return new Map(boundaries.map((boundary) => [boundaryKey(boundary.previousBlockId, boundary.nextBlockId), boundary]));
425
+ function joinAcrossRun(byPair, previousBlockId, nextBlockId, run) {
426
+ const firstOmittedId = run[0]?.id;
427
+ const lastOmittedId = run[run.length - 1]?.id;
428
+ const entering = firstOmittedId ? byPair.get(pairKey(previousBlockId, firstOmittedId)) : void 0;
429
+ const exiting = lastOmittedId ? byPair.get(pairKey(lastOmittedId, nextBlockId)) : void 0;
430
+ const donor = entering ?? exiting;
431
+ return donor ? {
432
+ previousBlockId,
433
+ nextBlockId,
434
+ treatment: donor.treatment
435
+ } : void 0;
396
436
  }
397
- function boundaryBetweenBlocks(previousBlock, nextBlock, boundaries) {
398
- const previousBlockId = previousBlock?.id ?? null;
399
- const nextBlockId = nextBlock?.id ?? null;
400
- if (!previousBlockId || !nextBlockId) return null;
401
- return boundaries.get(boundaryKey(previousBlockId, nextBlockId)) ?? null;
437
+ /**
438
+ * The single composition site. For every adjacent pair of survivors with ids,
439
+ * finds its join and composes it from both survivors' final content: what
440
+ * each paints with and the frame each draws.
441
+ */
442
+ function composePageJoins(input) {
443
+ const byPair = joinsByPair(input.joins);
444
+ return input.survivors.flatMap((previous, index) => {
445
+ const next = input.survivors[index + 1];
446
+ if (!next || !previous.id || !next.id) return [];
447
+ const join = byPair.get(pairKey(previous.id, next.id));
448
+ return [{
449
+ previousBlockId: previous.id,
450
+ nextBlockId: next.id,
451
+ join: join ? composeJoin(join, previous, next) : null
452
+ }];
453
+ });
454
+ }
455
+ function composeJoin(join, previous, next) {
456
+ return {
457
+ boundaryId: pairKey(join.previousBlockId, join.nextBlockId),
458
+ previousBlockId: join.previousBlockId,
459
+ nextBlockId: join.nextBlockId,
460
+ treatment: join.treatment,
461
+ outcome: composeBoundary(sectionFactsForContent(previous.content), sectionFactsForContent(next.content))
462
+ };
463
+ }
464
+ /** Placement, reserves and paint for a join that draws; null otherwise. */
465
+ function renderedJoinLayout(join) {
466
+ if (!join || join.outcome.kind !== "shown") return null;
467
+ return boundaryLayout(join.treatment, join.outcome.composition);
468
+ }
469
+ /** Joins with a missing id on either side cannot sit between two blocks. */
470
+ function joinsByPair(joins) {
471
+ return new Map(joins.flatMap((join) => join.previousBlockId && join.nextBlockId ? [[pairKey(join.previousBlockId, join.nextBlockId), join]] : []));
472
+ }
473
+ /** Slot lookup key for an adjacent pair, in the one boundary-id scheme. */
474
+ function joinSlotKey(previousBlockId, nextBlockId) {
475
+ return pairKey(previousBlockId, nextBlockId);
476
+ }
477
+ function pairKey(previousBlockId, nextBlockId) {
478
+ return makeBoundaryId(asDesignBlockId(previousBlockId), asDesignBlockId(nextBlockId));
479
+ }
480
+ //#endregion
481
+ //#region ../blocks/src/pageRendererBoundaries.tsx
482
+ function joinSlotsByPair(slots) {
483
+ return new Map(slots.map((slot) => [joinSlotKey(slot.previousBlockId, slot.nextBlockId), slot]));
402
484
  }
403
- function renderBoundaryAfterBlock(input) {
404
- const previousBlockId = input.block.id;
405
- const nextBlockId = input.nextBlock?.id ?? null;
485
+ function joinSlotBetween(previousBlockId, nextBlockId, slots) {
406
486
  if (!previousBlockId || !nextBlockId) return null;
407
- const boundary = input.boundaryByAdjacentBlockIds.get(boundaryKey(previousBlockId, nextBlockId));
408
- if (!boundary) return null;
409
- const rendered = /* @__PURE__ */ jsx("div", {
487
+ return slots.get(joinSlotKey(previousBlockId, nextBlockId)) ?? null;
488
+ }
489
+ /**
490
+ * The markup at one join: the painted boundary element when the join draws,
491
+ * then whatever `renderJoin` adds. Null when there is nothing to render.
492
+ */
493
+ function renderJoinSlot(input) {
494
+ const { slot } = input;
495
+ if (!slot) return null;
496
+ const layout = renderedJoinLayout(slot.join);
497
+ const painted = slot.join && layout ? /* @__PURE__ */ jsx("div", {
410
498
  "aria-hidden": "true",
411
499
  "data-block-boundary": "",
412
- "data-boundary-id": boundary.boundaryId,
413
- "data-boundary-previous-block-id": boundary.previousBlockId,
414
- "data-boundary-next-block-id": boundary.nextBlockId,
415
- "data-style-group": boundary.styleGroup,
416
- style: boundaryCssVarsStyle(boundary)
417
- }, `${input.blockKey}:boundary`);
418
- return input.wrapBoundary ? input.wrapBoundary(boundary, rendered) : rendered;
419
- }
420
- function boundaryCssVarsStyle(boundary) {
421
- return {
422
- "--site-style-transition-from": boundary.cssVars.from,
423
- "--site-style-transition-to": boundary.cssVars.to
424
- };
500
+ "data-boundary-id": slot.join.boundaryId,
501
+ "data-boundary-previous-block-id": slot.previousBlockId,
502
+ "data-boundary-next-block-id": slot.nextBlockId,
503
+ "data-boundary-treatment": slot.join.treatment,
504
+ "data-boundary-placement": layout.placement,
505
+ style: boundaryPaintStyle(layout.paint)
506
+ }, `${input.blockKey}:boundary`) : null;
507
+ const extra = input.renderJoin?.({
508
+ previousBlockId: slot.previousBlockId,
509
+ nextBlockId: slot.nextBlockId,
510
+ join: slot.join
511
+ });
512
+ if (!painted && (extra === null || extra === void 0)) return null;
513
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [painted, extra] }, `${input.blockKey}:join`);
425
514
  }
426
- function boundaryReserveCssVarsStyle(input) {
427
- const before = input.before?.metrics.reserveCss ?? null;
428
- const after = input.after?.metrics.reserveCss ?? null;
429
- if (!before && !after) return void 0;
430
- return {
431
- ...before ? { "--site-style-boundary-before-reserve": before } : {},
432
- ...after ? { "--site-style-boundary-after-reserve": after } : {}
433
- };
515
+ /**
516
+ * The one render-edge place a theme token becomes CSS.
517
+ */
518
+ function themeTokenCss(token) {
519
+ return `rgb(var(--tb-${token}))`;
434
520
  }
435
- function transitionCssVarsStyle(content) {
436
- const transitionStyles = isObjectRecord(content._transitionStyles) ? content._transitionStyles : null;
437
- const cssVars = isObjectRecord(transitionStyles?.cssVars) ? transitionStyles.cssVars : null;
438
- const from = typeof cssVars?.from === "string" ? cssVars.from : null;
439
- const to = typeof cssVars?.to === "string" ? cssVars.to : null;
440
- if (!from && !to) return void 0;
521
+ function boundaryPaintStyle(paint) {
441
522
  return {
442
- ...from ? { "--site-style-transition-from": from } : {},
443
- ...to ? { "--site-style-transition-to": to } : {}
523
+ "--boundary-shape-paint": themeTokenCss(paint.shape),
524
+ ...paint.band ? { "--boundary-band-paint": themeTokenCss(paint.band) } : {}
444
525
  };
445
526
  }
446
- function mergeStyleObjects(left, right) {
447
- if (!left) return right;
448
- if (!right) return left;
449
- return {
450
- ...left,
451
- ...right
527
+ /**
528
+ * Reserve attributes and variables for a block wrapper, from the joins on
529
+ * either side. A join's `before` reserve sits inside its previous section, so
530
+ * it pads the bottom of the block above the join; its `after` reserve pads the
531
+ * top of the block below. Joins that do not draw reserve nothing.
532
+ */
533
+ function blockBoundaryReserves(input) {
534
+ const top = reserveOnSide(input.before, "after");
535
+ const bottom = reserveOnSide(input.after, "before");
536
+ const style = {
537
+ ...top ? { "--site-style-boundary-before-reserve": top.length } : {},
538
+ ...bottom ? { "--site-style-boundary-after-reserve": bottom.length } : {}
452
539
  };
540
+ return {
541
+ topPlacement: top?.placement,
542
+ bottomPlacement: bottom?.placement,
543
+ style: top || bottom ? style : void 0
544
+ };
545
+ }
546
+ /** The reserve one join needs on one side of itself, if it draws at all. */
547
+ function reserveOnSide(slot, side) {
548
+ const layout = renderedJoinLayout(slot?.join ?? null);
549
+ const length = layout?.reserves[side] ?? null;
550
+ return layout && length ? {
551
+ length,
552
+ placement: layout.placement
553
+ } : null;
453
554
  }
454
555
  function pageBlockPosition(index, blockCount) {
455
556
  if (blockCount <= 1) return "only";
@@ -460,7 +561,7 @@ function pageBlockPosition(index, blockCount) {
460
561
  //#endregion
461
562
  //#region ../blocks/src/pageRendererContracts.ts
462
563
  function buildPageRendererRootRuntime(dataContext) {
463
- const { siteId = null, pageId = null, pathname = null, bookingTimeZone, previewStage = "published", apiBaseUrl = null, portalToken = null, bookingOfferingPresets = [], appointmentServicePathPrefix = null, mailingList = { tag: "not_configured" }, eventRegistrationOverlayEnabled = false, loaderFailures = {} } = dataContext ?? {};
564
+ const { siteId = null, pageId = null, pathname = null, bookingTimeZone, previewStage = "published", apiBaseUrl = null, portalToken = null, readAuthority, bookingOfferingPresets = [], appointmentServicePathPrefix = null, mailingList = { tag: "not_configured" }, eventRegistrationOverlayEnabled = false, loaderFailures = {} } = dataContext ?? {};
464
565
  return {
465
566
  siteId,
466
567
  pageId,
@@ -469,6 +570,7 @@ function buildPageRendererRootRuntime(dataContext) {
469
570
  previewStage,
470
571
  apiBaseUrl,
471
572
  portalToken,
573
+ readAuthority,
472
574
  bookingOfferingPresets,
473
575
  appointmentServicePathPrefix,
474
576
  mailingList,
@@ -651,11 +753,10 @@ function buildPageRenderPlan(input) {
651
753
  return {
652
754
  entries,
653
755
  omitted,
654
- runtimeBoundaries: retargetBoundariesAcrossOmissions({
655
- boundaries: input.runtimeBoundaries,
756
+ runtimeJoins: retargetJoinsAcrossOmissions({
757
+ joins: input.runtimeJoins ?? [],
656
758
  originalBlocks: input.page.blocks,
657
- survivingBlocks: new Set(entries.map((entry) => entry.block)),
658
- previewStage: input.previewStage
759
+ survivingBlocks: new Set(entries.map((entry) => entry.block))
659
760
  })
660
761
  };
661
762
  }
@@ -757,86 +858,15 @@ function getBlockOverride(blockKind, overrides) {
757
858
  * For draft/preview: draftContent takes priority over content.
758
859
  * For published: content is the source of truth.
759
860
  */
760
- function getRenderableContent(block, previewStage = "published") {
761
- const source = previewStage === "preview" && block.draftContent ? block.draftContent : block.content ?? {};
762
- return isObjectRecord(source) ? source : {};
763
- }
764
861
  /**
765
- * Re-points section boundaries across omitted blocks.
766
- *
767
- * Boundaries are keyed by adjacent block-id *pairs*, so dropping B from
768
- * [A, B, C] does not merely remove B's boundaries — it removes the boundary
769
- * between the survivors, because no `A→C` key was ever compiled.
770
- *
771
- * Per decision D2 the treatment for a merged gap comes from the boundary
772
- * entering the omitted run (`A→firstOmitted`), falling back to the one leaving
773
- * it (`lastOmitted→C`). The destination surface is a separate question: only
774
- * the exiting boundary knows what C looks like, so the merged boundary ends on
775
- * that endpoint rather than on the omitted block's. In the exiting-only
776
- * fallback the origin remains an approximation: `from` is the omitted block's
777
- * surface, because no compiled boundary carries A's. The hosted path no longer
778
- * needs this at all (site-renderer admits blocks before compiling boundaries);
779
- * it remains the safety net for an SDK whose compiled boundaries predate an
780
- * omission.
862
+ * The content a block renders with. Every render path (public, preview,
863
+ * templates, SDK) chooses content here, so this is also where a stale
864
+ * `site-style-transition-*` styleGroup is dropped; authored values survive.
781
865
  */
782
- function retargetBoundariesAcrossOmissions(input) {
783
- const { boundaries, originalBlocks, survivingBlocks, previewStage } = input;
784
- if (boundaries === void 0) return void 0;
785
- if (boundaries.length === 0) return boundaries;
786
- if (!originalBlocks.some((block) => !survivingBlocks.has(block))) return boundaries;
787
- const byPair = new Map(boundaries.map((boundary) => [pairKey(boundary.previousBlockId, boundary.nextBlockId), boundary]));
788
- const retargeted = [];
789
- let previousSurvivor = null;
790
- let run = [];
791
- for (const block of originalBlocks) {
792
- if (!survivingBlocks.has(block)) {
793
- run.push(block);
794
- continue;
795
- }
796
- if (previousSurvivor?.id && block.id) {
797
- const boundary = run.length === 0 ? byPair.get(pairKey(previousSurvivor.id, block.id)) : mergedBoundary({
798
- byPair,
799
- previousBlock: previousSurvivor,
800
- previousBlockId: previousSurvivor.id,
801
- nextBlock: block,
802
- nextBlockId: block.id,
803
- run,
804
- previewStage
805
- });
806
- if (boundary) retargeted.push(boundary);
807
- }
808
- previousSurvivor = block;
809
- run = [];
810
- }
811
- return retargeted;
812
- }
813
- function mergedBoundary(input) {
814
- const { byPair, previousBlock, previousBlockId, nextBlock, nextBlockId, run, previewStage } = input;
815
- const firstOmittedId = run[0]?.id;
816
- const lastOmittedId = run[run.length - 1]?.id;
817
- const entering = firstOmittedId ? byPair.get(pairKey(previousBlockId, firstOmittedId)) : void 0;
818
- const exiting = lastOmittedId ? byPair.get(pairKey(lastOmittedId, nextBlockId)) : void 0;
819
- const donor = entering ?? exiting;
820
- if (!donor) return void 0;
821
- const transition = compileTransitionRuntime({
822
- treatment: donor.treatment,
823
- from: donor.from,
824
- to: exiting?.to ?? donor.to
825
- });
826
- return retargetCompiledBoundaryRuntimeForContentAdjacency({
827
- ...donor,
828
- boundaryId: makeBoundaryId(asDesignBlockId(previousBlockId), asDesignBlockId(nextBlockId)),
829
- previousBlockId,
830
- nextBlockId,
831
- from: transition.from,
832
- to: transition.to,
833
- cssVars: transition.cssVars
834
- }, {
835
- currentContent: getRenderableContent(previousBlock, previewStage),
836
- nextContent: getRenderableContent(nextBlock, previewStage)
837
- });
866
+ function getRenderableContent(block, previewStage = "published") {
867
+ const source = previewStage === "preview" && block.draftContent ? block.draftContent : block.content ?? {};
868
+ return isObjectRecord(source) ? stripStaleTransitionStyleGroup(source) : {};
838
869
  }
839
- const pairKey = boundaryKey;
840
870
  //#endregion
841
871
  //#region ../blocks/src/system/manifest/hydrateLinks.ts
842
872
  /**
@@ -871,7 +901,7 @@ function hydrateResolvedBookingConsentValue(value, context) {
871
901
  const hydratedItems = value.map((item) => hydrateResolvedBookingConsentValue(item, context));
872
902
  return hydratedItems.every((item, index) => item === value[index]) ? value : hydratedItems;
873
903
  }
874
- if (!isRecord$13(value)) return value;
904
+ if (!isRecord$11(value)) return value;
875
905
  if (isBookingConsentCarrier(value)) {
876
906
  const agreement = hydrateValue(value.agreement, context);
877
907
  return agreement === value.agreement ? value : {
@@ -891,7 +921,7 @@ function hydrateValue(value, context) {
891
921
  const resolvedItems = value.map((item) => hydrateValue(item, context));
892
922
  return resolvedItems.every((item, index) => item === value[index]) ? value : resolvedItems;
893
923
  }
894
- if (isRecord$13(value)) {
924
+ if (isRecord$11(value)) {
895
925
  if (isInternalLink(value)) return hydrateInternalLink(value, context.routes);
896
926
  if (isPageLink(value)) return hydratePageLink(value, context);
897
927
  if (isEntryLink(value)) return hydrateEntryLink(value, context);
@@ -956,7 +986,7 @@ function hydrateEntryLink(link, context) {
956
986
  //#region ../blocks/src/system/manifest/resolveBlockData.ts
957
987
  function resolveBlockData(blockId, dataLoaders, dataContext, routes) {
958
988
  const raw = blockId ? dataContext?.resolvedData?.[blockId] : void 0;
959
- if (isRecord$13(raw)) return routes ? hydrateResolvedBookingConsentLinks(raw, routes, dataContext?.pagesByIdentifier, dataContext?.entriesByIdentifier) : raw;
989
+ if (isRecord$11(raw)) return routes ? hydrateResolvedBookingConsentLinks(raw, routes, dataContext?.pagesByIdentifier, dataContext?.entriesByIdentifier) : raw;
960
990
  return dataLoaders && typeof dataLoaders === "object" && Object.keys(dataLoaders).length > 0 ? {} : void 0;
961
991
  }
962
992
  //#endregion
@@ -991,23 +1021,44 @@ function preparePageRender(input) {
991
1021
  prepared
992
1022
  });
993
1023
  }
994
- if (constructionFailures.length === 0 || input.audience === "authoring") return {
995
- entries,
996
- constructionFailures,
997
- runtimeBoundaries: input.plan.runtimeBoundaries
998
- };
999
- const survivors = entries.filter((candidate) => candidate.prepared.kind !== "render-threw");
1024
+ const survivors = input.audience === "authoring" ? entries : entries.filter((candidate) => candidate.prepared.kind !== "render-threw");
1000
1025
  return {
1001
1026
  entries: survivors,
1002
1027
  constructionFailures,
1003
- runtimeBoundaries: retargetBoundariesAcrossOmissions({
1004
- boundaries: input.plan.runtimeBoundaries,
1005
- originalBlocks: input.plan.entries.map((planned) => planned.block),
1006
- survivingBlocks: new Set(survivors.map((survivor) => survivor.entry.block)),
1007
- previewStage: input.previewStage
1008
- })
1028
+ joins: composeSurvivorJoins(input.plan, survivors, input.themeResources)
1009
1029
  };
1010
1030
  }
1031
+ /**
1032
+ * The only place joins are composed. Plan-time omissions were already
1033
+ * re-pointed by the plan; construction failures are re-pointed here by the
1034
+ * same primitive, so `[A, B, C]` losing B still gets an A→C join. Each
1035
+ * survivor is then classified from its final content.
1036
+ */
1037
+ function composeSurvivorJoins(plan, survivors, themeResources) {
1038
+ return composePageJoins({
1039
+ joins: retargetJoinsAcrossOmissions({
1040
+ joins: plan.runtimeJoins,
1041
+ originalBlocks: plan.entries.map((planned) => planned.block),
1042
+ survivingBlocks: new Set(survivors.map((survivor) => survivor.entry.block))
1043
+ }),
1044
+ survivors: survivors.map(({ entry }) => ({
1045
+ id: entry.block.id,
1046
+ kind: entry.block.kind,
1047
+ content: boundaryClassificationContent(entry, themeResources)
1048
+ }))
1049
+ });
1050
+ }
1051
+ /**
1052
+ * The content a join is classified from must be the content that paints the
1053
+ * section. The default block renderer layers the theme's per-block style
1054
+ * defaults (`theme.blockOverrides[kind].styles`, background included) under
1055
+ * the block's own `_sectionStyles`, so classify that same projection. An
1056
+ * override component renders its own markup from the unmerged content.
1057
+ */
1058
+ function boundaryClassificationContent(entry, themeResources) {
1059
+ if (entry.kind !== "renderable" || entry.override) return entry.renderableContent;
1060
+ return mergeContentWithBlockStyleOverrides(entry.renderableContent, themeResources.kind === "available" ? themeResources.config : void 0, entry.block.kind);
1061
+ }
1011
1062
  function prepareEntry(entry, input) {
1012
1063
  if (entry.kind !== "renderable") return { kind: "plan-decided" };
1013
1064
  const draftContent = previewableEditorContent(entry);
@@ -1078,6 +1129,7 @@ function blockSessionProps(dataContext) {
1078
1129
  supabaseUrl: dataContext?.supabaseUrl,
1079
1130
  portalToken: dataContext?.portalToken ?? null,
1080
1131
  previewToken: dataContext?.previewToken ?? null,
1132
+ readAuthority: dataContext?.readAuthority,
1081
1133
  stage: dataContext?.previewStage
1082
1134
  };
1083
1135
  }
@@ -1179,7 +1231,7 @@ function EditorPageRenderer(props) {
1179
1231
  });
1180
1232
  }
1181
1233
  function PageRendererCore(props) {
1182
- const { page, audience, runtimeBoundaries, dataContext, routeMap, registry, sdkConfig, customBlocks, blockOverrides } = props;
1234
+ const { page, audience, runtimeJoins, dataContext, routeMap, registry, sdkConfig, customBlocks, blockOverrides } = props;
1183
1235
  const imageResolveContext = React$1.useMemo(() => resolvePageRendererImageResolveContext(dataContext), [
1184
1236
  dataContext?.imageResolveContext,
1185
1237
  dataContext?.mediaAssets,
@@ -1195,7 +1247,7 @@ function PageRendererCore(props) {
1195
1247
  blocks: []
1196
1248
  },
1197
1249
  audience,
1198
- runtimeBoundaries,
1250
+ runtimeJoins,
1199
1251
  previewStage,
1200
1252
  sdkConfig,
1201
1253
  customBlocks,
@@ -1203,7 +1255,7 @@ function PageRendererCore(props) {
1203
1255
  }), [
1204
1256
  page,
1205
1257
  audience,
1206
- runtimeBoundaries,
1258
+ runtimeJoins,
1207
1259
  previewStage,
1208
1260
  sdkConfig,
1209
1261
  customBlocks,
@@ -1220,19 +1272,16 @@ function PageRendererCore(props) {
1220
1272
  dataContext,
1221
1273
  routeMap,
1222
1274
  themeResources,
1223
- imageResolveContext,
1224
- previewStage
1275
+ imageResolveContext
1225
1276
  }), [
1226
1277
  plan,
1227
1278
  audience,
1228
1279
  dataContext,
1229
1280
  routeMap,
1230
1281
  themeResources,
1231
- imageResolveContext,
1232
- previewStage
1282
+ imageResolveContext
1233
1283
  ]);
1234
- const boundaryByAdjacentBlockIds = React$1.useMemo(() => boundaryMapForAdjacentBlockIds(preparation.runtimeBoundaries ?? []), [preparation.runtimeBoundaries]);
1235
- const usesRuntimeBoundaries = preparation.runtimeBoundaries !== void 0;
1284
+ const joinSlots = React$1.useMemo(() => joinSlotsByPair(preparation.joins), [preparation.joins]);
1236
1285
  reportAndReplayOmissions({
1237
1286
  plan,
1238
1287
  preparation,
@@ -1250,10 +1299,9 @@ function PageRendererCore(props) {
1250
1299
  themeResources,
1251
1300
  imageResolveContext,
1252
1301
  resolvedRegistry,
1253
- boundaryByAdjacentBlockIds,
1254
- usesRuntimeBoundaries,
1302
+ joinSlots,
1255
1303
  wrapBlock: props.wrapBlock,
1256
- wrapBoundary: props.wrapBoundary
1304
+ renderJoin: props.renderJoin
1257
1305
  })) });
1258
1306
  }
1259
1307
  /**
@@ -1342,27 +1390,25 @@ function requireEntryBlockOverride(entry, themeResources) {
1342
1390
  }
1343
1391
  /**
1344
1392
  * Renders one planned block: its wrapper, style-group data attributes,
1345
- * boundary reserve space and any boundary or transition sibling that follows.
1393
+ * boundary reserve space and the join markup that follows it.
1346
1394
  *
1347
1395
  * Extracted from PageRendererCore so the component stays about wiring the plan
1348
1396
  * rather than also owning per-block markup.
1349
1397
  */
1350
1398
  function renderPlanEntry(input) {
1351
- const { index, entries, props, themeResources, imageResolveContext, resolvedRegistry, boundaryByAdjacentBlockIds, usesRuntimeBoundaries, wrapBlock, wrapBoundary } = input;
1399
+ const { index, entries, props, themeResources, imageResolveContext, resolvedRegistry, joinSlots, wrapBlock, renderJoin } = input;
1352
1400
  const entry = input.entry.entry;
1353
1401
  const block = entry.block;
1354
1402
  const blockPosition = pageBlockPosition(index, entries.length);
1355
1403
  const blockKey = blockKeyFor(block, index);
1356
1404
  const previousBlock = entries[index - 1]?.entry.block ?? null;
1357
1405
  const nextBlock = entries[index + 1]?.entry.block ?? null;
1358
- const boundaryBefore = boundaryBetweenBlocks(previousBlock, block, boundaryByAdjacentBlockIds);
1359
- const boundaryAfter = boundaryBetweenBlocks(block, nextBlock, boundaryByAdjacentBlockIds);
1360
- const boundaryElement = renderBoundaryAfterBlock({
1361
- block,
1362
- nextBlock,
1406
+ const joinBefore = joinSlotBetween(previousBlock?.id, block.id, joinSlots);
1407
+ const joinAfter = joinSlotBetween(block.id, nextBlock?.id, joinSlots);
1408
+ const boundaryElement = renderJoinSlot({
1409
+ slot: joinAfter,
1363
1410
  blockKey,
1364
- boundaryByAdjacentBlockIds,
1365
- wrapBoundary
1411
+ renderJoin
1366
1412
  });
1367
1413
  const cleanKind = block.kind.replace(/^block\./, "");
1368
1414
  const managesOwnWrapper = entry.kind === "renderable" && entry.managesOwnWrapper;
@@ -1385,11 +1431,10 @@ function renderPlanEntry(input) {
1385
1431
  const styleGroup = typeof renderableContent.styleGroup === "string" ? renderableContent.styleGroup : void 0;
1386
1432
  const blockLook = typeof renderableContent.blockLook === "string" ? renderableContent.blockLook : void 0;
1387
1433
  const blockComposition = readBlockComposition(renderableContent.blockComposition);
1388
- const transitionStyle = transitionCssVarsStyle(renderableContent);
1389
- const blockStyle = mergeStyleObjects(transitionStyle, boundaryReserveCssVarsStyle({
1390
- before: boundaryBefore,
1391
- after: boundaryAfter
1392
- }));
1434
+ const reserves = blockBoundaryReserves({
1435
+ before: joinBefore,
1436
+ after: joinAfter
1437
+ });
1393
1438
  const blockElement = /* @__PURE__ */ jsx("div", {
1394
1439
  className: wrapperClassName,
1395
1440
  "data-block": cleanKind,
@@ -1401,21 +1446,14 @@ function renderPlanEntry(input) {
1401
1446
  "data-block-composition": blockComposition?.treatment,
1402
1447
  "data-block-composition-kind": blockComposition?.kind,
1403
1448
  "data-page-block-position": blockPosition,
1404
- "data-site-style-boundary-before": boundaryBefore?.metrics.size,
1405
- "data-site-style-boundary-after": boundaryAfter?.metrics.size,
1449
+ "data-site-style-boundary-before": reserves.topPlacement,
1450
+ "data-site-style-boundary-after": reserves.bottomPlacement,
1406
1451
  "data-style-group": styleGroup,
1407
- style: blockStyle,
1452
+ style: reserves.style,
1408
1453
  children: /* @__PURE__ */ jsx(MemoBlockSection, { ...blockSectionProps })
1409
1454
  }, blockKey);
1410
1455
  if (boundaryElement) return /* @__PURE__ */ jsxs(React$1.Fragment, { children: [blockElement, boundaryElement] }, blockKey);
1411
- if (usesRuntimeBoundaries || !isSiteStyleTransitionStyleGroup(styleGroup)) return blockElement;
1412
- return /* @__PURE__ */ jsxs(React$1.Fragment, { children: [blockElement, /* @__PURE__ */ jsx("div", {
1413
- "aria-hidden": "true",
1414
- "data-block-transition": "",
1415
- "data-block-transition-for": block.id ?? blockKey,
1416
- "data-style-group": styleGroup,
1417
- style: transitionStyle
1418
- })] }, blockKey);
1456
+ return blockElement;
1419
1457
  }
1420
1458
  function resolvePageRendererImageResolveContext(dataContext) {
1421
1459
  const input = dataContext?.imageResolveContext;
@@ -2061,6 +2099,17 @@ function coerceToString(value) {
2061
2099
  return "";
2062
2100
  }
2063
2101
  /**
2102
+ * The appointment-services catalogue (issue 1403) pairs the services with the
2103
+ * site's ordered categories. Both are needed to group them, so that response
2104
+ * is passed through whole; any other `{ services }` wrapper is unwrapped.
2105
+ */
2106
+ function coerceServicesPayload(record) {
2107
+ return Array.isArray(record.services) && Array.isArray(record.categories) ? {
2108
+ services: record.services,
2109
+ categories: record.categories
2110
+ } : record.services;
2111
+ }
2112
+ /**
2064
2113
  * Extract data from API response.
2065
2114
  * Unwraps common response wrappers: { data }, { form }, { entries }, { services }, { teamMembers }
2066
2115
  *
@@ -2075,7 +2124,7 @@ function coercePayload(payload) {
2075
2124
  if ("data" in record && typeof record.data !== "function") return record.data;
2076
2125
  if ("form" in record && typeof record.form !== "function") return record.form;
2077
2126
  if ("entries" in record && typeof record.entries !== "function") return record.entries;
2078
- if ("services" in record && typeof record.services !== "function") return record.services;
2127
+ if ("services" in record && typeof record.services !== "function") return coerceServicesPayload(record);
2079
2128
  if ("teamMembers" in record && typeof record.teamMembers !== "function") return record.teamMembers;
2080
2129
  }
2081
2130
  return payload;
@@ -2652,12 +2701,19 @@ const bookingQuestionsFlatSchemaSchema = z.object({
2652
2701
  version: z.string().default("1.0"),
2653
2702
  fields: z.array(bookingQuestionFieldSchema).min(1, "Form must have at least one question")
2654
2703
  }).strict();
2655
- z.union([bookingQuestionsFlatSchemaSchema, bookingQuestionsDetailedSchemaSchema]);
2704
+ const bookingQuestionsStoredSchemaSchema = z.union([bookingQuestionsFlatSchemaSchema, bookingQuestionsDetailedSchemaSchema]);
2656
2705
  const formSlugSchema = z.string().min(1, "Form slug is required").regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Use lowercase letters, numbers, and hyphens only").transform((value) => value);
2706
+ /**
2707
+ * A form's fields as sent to the Forms API: the generic contract, or the
2708
+ * booking-questions contract (which adds file uploads). Which one a form may
2709
+ * use depends on its type, which the service checks — on update the type
2710
+ * lives on the stored form, not the request.
2711
+ */
2712
+ const formPayloadFieldsSchema = z.union([formSchemaSchema, bookingQuestionsStoredSchemaSchema]);
2657
2713
  z.object({
2658
2714
  name: z.string().min(1, "Form name is required"),
2659
2715
  slug: formSlugSchema,
2660
- schema: formSchemaSchema,
2716
+ schema: formPayloadFieldsSchema,
2661
2717
  settings: formSettingsInputSchema.optional(),
2662
2718
  presentation: formPresentationSettingsSchema.optional()
2663
2719
  }).strict();
@@ -2856,7 +2912,7 @@ function assertRelativeStoragePath(value) {
2856
2912
  if (!parsed.ok) throw new Error(`Expected RelativeStoragePath, got ${parsed.error.tag}`);
2857
2913
  return parsed.value;
2858
2914
  }
2859
- function isRecord$11(value) {
2915
+ function isRecord$9(value) {
2860
2916
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
2861
2917
  }
2862
2918
  function parseFileKindJson(value) {
@@ -3077,7 +3133,7 @@ function parseEntitledCustomerAccessScopeJson(value) {
3077
3133
  }
3078
3134
  }
3079
3135
  function requireRecord(value) {
3080
- if (!isRecord$11(value)) return err("expected-object");
3136
+ if (!isRecord$9(value)) return err("expected-object");
3081
3137
  return ok(value);
3082
3138
  }
3083
3139
  function requireString(value) {
@@ -3329,7 +3385,7 @@ const DEFAULT_MESSAGES = {
3329
3385
  update: "Failed to update media asset",
3330
3386
  delete: "Failed to delete media asset"
3331
3387
  };
3332
- function isRecord$10(value) {
3388
+ function isRecord$8(value) {
3333
3389
  return typeof value === "object" && value !== null;
3334
3390
  }
3335
3391
  const normalizeLabels = (labels) => labels !== void 0 && labels.length > 0 ? labels.map((label) => label.trim()).filter((label) => label.length > 0).join(",") : void 0;
@@ -3363,7 +3419,7 @@ const filterUpdatePayload = (input) => {
3363
3419
  return payload;
3364
3420
  };
3365
3421
  const extractErrorMessage = (body) => {
3366
- if (!isRecord$10(body)) return typeof body === "string" && body.trim().length > 0 ? body : null;
3422
+ if (!isRecord$8(body)) return typeof body === "string" && body.trim().length > 0 ? body : null;
3367
3423
  for (const key of [
3368
3424
  "error",
3369
3425
  "message",
@@ -3376,11 +3432,11 @@ const extractErrorMessage = (body) => {
3376
3432
  const details = body.details;
3377
3433
  if (Array.isArray(details)) for (const entry of details) {
3378
3434
  if (typeof entry === "string" && entry.trim().length > 0) return entry;
3379
- if (isRecord$10(entry) && typeof entry.message === "string" && entry.message.trim().length > 0) return entry.message;
3435
+ if (isRecord$8(entry) && typeof entry.message === "string" && entry.message.trim().length > 0) return entry.message;
3380
3436
  }
3381
3437
  const errors = body.errors;
3382
3438
  if (Array.isArray(errors)) {
3383
- for (const entry of errors) if (isRecord$10(entry) && typeof entry.message === "string" && entry.message.trim().length > 0) return entry.message;
3439
+ for (const entry of errors) if (isRecord$8(entry) && typeof entry.message === "string" && entry.message.trim().length > 0) return entry.message;
3384
3440
  }
3385
3441
  return null;
3386
3442
  };
@@ -5258,7 +5314,7 @@ function parseBackgroundOverrideFromContent(content) {
5258
5314
  * Only the explicit owner marker can make a background a page-design override.
5259
5315
  */
5260
5316
  function parseCanonicalSectionBackground(content) {
5261
- const background = (isRecord$9(content._sectionStyles) ? content._sectionStyles : null)?.background;
5317
+ const background = (isRecord$7(content._sectionStyles) ? content._sectionStyles : null)?.background;
5262
5318
  if (background === null || background === void 0) return { kind: "none" };
5263
5319
  const canonical = parseBackgroundContent(background);
5264
5320
  if (!canonical) return { kind: "none" };
@@ -5276,7 +5332,7 @@ function parseBackgroundOverride(value) {
5276
5332
  kind: "supported",
5277
5333
  override: DEFAULT_BACKGROUND_OVERRIDE
5278
5334
  };
5279
- if (!isRecord$9(value)) return {
5335
+ if (!isRecord$7(value)) return {
5280
5336
  kind: "unsupported",
5281
5337
  reason: "unsupported-shape",
5282
5338
  background: {}
@@ -5364,7 +5420,7 @@ function parseBackgroundOverride(value) {
5364
5420
  }
5365
5421
  }
5366
5422
  function applyBackgroundOverrideContentPatch(content, override) {
5367
- const sectionStyles = isRecord$9(content._sectionStyles) ? content._sectionStyles : {};
5423
+ const sectionStyles = isRecord$7(content._sectionStyles) ? content._sectionStyles : {};
5368
5424
  const serialized = serializeBackgroundOverride(override);
5369
5425
  if (serialized === null) return withSectionStyles(content, omitRecordKey$1(sectionStyles, "background"));
5370
5426
  return withSectionStyles(content, {
@@ -5588,7 +5644,7 @@ function imageAllowed(mediaId, pool) {
5588
5644
  return pool?.some((item) => item.mediaId === mediaId) ?? false;
5589
5645
  }
5590
5646
  function parseImageMediaAssetId(value) {
5591
- if (!isRecord$9(value)) return { kind: "missing" };
5647
+ if (!isRecord$7(value)) return { kind: "missing" };
5592
5648
  if (value.type !== void 0 && value.type !== "image") return { kind: "missing" };
5593
5649
  const parsed = parseMediaAssetId(value.assetId);
5594
5650
  if (!parsed.ok) return value.assetId === void 0 || value.assetId === null ? { kind: "missing" } : { kind: "invalid" };
@@ -5629,7 +5685,7 @@ function withSectionStyles(content, sectionStyles) {
5629
5685
  function omitRecordKey$1(content, key) {
5630
5686
  return Object.fromEntries(Object.entries(content).filter(([entryKey]) => entryKey !== key));
5631
5687
  }
5632
- function isRecord$9(value) {
5688
+ function isRecord$7(value) {
5633
5689
  return typeof value === "object" && value !== null && !Array.isArray(value);
5634
5690
  }
5635
5691
  //#endregion
@@ -6229,10 +6285,12 @@ function applyPreviewCustomizeActionToLoadedState(state, action) {
6229
6285
  ...state.editorModel,
6230
6286
  boundaries: state.editorModel.boundaries.map((boundary) => {
6231
6287
  if (boundary.previousBlockId !== action.previousBlockId || boundary.nextBlockId !== action.nextBlockId) return boundary;
6232
- return {
6233
- ...boundary,
6234
- breakChoice: optimisticBoundaryBreakChoice(state.editorModel, boundary, action)
6235
- };
6288
+ return resolvePageDesignEditorBoundaryForChoice({
6289
+ editorModel: state.editorModel,
6290
+ previousBlockId: boundary.previousBlockId,
6291
+ nextBlockId: boundary.nextBlockId,
6292
+ choice: optimisticBoundaryChoice(action)
6293
+ }) ?? boundary;
6236
6294
  })
6237
6295
  }
6238
6296
  };
@@ -6265,26 +6323,17 @@ function optimisticLayoutLookState(block, layoutVariantKey) {
6265
6323
  default: return assertNever$1(plan, "Unhandled layout/Look compatibility plan");
6266
6324
  }
6267
6325
  }
6268
- function optimisticBoundaryBreakChoice(editorModel, boundary, action) {
6326
+ /**
6327
+ * The stored choice an action leaves behind. The effective break, its source
6328
+ * and the join are then resolved by theme-core, exactly as the server will.
6329
+ */
6330
+ function optimisticBoundaryChoice(action) {
6269
6331
  switch (action.kind) {
6270
- case "set-boundary": return {
6271
- kind: "user-pinned",
6272
- value: action.boundaryOptionId,
6273
- status: "supported",
6274
- effectiveValue: action.boundaryOptionId
6275
- };
6276
- case "reset-boundary": return {
6277
- kind: "auto",
6278
- effectiveValue: autoBoundaryEffectiveValue(editorModel, boundary)
6279
- };
6332
+ case "set-boundary": return userPinnedDesignChoice(boundaryTreatmentForBoundaryOptionId(action.boundaryOptionId));
6333
+ case "reset-boundary": return autoDesignChoice();
6280
6334
  default: return assertNever$1(action, "Unhandled optimistic boundary action");
6281
6335
  }
6282
6336
  }
6283
- function autoBoundaryEffectiveValue(editorModel, boundary) {
6284
- const preferredBoundaryOptionId = editorModel.pageFlowPresets.find((preset) => preset.id === editorModel.pageFlow.effectiveValue)?.defaultBoundaryOptionId ?? null;
6285
- if (preferredBoundaryOptionId && boundary.availableBreaks.some((option) => option.id === preferredBoundaryOptionId)) return preferredBoundaryOptionId;
6286
- return boundary.availableBreaks[0]?.id ?? null;
6287
- }
6288
6337
  //#endregion
6289
6338
  //#region ../blocks/src/system/customize/facets.ts
6290
6339
  function defineCustomizeFacet(definition) {
@@ -6430,8 +6479,8 @@ function contentWithPreviousLayoutVariant(currentContent, previousContent) {
6430
6479
  return nextContent;
6431
6480
  }
6432
6481
  function contentWithPreviousBackground(currentContent, previousContent) {
6433
- const previousSectionStyles = isRecord$8(previousContent._sectionStyles) ? previousContent._sectionStyles : {};
6434
- const nextSectionStyles = { ...isRecord$8(currentContent._sectionStyles) ? currentContent._sectionStyles : {} };
6482
+ const previousSectionStyles = isRecord$6(previousContent._sectionStyles) ? previousContent._sectionStyles : {};
6483
+ const nextSectionStyles = { ...isRecord$6(currentContent._sectionStyles) ? currentContent._sectionStyles : {} };
6435
6484
  if (Object.prototype.hasOwnProperty.call(previousSectionStyles, "background")) nextSectionStyles.background = previousSectionStyles.background;
6436
6485
  else delete nextSectionStyles.background;
6437
6486
  if (Object.keys(nextSectionStyles).length > 0) return {
@@ -6444,9 +6493,9 @@ function contentWithPreviousBackground(currentContent, previousContent) {
6444
6493
  }
6445
6494
  function withRuntimeBackgroundImageAsset(content, imageAsset) {
6446
6495
  if (!imageAsset) return content;
6447
- const sectionStyles = isRecord$8(content._sectionStyles) ? content._sectionStyles : null;
6448
- const background = isRecord$8(sectionStyles?.background) ? sectionStyles.background : null;
6449
- const image = isRecord$8(background?.image) ? background.image : null;
6496
+ const sectionStyles = isRecord$6(content._sectionStyles) ? content._sectionStyles : null;
6497
+ const background = isRecord$6(sectionStyles?.background) ? sectionStyles.background : null;
6498
+ const image = isRecord$6(background?.image) ? background.image : null;
6450
6499
  if (!sectionStyles || !background || !image || background.type !== "image") return content;
6451
6500
  return {
6452
6501
  ...content,
@@ -6459,7 +6508,7 @@ function withRuntimeBackgroundImageAsset(content, imageAsset) {
6459
6508
  }
6460
6509
  };
6461
6510
  }
6462
- function isRecord$8(value) {
6511
+ function isRecord$6(value) {
6463
6512
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
6464
6513
  }
6465
6514
  //#endregion
@@ -6489,7 +6538,7 @@ function rollbackPreviewCustomizeDraftPatch(uiStore, patch) {
6489
6538
  }
6490
6539
  function currentLocalBlockContent(uiStore, targetBlockId) {
6491
6540
  const current = uiStore.getState().drafts.getCurrentValues(unsafeAsEditorBlockId(targetBlockId));
6492
- return isRecord$7(current) ? current : null;
6541
+ return isRecord$5(current) ? current : null;
6493
6542
  }
6494
6543
  function replaceLocalBlockContentWithoutHistory(input) {
6495
6544
  const editorBlockId = unsafeAsEditorBlockId(input.targetBlockId);
@@ -6542,7 +6591,7 @@ function localRuntimeDraftForBlock(input) {
6542
6591
  }
6543
6592
  };
6544
6593
  }
6545
- function isRecord$7(value) {
6594
+ function isRecord$5(value) {
6546
6595
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
6547
6596
  }
6548
6597
  //#endregion
@@ -7029,6 +7078,7 @@ function PreviewEntryControllerProvider({ children, siteId, pageId, routeId: pro
7029
7078
  const normalizedInitialBlocks = useMemo(() => {
7030
7079
  return (initialBlocks ?? []).map((b, index) => ({
7031
7080
  id: b.id ?? null,
7081
+ contentVersionId: b.contentVersionId ?? null,
7032
7082
  kind: b.kind,
7033
7083
  orderIndex: typeof b.orderIndex === "number" ? b.orderIndex : index,
7034
7084
  content: b.content ?? null,
@@ -7386,25 +7436,25 @@ const INITIAL_ONBOARDING_CONFIRMATION_STATE = {
7386
7436
  resendFeedback: null,
7387
7437
  statusLoadFailed: false
7388
7438
  };
7389
- function isRecord$6(value) {
7439
+ function isRecord$4(value) {
7390
7440
  return value !== null && typeof value === "object";
7391
7441
  }
7392
7442
  function getErrorMessageFromEnvelope(payload, fallback) {
7393
- const error = isRecord$6(payload) ? payload.error : null;
7394
- const message = isRecord$6(error) ? error.message : null;
7443
+ const error = isRecord$4(payload) ? payload.error : null;
7444
+ const message = isRecord$4(error) ? error.message : null;
7395
7445
  return typeof message === "string" && message.trim().length > 0 ? message : fallback;
7396
7446
  }
7397
7447
  function isLaunchReadiness(value) {
7398
- return isRecord$6(value) && Array.isArray(value.requirements) && typeof value.pendingRequiredCount === "number" && typeof value.pendingRecommendedCount === "number" && typeof value.pendingOptionalCount === "number" && isRecord$6(value.goLiveDecision) && (value.goLiveDecision.kind === "allowed" || value.goLiveDecision.kind === "blocked");
7448
+ return isRecord$4(value) && Array.isArray(value.requirements) && typeof value.pendingRequiredCount === "number" && typeof value.pendingRecommendedCount === "number" && typeof value.pendingOptionalCount === "number" && isRecord$4(value.goLiveDecision) && (value.goLiveDecision.kind === "allowed" || value.goLiveDecision.kind === "blocked");
7399
7449
  }
7400
7450
  function isOnboardingPreviewStatusResponse(value) {
7401
- return isRecord$6(value) && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
7451
+ return isRecord$4(value) && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
7402
7452
  }
7403
7453
  function isResendOnboardingPreviewConfirmationResponse(value) {
7404
- return isRecord$6(value) && (value.result === "resent" || value.result === "already_confirmed") && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
7454
+ return isRecord$4(value) && (value.result === "resent" || value.result === "already_confirmed") && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
7405
7455
  }
7406
7456
  function getSuccessData(payload, isData) {
7407
- if (!isRecord$6(payload) || payload.success !== true || !isData(payload.data)) return null;
7457
+ if (!isRecord$4(payload) || payload.success !== true || !isData(payload.data)) return null;
7408
7458
  return payload.data;
7409
7459
  }
7410
7460
  function useOnboardingConfirmationCheck(input) {
@@ -9250,10 +9300,10 @@ function resolveShellThemeRoles(props) {
9250
9300
  }
9251
9301
  const previewContainerResponsiveEnabled = process.env.NEXT_PUBLIC_ENABLE_PREVIEW_CONTAINER_RESPONSIVE !== "false";
9252
9302
  const PreviewEditorSidebar = React.lazy(async () => {
9253
- return { default: (await import("./PreviewEditorSidebar-DROGfMKi.mjs")).PreviewEditorSidebar };
9303
+ return { default: (await import("./PreviewEditorSidebar-O-V6Pl5a.mjs")).PreviewEditorSidebar };
9254
9304
  });
9255
9305
  const PreviewEditorUI = React.lazy(async () => {
9256
- return { default: (await import("./PreviewEditorUI-BaRjhFu-.mjs")).PreviewEditorUI };
9306
+ return { default: (await import("./PreviewEditorUI-1UlX_9cw.mjs")).PreviewEditorUI };
9257
9307
  });
9258
9308
  const previewPaneContainmentStyle = {
9259
9309
  contain: "layout paint",
@@ -9700,11 +9750,11 @@ function resolveShellAccess(input) {
9700
9750
  //#region ../preview-next/src/client/utils/path.ts
9701
9751
  const PATH_SEPARATOR_REGEX = /\./g;
9702
9752
  const BRACKET_ACCESS_REGEX = /\[([^\]]+)\]/g;
9703
- function isRecord$5(value) {
9753
+ function isRecord$3(value) {
9704
9754
  return typeof value === "object" && value !== null && !Array.isArray(value);
9705
9755
  }
9706
9756
  function isPathContainer(value) {
9707
- return Array.isArray(value) || isRecord$5(value);
9757
+ return Array.isArray(value) || isRecord$3(value);
9708
9758
  }
9709
9759
  function createPathContainer(nextIsIndex) {
9710
9760
  return nextIsIndex ? [] : {};
@@ -9867,24 +9917,21 @@ function runtimeContentDecorationProjectionFromEditorModel(editorModel, surfaceR
9867
9917
  kind: "runtime-content-decoration",
9868
9918
  source: "page-design",
9869
9919
  fieldsByBlockId: runtimeFieldsByBlockId(compiled.blocks),
9870
- boundaries: compiled.boundaries
9920
+ joins: compiled.joins
9871
9921
  };
9872
9922
  }
9873
9923
  function runtimeFieldsByBlockId(blocks) {
9874
9924
  return new Map(blocks.map((block) => [block.blockId, block.fields]));
9875
9925
  }
9876
- function applyRuntimeContentDecorationProjection(block, content, projection, adjacency) {
9926
+ function applyRuntimeContentDecorationProjection(block, content, projection) {
9877
9927
  const blockId = designBlockIdFromBlockItem(block);
9878
- const retargetedFields = retargetCompiledRuntimeFieldsForContentAdjacency(blockId ? projection.fieldsByBlockId.get(blockId) : void 0, {
9879
- currentContent: isRecord$4(content) ? content : null,
9880
- nextContent: adjacency?.nextContent
9881
- });
9882
- return applyCompiledRuntimeFieldsToContent(isRecord$4(content) ? content : {}, retargetedFields);
9928
+ const fields = blockId ? projection.fieldsByBlockId.get(blockId) : void 0;
9929
+ return applyCompiledRuntimeFieldsToContent(isRecord$2(content) ? content : {}, fields);
9883
9930
  }
9884
9931
  function designBlockIdFromBlockItem(block) {
9885
9932
  return typeof block.id === "string" && block.id.length > 0 ? asDesignBlockId(block.id) : null;
9886
9933
  }
9887
- function isRecord$4(value) {
9934
+ function isRecord$2(value) {
9888
9935
  return typeof value === "object" && value !== null && !Array.isArray(value);
9889
9936
  }
9890
9937
  //#endregion
@@ -9901,10 +9948,10 @@ function applyPreviewContentFieldProjections(blockId, content, projections) {
9901
9948
  return applyContentFieldOverrideProjection(blockId, current, projection);
9902
9949
  }, content);
9903
9950
  }
9904
- function applyPreviewRuntimeContentProjections(block, content, projections, adjacency) {
9951
+ function applyPreviewRuntimeContentProjections(block, content, projections) {
9905
9952
  return projections.reduce((current, projection) => {
9906
9953
  if (projection.kind !== "runtime-content-decoration") return current;
9907
- return applyRuntimeContentDecorationProjection(block, current, projection, adjacency);
9954
+ return applyRuntimeContentDecorationProjection(block, current, projection);
9908
9955
  }, content);
9909
9956
  }
9910
9957
  function blockHasPreviewContentFieldProjection(blockId, projections) {
@@ -9935,7 +9982,7 @@ function overlayValue(value, overlays) {
9935
9982
  });
9936
9983
  return changed ? next : value;
9937
9984
  }
9938
- if (!isRecord$3(value)) return value;
9985
+ if (!isRecord$1(value)) return value;
9939
9986
  const meta = parseLinkedEntryMeta(value[LINKED_CONTENT_ENTRY_META_KEY]);
9940
9987
  if (meta) {
9941
9988
  const overlay = overlays.get(unsafeAsLinkedContentEntryId(meta.entryId));
@@ -10001,7 +10048,7 @@ function resolveOverlayTitle(content, meta) {
10001
10048
  function parseLinkedEntryMeta(value) {
10002
10049
  return getLinkedContentEntryMeta({ [LINKED_CONTENT_ENTRY_META_KEY]: value });
10003
10050
  }
10004
- function isRecord$3(value) {
10051
+ function isRecord$1(value) {
10005
10052
  return typeof value === "object" && value !== null && !Array.isArray(value);
10006
10053
  }
10007
10054
  //#endregion
@@ -10011,48 +10058,36 @@ function getDraftSnapshots(uiStore) {
10011
10058
  const snapshots = uiStore.getState().drafts.inspect();
10012
10059
  return new Map(snapshots.map((snap) => [snap.id, snap]));
10013
10060
  }
10014
- function mergeBlockWithDraft(block, draftMap, index, projections = [], linkedEntryOverlays = EMPTY_LINKED_ENTRY_OVERLAY, nextBlock = null) {
10061
+ function mergeBlockWithDraft(block, draftMap, index, projections = [], linkedEntryOverlays = EMPTY_LINKED_ENTRY_OVERLAY) {
10015
10062
  const id = block.id ?? null;
10016
10063
  const editorBlockId = id ? unsafeAsEditorBlockId(id) : null;
10017
10064
  const snap = editorBlockId ? draftMap.get(editorBlockId) ?? null : null;
10018
10065
  const draftContent = editorBlockId ? readProjectedDraftRenderContent(block, editorBlockId, snap, projections) : null;
10019
10066
  const baseline = snap?.baseline ?? block.content ?? block.publishedContent ?? null;
10020
- const nextContent = nextBlock ? readBlockRenderContents(nextBlock, draftMap, projections) : null;
10021
10067
  return {
10022
10068
  id,
10069
+ contentVersionId: block.contentVersionId ?? null,
10023
10070
  kind: block.kind,
10024
10071
  purpose: "content",
10025
10072
  orderIndex: block.orderIndex ?? index,
10026
- content: renderContent(block, baseline, projections, linkedEntryOverlays, nextContent?.baseline ?? null),
10027
- draftContent: renderContent(block, draftContent, projections, linkedEntryOverlays, nextContent?.draft ?? null),
10028
- publishedContent: renderContent(block, block.publishedContent ?? null, projections, EMPTY_LINKED_ENTRY_OVERLAY, nextContent?.published ?? null),
10073
+ content: renderContent(block, baseline, projections, linkedEntryOverlays),
10074
+ draftContent: renderContent(block, draftContent, projections, linkedEntryOverlays),
10075
+ publishedContent: renderContent(block, block.publishedContent ?? null, projections, EMPTY_LINKED_ENTRY_OVERLAY),
10029
10076
  bindings: block.bindings ?? null
10030
10077
  };
10031
10078
  }
10032
- function readBlockRenderContents(block, draftMap, projections) {
10033
- const id = block.id ?? null;
10034
- const editorBlockId = id ? unsafeAsEditorBlockId(id) : null;
10035
- const snap = editorBlockId ? draftMap.get(editorBlockId) ?? null : null;
10036
- return {
10037
- baseline: snap?.baseline ?? block.content ?? block.publishedContent ?? null,
10038
- draft: editorBlockId ? readProjectedDraftRenderContent(block, editorBlockId, snap, projections) : null,
10039
- published: block.publishedContent ?? null
10040
- };
10041
- }
10042
10079
  function readProjectedDraftRenderContent(block, editorBlockId, snap, projections) {
10043
10080
  return applyPreviewContentFieldProjections(editorBlockId, snap?.current ?? snap?.baseline ?? block.content ?? block.publishedContent ?? null, projections);
10044
10081
  }
10045
- function renderContent(block, content, projections, linkedEntryOverlays, nextContent) {
10046
- return applyPreviewRuntimeContentProjections(block, applyLinkedEntryRenderOverlay(content, linkedEntryOverlays), projections, { nextContent: isRecord$2(nextContent) ? nextContent : null });
10047
- }
10048
- function isRecord$2(value) {
10049
- return typeof value === "object" && value !== null && !Array.isArray(value);
10082
+ function renderContent(block, content, projections, linkedEntryOverlays) {
10083
+ return applyPreviewRuntimeContentProjections(block, applyLinkedEntryRenderOverlay(content, linkedEntryOverlays), projections);
10050
10084
  }
10051
10085
  //#endregion
10052
10086
  //#region ../preview-next/src/client/blocks/composer/transformBlock.ts
10053
10087
  function transformToPageBlock(enriched) {
10054
10088
  return {
10055
10089
  id: enriched.id,
10090
+ ...enriched.contentVersionId !== null ? { contentVersionId: enriched.contentVersionId } : {},
10056
10091
  kind: enriched.kind,
10057
10092
  purpose: enriched.purpose,
10058
10093
  content: enriched.content ?? {},
@@ -10104,8 +10139,7 @@ function composePreviewRenderPage(args, cacheRef) {
10104
10139
  if (!page) return page;
10105
10140
  if (!blockItems.length) return page;
10106
10141
  const draftMap = draftSnapshotMap(draftSnapshots);
10107
- const projectedBlockItems = applyPreviewStructureProjections(blockItems, projections);
10108
- const renderedBlocks = applyCacheOptimization([...projectedBlockItems.map((block, index) => mergeBlockWithDraft(block, draftMap, index, projections, linkedEntryOverlays, projectedBlockItems[index + 1] ?? null))].sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0)), cacheRef);
10142
+ const renderedBlocks = applyCacheOptimization([...applyPreviewStructureProjections(blockItems, projections).map((block, index) => mergeBlockWithDraft(block, draftMap, index, projections, linkedEntryOverlays))].sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0)), cacheRef);
10109
10143
  return {
10110
10144
  ...page,
10111
10145
  blocks: renderedBlocks
@@ -10267,7 +10301,7 @@ const editorRegistry = {
10267
10301
  };
10268
10302
  //#endregion
10269
10303
  //#region ../preview-next/src/client/blocks/isRecord.ts
10270
- function isRecord$1(value) {
10304
+ function isRecord(value) {
10271
10305
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
10272
10306
  }
10273
10307
  //#endregion
@@ -10441,7 +10475,7 @@ function BlockToolbar({ blockId, blockKind, content, bookingOfferingPresets, the
10441
10475
  const uiStore = useEditorUiStoreInstance();
10442
10476
  const editorBlockId = useMemo(() => unsafeAsEditorBlockId(blockId), [blockId]);
10443
10477
  const draftContent = useEditorUiStore((state) => state.drafts.getCurrentValues(editorBlockId));
10444
- const customizeContent = useMemo(() => isRecord$1(draftContent) ? draftContent : content, [content, draftContent]);
10478
+ const customizeContent = useMemo(() => isRecord(draftContent) ? draftContent : content, [content, draftContent]);
10445
10479
  const customizeSelection = usePreviewBlockCustomizeSelectionOptional();
10446
10480
  const popover = useCustomizePopoverController();
10447
10481
  const focusTarget = useMemo(() => computeDefaultFocus(blockKind, customizeContent), [blockKind, customizeContent]);
@@ -10997,13 +11031,13 @@ function findFirstFieldPath(fields, data, prefix) {
10997
11031
  if (Array.isArray(field.visibleRoles) && !field.visibleRoles.includes("author")) continue;
10998
11032
  const nextPrefix = [...prefix, field.id];
10999
11033
  if (field.type === "group") {
11000
- const groupValue = isRecord$1(data) ? data[field.id] : void 0;
11034
+ const groupValue = isRecord(data) ? data[field.id] : void 0;
11001
11035
  const nested = findFirstFieldPath(field.schema.fields, groupValue, nextPrefix);
11002
11036
  if (nested) return nested;
11003
11037
  continue;
11004
11038
  }
11005
11039
  if (field.type === "repeater" && field.schema) {
11006
- const collection = isRecord$1(data) ? data[field.id] : void 0;
11040
+ const collection = isRecord(data) ? data[field.id] : void 0;
11007
11041
  const items = isUnknownArray(collection) ? collection : [];
11008
11042
  if (items.length > 0) {
11009
11043
  const firstItem = items[0];
@@ -11180,7 +11214,7 @@ function dedupeBackgroundImagePool(items) {
11180
11214
  }
11181
11215
  //#endregion
11182
11216
  //#region ../preview-next/src/client/blocks/BoundaryControl.tsx
11183
- function BoundaryControl({ previousBlockId, nextBlockId, previousBlockKind, nextBlockKind }) {
11217
+ function BoundaryControl({ previousBlockId, nextBlockId, previousBlockKind, nextBlockKind, outcome }) {
11184
11218
  const panelId = useId();
11185
11219
  const panelDescriptionId = `${panelId}-description`;
11186
11220
  const [open, setOpen] = useState(false);
@@ -11208,11 +11242,17 @@ function BoundaryControl({ previousBlockId, nextBlockId, previousBlockKind, next
11208
11242
  }, [hasControls]);
11209
11243
  if (!boundary || !hasControls) return null;
11210
11244
  const display = boundaryBreakDisplay(boundary);
11211
- const panelStatus = display.detail ? {
11212
- id: `${panelId}-status`,
11213
- text: display.detail
11214
- } : null;
11215
- const panelDescribedBy = panelStatus ? `${panelDescriptionId} ${panelStatus.id}` : panelDescriptionId;
11245
+ const panelSummaryId = `${panelId}-summary`;
11246
+ const panelStatuses = boundaryPanelStatuses({
11247
+ panelId,
11248
+ detail: display.detail,
11249
+ outcome
11250
+ });
11251
+ const panelDescribedBy = [
11252
+ panelDescriptionId,
11253
+ panelSummaryId,
11254
+ ...panelStatuses.map((status) => status.id)
11255
+ ].join(" ");
11216
11256
  const openPanel = (event) => {
11217
11257
  event.preventDefault();
11218
11258
  event.stopPropagation();
@@ -11316,15 +11356,9 @@ function BoundaryControl({ previousBlockId, nextBlockId, previousBlockKind, next
11316
11356
  })
11317
11357
  })]
11318
11358
  }),
11319
- /* @__PURE__ */ jsxs("div", {
11320
- className: "rounded-lg border border-slate-200 bg-slate-50 p-2 text-center",
11321
- children: [/* @__PURE__ */ jsx("div", {
11322
- className: "truncate text-sm font-medium",
11323
- children: boundaryBreakLabel(boundary)
11324
- }), /* @__PURE__ */ jsx("div", {
11325
- className: "mt-0.5 text-xs text-slate-500",
11326
- children: boundaryBreakModeLabel(boundary)
11327
- })]
11359
+ /* @__PURE__ */ jsx(BoundaryBreakSummary, {
11360
+ id: panelSummaryId,
11361
+ display
11328
11362
  }),
11329
11363
  /* @__PURE__ */ jsxs("div", {
11330
11364
  className: "mt-3",
@@ -11354,11 +11388,7 @@ function BoundaryControl({ previousBlockId, nextBlockId, previousBlockKind, next
11354
11388
  }, variant.boundaryOption.id))
11355
11389
  })]
11356
11390
  }) : null,
11357
- panelStatus ? /* @__PURE__ */ jsx("p", {
11358
- id: panelStatus.id,
11359
- className: "mt-2 text-xs text-slate-500",
11360
- children: panelStatus.text
11361
- }) : null,
11391
+ /* @__PURE__ */ jsx(BoundaryPanelStatusLines, { statuses: panelStatuses }),
11362
11392
  display.canReset ? /* @__PURE__ */ jsxs("button", {
11363
11393
  type: "button",
11364
11394
  className: "mt-2 inline-flex w-full items-center justify-center gap-2 rounded-md border border-slate-200 px-3 py-2 text-sm font-medium text-slate-700 transition hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-sky-400",
@@ -11382,6 +11412,53 @@ function BoundaryControl({ previousBlockId, nextBlockId, previousBlockKind, next
11382
11412
  })
11383
11413
  });
11384
11414
  }
11415
+ /** Approved copy (issue 1422) for a join the renderer did not draw. */
11416
+ const notShownCopy = {
11417
+ "both-unpainted": "This break won't show here, because both sections have an image or video background. It'll appear if you give one of them a color background.",
11418
+ "flush-panel": "This break won't show here, because one of these sections has an image that runs right to its edge. It'll appear if you pick a different look for that section."
11419
+ };
11420
+ /**
11421
+ * Status lines under the controls, each wired into the dialog's
11422
+ * `aria-describedby`. The not-shown line comes from the same composition as
11423
+ * the painted page, so it appears or clears as backgrounds change.
11424
+ */
11425
+ function boundaryPanelStatuses(input) {
11426
+ return [...input.detail ? [{
11427
+ id: `${input.panelId}-status`,
11428
+ kind: "saved-break-unavailable",
11429
+ text: input.detail
11430
+ }] : [], ...input.outcome?.kind === "not-shown" ? [{
11431
+ id: `${input.panelId}-not-shown`,
11432
+ kind: `not-shown:${input.outcome.reason}`,
11433
+ text: notShownCopy[input.outcome.reason]
11434
+ }] : []];
11435
+ }
11436
+ function BoundaryPanelStatusLines({ statuses }) {
11437
+ return statuses.map((status) => /* @__PURE__ */ jsx("p", {
11438
+ id: status.id,
11439
+ "data-boundary-status": status.kind,
11440
+ className: "mt-2 text-xs text-slate-500",
11441
+ children: status.text
11442
+ }, status.id));
11443
+ }
11444
+ /**
11445
+ * The current break and where it comes from. The source is exposed as data so
11446
+ * the state is inspectable without reading the copy.
11447
+ */
11448
+ function BoundaryBreakSummary({ id, display }) {
11449
+ return /* @__PURE__ */ jsxs("div", {
11450
+ id,
11451
+ "data-boundary-break-source": display.source,
11452
+ className: "rounded-lg border border-slate-200 bg-slate-50 p-2 text-center",
11453
+ children: [/* @__PURE__ */ jsx("div", {
11454
+ className: "truncate text-sm font-medium",
11455
+ children: display.label
11456
+ }), /* @__PURE__ */ jsx("div", {
11457
+ className: "mt-0.5 text-xs text-slate-500",
11458
+ children: display.modeLabel
11459
+ })]
11460
+ });
11461
+ }
11385
11462
  function SectionTransitionFamilyButton({ family, active, onClick }) {
11386
11463
  return /* @__PURE__ */ jsx("button", {
11387
11464
  type: "button",
@@ -11405,24 +11482,13 @@ function SectionTransitionVariantButton({ variant, active, onClick }) {
11405
11482
  function sectionTransitionChoiceClassName(active) {
11406
11483
  return ["min-h-8 flex-1 rounded-md px-2.5 text-xs font-medium transition focus:outline-none focus:ring-2 focus:ring-sky-400", active ? "bg-slate-950 text-white shadow-sm" : "bg-transparent text-slate-600 hover:bg-white hover:text-slate-950"].join(" ");
11407
11484
  }
11408
- function boundaryBreakLabel(boundary) {
11409
- return boundaryBreakDisplay(boundary).label;
11410
- }
11411
- function boundaryBreakModeLabel(boundary) {
11412
- return boundaryBreakDisplay(boundary).modeLabel;
11413
- }
11414
11485
  function boundaryBreakDisplay(boundary) {
11415
11486
  const option = boundary.availableBreaks.find((candidate) => candidate.id === boundary.breakChoice.effectiveValue) ?? null;
11416
11487
  switch (boundary.breakChoice.kind) {
11417
- case "auto": return {
11418
- label: option ? `Default: ${option.label}` : "Default",
11419
- modeLabel: "Page Flow",
11420
- detail: null,
11421
- canReset: false,
11422
- resetLabel: "Default"
11423
- };
11488
+ case "auto": return autoBoundaryBreakDisplay(boundary.breakChoice.source, option ? `Default: ${option.label}` : "Default");
11424
11489
  case "user-pinned":
11425
11490
  if (boundary.breakChoice.status === "supported") return {
11491
+ source: "user-pinned",
11426
11492
  label: option?.label ?? "Selected break",
11427
11493
  modeLabel: "Custom",
11428
11494
  detail: null,
@@ -11430,6 +11496,7 @@ function boundaryBreakDisplay(boundary) {
11430
11496
  resetLabel: "Default"
11431
11497
  };
11432
11498
  return {
11499
+ source: "unavailable",
11433
11500
  label: "Saved break unavailable",
11434
11501
  modeLabel: option ? `Using default: ${option.label}` : "Using Page Flow fallback",
11435
11502
  detail: "This page still has a saved custom break that is no longer available for these sections.",
@@ -11439,6 +11506,31 @@ function boundaryBreakDisplay(boundary) {
11439
11506
  default: return assertNever$1(boundary.breakChoice, "Unhandled boundary break choice");
11440
11507
  }
11441
11508
  }
11509
+ /**
11510
+ * A default break has no reset: there is nothing saved to clear. Picking
11511
+ * another break pins it as a user choice, and reset returns here.
11512
+ */
11513
+ function autoBoundaryBreakDisplay(source, label) {
11514
+ switch (source.kind) {
11515
+ case "site-style-default": return {
11516
+ source: "site-style-default",
11517
+ label,
11518
+ modeLabel: "Set by your site style",
11519
+ detail: null,
11520
+ canReset: false,
11521
+ resetLabel: "Default"
11522
+ };
11523
+ case "page-flow-default": return {
11524
+ source: "page-flow-default",
11525
+ label,
11526
+ modeLabel: "Page Flow",
11527
+ detail: null,
11528
+ canReset: false,
11529
+ resetLabel: "Default"
11530
+ };
11531
+ default: return assertNever$1(source, "Unhandled boundary default source");
11532
+ }
11533
+ }
11442
11534
  function formatBlockKindLabel(blockKind) {
11443
11535
  const blockTitle = getBlockDefinition(blockKind)?.manifest.title;
11444
11536
  if (blockTitle) return blockTitle;
@@ -11673,33 +11765,32 @@ function EditablePageRenderer(props) {
11673
11765
  uiStore,
11674
11766
  renderStateVersion
11675
11767
  ]) ?? pageRendererProps.page;
11676
- const runtimeBoundaries = useMemo(() => retargetRuntimeBoundariesForRenderPage(runtimeProjection?.boundaries ?? pageRendererProps.runtimeBoundaries ?? [], renderPage), [
11677
- pageRendererProps.runtimeBoundaries,
11678
- renderPage,
11679
- runtimeProjection
11680
- ]);
11768
+ const runtimeJoins = editorRuntimeJoins(runtimeProjection, pageRendererProps.runtimeJoins);
11681
11769
  const renderedBlockById = useMemo(() => {
11682
11770
  return new Map((renderPage?.blocks ?? []).filter((block) => Boolean(block.id)).map((block) => [block.id, block]));
11683
11771
  }, [renderPage?.blocks]);
11684
- const wrapBoundaryWithControl = useCallback((boundary, rendered) => {
11685
- const previousBlock = renderedBlockById.get(boundary.previousBlockId);
11686
- const nextBlock = renderedBlockById.get(boundary.nextBlockId);
11772
+ const renderJoinWithControl = useCallback((input) => {
11773
+ const previousBlock = renderedBlockById.get(input.previousBlockId);
11774
+ const nextBlock = renderedBlockById.get(input.nextBlockId);
11687
11775
  const control = !isEntryTemplatePage && previousBlock && nextBlock ? /* @__PURE__ */ jsx(BoundaryControl, {
11688
- previousBlockId: asDesignBlockId(boundary.previousBlockId),
11689
- nextBlockId: asDesignBlockId(boundary.nextBlockId),
11776
+ previousBlockId: asDesignBlockId(input.previousBlockId),
11777
+ nextBlockId: asDesignBlockId(input.nextBlockId),
11690
11778
  previousBlockKind: previousBlock.kind,
11691
- nextBlockKind: nextBlock.kind
11779
+ nextBlockKind: nextBlock.kind,
11780
+ outcome: input.join?.outcome ?? null
11692
11781
  }) : null;
11693
- const wrapped = pageRendererProps.wrapBoundary ? pageRendererProps.wrapBoundary(boundary, rendered) : rendered;
11782
+ const extra = pageRendererProps.renderJoin?.(input) ?? null;
11783
+ if (!control && !extra) return null;
11694
11784
  return /* @__PURE__ */ jsxs("div", {
11695
11785
  className: "relative",
11696
11786
  "data-preview-boundary-wrapper": "",
11697
- "data-boundary-id": boundary.boundaryId,
11698
- children: [wrapped, control]
11787
+ "data-boundary-previous-block-id": input.previousBlockId,
11788
+ "data-boundary-next-block-id": input.nextBlockId,
11789
+ children: [extra, control]
11699
11790
  });
11700
11791
  }, [
11701
11792
  isEntryTemplatePage,
11702
- pageRendererProps.wrapBoundary,
11793
+ pageRendererProps.renderJoin,
11703
11794
  renderedBlockById
11704
11795
  ]);
11705
11796
  const wrapBlockWithProvider = useCallback((blockId, rendered) => {
@@ -11770,32 +11861,20 @@ function EditablePageRenderer(props) {
11770
11861
  return /* @__PURE__ */ jsx(EditorPageRenderer, {
11771
11862
  ...pageRendererProps,
11772
11863
  page: renderPage,
11773
- runtimeBoundaries,
11864
+ runtimeJoins,
11774
11865
  registry: allowInlineEditing ? editorRegistry : pageRendererProps.registry ?? clientComponentRegistry,
11775
11866
  wrapBlock: allowInlineEditing ? wrapBlockWithProvider : pageRendererProps.wrapBlock,
11776
- wrapBoundary: allowInlineEditing ? wrapBoundaryWithControl : pageRendererProps.wrapBoundary,
11867
+ renderJoin: allowInlineEditing ? renderJoinWithControl : pageRendererProps.renderJoin,
11777
11868
  dataContext,
11778
11869
  previewAuthoring
11779
11870
  });
11780
11871
  }
11781
- function retargetRuntimeBoundariesForRenderPage(boundaries, page) {
11782
- if (!boundaries?.length) return boundaries;
11783
- const blockById = new Map(page.blocks.filter((block) => Boolean(block.id)).map((block) => [block.id, block]));
11784
- return boundaries.map((boundary) => {
11785
- const currentBlock = blockById.get(boundary.previousBlockId);
11786
- const nextBlock = blockById.get(boundary.nextBlockId);
11787
- return retargetCompiledBoundaryRuntimeForContentAdjacency(boundary, {
11788
- currentContent: renderableBoundaryContent(currentBlock),
11789
- nextContent: renderableBoundaryContent(nextBlock)
11790
- });
11791
- });
11792
- }
11793
- function renderableBoundaryContent(block) {
11794
- const source = block?.draftContent ?? block?.content ?? null;
11795
- return isRecord(source) ? source : null;
11796
- }
11797
- function isRecord(value) {
11798
- return typeof value === "object" && value !== null && !Array.isArray(value);
11872
+ const emptyRuntimeJoins = [];
11873
+ /**
11874
+ * The editor's joins: its live projection wins, then whatever the caller sent.
11875
+ */
11876
+ function editorRuntimeJoins(projection, fallback) {
11877
+ return projection?.joins ?? fallback ?? emptyRuntimeJoins;
11799
11878
  }
11800
11879
  function usePreviewBlockResolvedData(args) {
11801
11880
  const { page, dataContext, apiClient } = args;
@@ -12135,6 +12214,7 @@ function resolveSdkPreviewRuntimeModel(props) {
12135
12214
  const customBlocks = isSdkCustomBlockArray(content.customBlocks) ? content.customBlocks : null;
12136
12215
  const initialBlocks = (page.blocks ?? []).map((block, index) => ({
12137
12216
  id: block.id ?? null,
12217
+ contentVersionId: typeof block.contentVersionId === "string" ? block.contentVersionId : null,
12138
12218
  kind: block.kind,
12139
12219
  purpose: block.purpose ?? null,
12140
12220
  orderIndex: index,