@riverbankcms/sdk 0.147.0 → 0.148.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 (381) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/{PreviewEditorSidebar-DtpB3_sS.mjs → PreviewEditorSidebar-DvEPG3Z2.mjs} +202 -143
  3. package/dist/{PreviewEditorUI-DxTLgaHo.mjs → PreviewEditorUI-D6eb6fkx.mjs} +68 -60
  4. package/dist/{PreviewQueryProvider-Dd4dxOiU.mjs → PreviewQueryProvider-5znTyJuz.mjs} +1 -1
  5. package/dist/{SdkPreviewModeRuntime-DMMNCngt.mjs → SdkPreviewModeRuntime-DJ6utQ_R.mjs} +1191 -513
  6. package/dist/{SiteChromeCustomizeContext-DQXZXiqS.mjs → SiteChromeCustomizeContext-CFJYh6vo.mjs} +201798 -197304
  7. package/dist/_dts/ai/src/contracts/proposals.d.ts +0 -33
  8. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +0 -3
  9. package/dist/_dts/api/src/accessAdmin.d.ts +0 -4
  10. package/dist/_dts/api/src/accountApi.d.ts +1 -1
  11. package/dist/_dts/api/src/admin.d.ts +22 -22
  12. package/dist/_dts/api/src/aiPatch.d.ts +2 -2
  13. package/dist/_dts/api/src/aiPlayground.d.ts +1 -0
  14. package/dist/_dts/api/src/analytics.d.ts +2 -2
  15. package/dist/_dts/api/src/apiEndpointTypes.d.ts +2 -0
  16. package/dist/_dts/api/src/appointmentSetup.d.ts +2 -2
  17. package/dist/_dts/api/src/auth.d.ts +10 -10
  18. package/dist/_dts/api/src/availability.d.ts +6 -6
  19. package/dist/_dts/api/src/billing.d.ts +42 -15
  20. package/dist/_dts/api/src/billingEndpointDefinitions.d.ts +8 -0
  21. package/dist/_dts/api/src/billingEndpointTypes.d.ts +15 -6
  22. package/dist/_dts/api/src/blocks.d.ts +15 -14
  23. package/dist/_dts/api/src/blocksKeys.d.ts +2 -0
  24. package/dist/_dts/api/src/bookingConfig.d.ts +0 -2
  25. package/dist/_dts/api/src/bookingOperations.d.ts +4 -4
  26. package/dist/_dts/api/src/bookingRecords.d.ts +1 -0
  27. package/dist/_dts/api/src/bookings.d.ts +7 -7
  28. package/dist/_dts/api/src/calendar.d.ts +9 -9
  29. package/dist/_dts/api/src/commercePortalEndpoints.d.ts +7 -6
  30. package/dist/_dts/api/src/common/envelope.d.ts +2 -2
  31. package/dist/_dts/api/src/content-editor.d.ts +2 -2
  32. package/dist/_dts/api/src/contentEntries.d.ts +17 -48
  33. package/dist/_dts/api/src/contentRuntime.d.ts +51 -37
  34. package/dist/_dts/api/src/contentTypes.d.ts +11 -11
  35. package/dist/_dts/api/src/contentVersionHistoryClient.d.ts +6 -6
  36. package/dist/_dts/api/src/documentLifecycle.d.ts +67 -0
  37. package/dist/_dts/api/src/domains.d.ts +16 -16
  38. package/dist/_dts/api/src/editLeaseEndpoints.d.ts +72 -0
  39. package/dist/_dts/api/src/emailSettings.d.ts +4 -4
  40. package/dist/_dts/api/src/endpoints.d.ts +133 -41
  41. package/dist/_dts/api/src/eventEmailTemplates.d.ts +2 -2
  42. package/dist/_dts/api/src/eventManagementContracts.d.ts +25 -0
  43. package/dist/_dts/api/src/eventManagementEndpointDefinitions.d.ts +0 -8
  44. package/dist/_dts/api/src/eventPageWords.d.ts +7 -12
  45. package/dist/_dts/api/src/footerSettings.d.ts +6 -6
  46. package/dist/_dts/api/src/index.d.ts +6 -5
  47. package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -0
  48. package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -1
  49. package/dist/_dts/api/src/navigation.d.ts +5 -5
  50. package/dist/_dts/api/src/pageSurfaceEditorEndpoints.d.ts +55 -0
  51. package/dist/_dts/api/src/pageSurfaceEndpoints.d.ts +28 -7
  52. package/dist/_dts/api/src/pages.d.ts +7 -7
  53. package/dist/_dts/api/src/performance.d.ts +1 -1
  54. package/dist/_dts/api/src/public/index.d.ts +1 -1
  55. package/dist/_dts/api/src/publicAppointmentBookingContracts.d.ts +2 -0
  56. package/dist/_dts/api/src/publicExperience/commerceEndpoints.d.ts +4 -0
  57. package/dist/_dts/api/src/redirects.d.ts +3 -3
  58. package/dist/_dts/api/src/request.d.ts +10 -1
  59. package/dist/_dts/api/src/resources.d.ts +4 -4
  60. package/dist/_dts/api/src/routes.d.ts +8 -3
  61. package/dist/_dts/api/src/sdk-event-upsert.d.ts +0 -1
  62. package/dist/_dts/api/src/sdkBlockUpsertContracts.d.ts +21 -0
  63. package/dist/_dts/api/src/sdkContracts.d.ts +5 -28
  64. package/dist/_dts/api/src/sdkEventEndpointDefinitions.d.ts +1 -1
  65. package/dist/_dts/api/src/sdkEventOccurrenceRequestContracts.d.ts +43 -0
  66. package/dist/_dts/api/src/sdkManagedEventContracts.d.ts +4 -2
  67. package/dist/_dts/api/src/sdkPullEventContracts.d.ts +8 -1
  68. package/dist/_dts/api/src/seo.d.ts +4 -4
  69. package/dist/_dts/api/src/services.d.ts +4 -4
  70. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +15 -8
  71. package/dist/_dts/api/src/siteMembers.d.ts +10 -10
  72. package/dist/_dts/api/src/siteOnboarding.d.ts +14 -0
  73. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +7 -3
  74. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +5 -12
  75. package/dist/_dts/api/src/siteRuntimeEntry.d.ts +31 -0
  76. package/dist/_dts/billing/src/checkout/platform.d.ts +77 -0
  77. package/dist/_dts/billing/src/components/index.d.ts +25 -40
  78. package/dist/_dts/billing/src/membership/index.d.ts +1 -3
  79. package/dist/_dts/billing/src/plans/entitlements.d.ts +80 -0
  80. package/dist/_dts/billing/src/plans/registry.d.ts +16 -16
  81. package/dist/_dts/billing/src/plans/standing.d.ts +9 -2
  82. package/dist/_dts/billing/src/plans/types.d.ts +5 -15
  83. package/dist/_dts/billing/src/site-arrangements.d.ts +2 -2
  84. package/dist/_dts/billing/src/subscriptions/standingEvidence.d.ts +2 -4
  85. package/dist/_dts/billing/src/subscriptions/store.d.ts +17 -11
  86. package/dist/_dts/block-form/src/backend/store-backend.d.ts +6 -7
  87. package/dist/_dts/block-form/src/backend/types.d.ts +7 -0
  88. package/dist/_dts/block-form/src/widgets/FieldFrame.d.ts +3 -1
  89. package/dist/_dts/blocks/src/client/events.d.ts +3 -0
  90. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +16 -4
  91. package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +4 -13
  92. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +2 -0
  93. package/dist/_dts/blocks/src/portal/types.d.ts +0 -2
  94. package/dist/_dts/blocks/src/system/blocks/contact-newsletter.d.ts +2 -1
  95. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +3 -1
  96. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +4 -4
  97. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +6 -1
  98. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +2 -2
  99. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
  100. package/dist/_dts/blocks/src/system/runtime/api/types/appointments.d.ts +2 -0
  101. package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +6 -0
  102. package/dist/_dts/blocks/src/system/runtime/api/types/portal.d.ts +6 -0
  103. package/dist/_dts/blocks/src/system/runtime/api/types/shop.d.ts +4 -0
  104. package/dist/_dts/blocks/src/system/runtime/components/booking/SuccessMessage.d.ts +4 -1
  105. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +24 -6
  106. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +12 -3
  107. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.d.ts +3 -0
  108. package/dist/_dts/blocks/src/system/runtime/hooks/usePaymentVerification.d.ts +2 -1
  109. package/dist/_dts/blocks/src/system/runtime/hooks/usePolling.d.ts +7 -48
  110. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.checkout-return-context.d.ts +7 -0
  111. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.completion.d.ts +3 -1
  112. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +4 -0
  113. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.interactive.d.ts +9 -0
  114. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.payment-confirmation.d.ts +13 -0
  115. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.state.d.ts +15 -1
  116. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.submit-actions.d.ts +8 -0
  117. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.submit-handler.d.ts +1 -0
  118. package/dist/_dts/blocks/src/system/runtime/nodes/booking-runtime-sources.d.ts +1 -0
  119. package/dist/_dts/blocks/src/system/runtime/nodes/checkout.server.d.ts +2 -1
  120. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +2 -1
  121. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationWizard.d.ts +5 -0
  122. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/SuccessStep.d.ts +4 -1
  123. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +2 -0
  124. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +2 -5
  125. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +9 -5
  126. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.interactive.d.ts +6 -0
  127. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/dates.d.ts +37 -3
  128. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventCard.client.d.ts +1 -1
  129. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventCard.d.ts +16 -1
  130. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCardPresentations.d.ts +13 -0
  131. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +5 -5
  132. package/dist/_dts/blocks/src/system/runtime/nodes/shared/MagicLinkForm.d.ts +1 -14
  133. package/dist/_dts/blocks/src/system/runtime/nodes/shared/MagicLinkForm.state.d.ts +12 -0
  134. package/dist/_dts/blocks/src/system/runtime/nodes/shop.interactive.d.ts +13 -0
  135. package/dist/_dts/blocks/src/system/runtime/shared/components/DemoBookingPortalAccess.d.ts +22 -0
  136. package/dist/_dts/blocks/src/system/runtime/shared/components/DemoPortalSignInLink.d.ts +4 -0
  137. package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +1 -0
  138. package/dist/_dts/blocks/src/system/runtime/shared/utils/demoBookingPassStorage.d.ts +10 -0
  139. package/dist/_dts/blocks/src/system/runtime/shared/utils/demoPortalMagicLink.d.ts +29 -0
  140. package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +4 -0
  141. package/dist/_dts/content-editor/src/components/ContentFieldsForm.d.ts +2 -7
  142. package/dist/_dts/content-editor/src/controller/EditLeaseController.d.ts +39 -0
  143. package/dist/_dts/content-editor/src/controller/EditorWriteGate.d.ts +38 -0
  144. package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +25 -61
  145. package/dist/_dts/content-editor/src/controller/LinkedEntryLeaseBanner.d.ts +7 -0
  146. package/dist/_dts/content-editor/src/controller/LinkedEntryLeaseControllers.d.ts +14 -0
  147. package/dist/_dts/content-editor/src/controller/deriveEditorUnpublishedState.d.ts +6 -0
  148. package/dist/_dts/content-editor/src/controller/documentValueBaseline.d.ts +25 -0
  149. package/dist/_dts/content-editor/src/controller/editLeaseLossSignal.d.ts +6 -0
  150. package/dist/_dts/content-editor/src/controller/editLeaseNotice.d.ts +28 -0
  151. package/dist/_dts/content-editor/src/controller/editorClientId.d.ts +2 -0
  152. package/dist/_dts/content-editor/src/controller/editorEditability.d.ts +38 -0
  153. package/dist/_dts/content-editor/src/controller/editorLeaseParticipation.d.ts +34 -0
  154. package/dist/_dts/content-editor/src/controller/normalizedMetadataBaseline.d.ts +29 -0
  155. package/dist/_dts/content-editor/src/controller/pageSurfaceDocumentBaselines.d.ts +14 -0
  156. package/dist/_dts/content-editor/src/controller/pageSurfaceLifecycle.d.ts +11 -0
  157. package/dist/_dts/content-editor/src/controller/planDocumentBaselineRefresh.d.ts +19 -0
  158. package/dist/_dts/content-editor/src/controller/readDocumentLeaseBaselines.d.ts +19 -0
  159. package/dist/_dts/content-editor/src/controller/refreshDocumentLeaseBaseline.d.ts +12 -0
  160. package/dist/_dts/content-editor/src/controller/refreshLinkedEntry.d.ts +17 -0
  161. package/dist/_dts/content-editor/src/controller/replayRestoredEditorEffects.d.ts +2 -3
  162. package/dist/_dts/content-editor/src/controller/routeWrites.d.ts +26 -0
  163. package/dist/_dts/content-editor/src/controller/useAutosaveTriggers.d.ts +16 -17
  164. package/dist/_dts/content-editor/src/controller/useBlockedPublishPlan.d.ts +6 -2
  165. package/dist/_dts/content-editor/src/controller/useBlocksList.d.ts +3 -3
  166. package/dist/_dts/content-editor/src/controller/useEntryValueAutosaves.d.ts +21 -0
  167. package/dist/_dts/content-editor/src/controller/useInitialEditorUiStore.d.ts +24 -0
  168. package/dist/_dts/content-editor/src/controller/useServerBaselineReconciliation.d.ts +17 -0
  169. package/dist/_dts/content-editor/src/footerComposerPanelTypes.d.ts +1 -1
  170. package/dist/_dts/content-editor/src/hooks/applyBlockedPublishPlan.d.ts +5 -1
  171. package/dist/_dts/content-editor/src/hooks/blockDraftLifecycle.d.ts +8 -47
  172. package/dist/_dts/content-editor/src/hooks/editLeaseMachine.d.ts +120 -0
  173. package/dist/_dts/content-editor/src/hooks/publishability.d.ts +6 -10
  174. package/dist/_dts/content-editor/src/hooks/useAutosaveStatus.d.ts +3 -0
  175. package/dist/_dts/content-editor/src/hooks/useBlockAutosave.d.ts +5 -15
  176. package/dist/_dts/content-editor/src/hooks/useDebouncedLatestSave.d.ts +7 -5
  177. package/dist/_dts/content-editor/src/hooks/useEditLease.d.ts +28 -0
  178. package/dist/_dts/content-editor/src/hooks/useEntryActions.d.ts +25 -39
  179. package/dist/_dts/content-editor/src/hooks/useEntryMutations.d.ts +17 -19
  180. package/dist/_dts/content-editor/src/hooks/useLinkedEntryAutosave.d.ts +5 -8
  181. package/dist/_dts/content-editor/src/hooks/useValueAutosave.d.ts +64 -0
  182. package/dist/_dts/content-editor/src/hooks/validateBlocksForPublish.d.ts +0 -7
  183. package/dist/_dts/content-editor/src/index.d.ts +26 -7
  184. package/dist/_dts/content-editor/src/linkedEntries/domain.d.ts +12 -0
  185. package/dist/_dts/content-editor/src/linkedEntries/owner.d.ts +9 -0
  186. package/dist/_dts/content-editor/src/liveDrafts/draftProjection.d.ts +66 -0
  187. package/dist/_dts/content-editor/src/liveDrafts/linkedSaveHandovers.d.ts +37 -0
  188. package/dist/_dts/content-editor/src/liveDrafts/remoteDraftOverlay.d.ts +113 -0
  189. package/dist/_dts/content-editor/src/liveDrafts/useLiveDrafts.d.ts +32 -0
  190. package/dist/_dts/content-editor/src/liveDrafts/useRetentionTicks.d.ts +7 -0
  191. package/dist/_dts/content-editor/src/primitives/shared/activePreviewField.d.ts +6 -0
  192. package/dist/_dts/content-editor/src/primitives/shared/storeBinding.d.ts +1 -0
  193. package/dist/_dts/content-editor/src/services/contentEntryServices.d.ts +96 -19
  194. package/dist/_dts/content-editor/src/services/editorApiClient.d.ts +13 -0
  195. package/dist/_dts/content-editor/src/services/index.d.ts +2 -0
  196. package/dist/_dts/content-editor/src/services/pageSurfaceEditorServices.d.ts +23 -0
  197. package/dist/_dts/content-editor/src/sync/flushValues.d.ts +13 -0
  198. package/dist/_dts/content-editor/src/sync/lifecycleFailure.d.ts +51 -0
  199. package/dist/_dts/content-editor/src/sync/runLifecycle.d.ts +64 -0
  200. package/dist/_dts/content-editor/src/sync/schedulerValues.d.ts +27 -0
  201. package/dist/_dts/content-editor/src/sync/sendPlanning.d.ts +104 -0
  202. package/dist/_dts/content-editor/src/sync/valueSync.d.ts +114 -0
  203. package/dist/_dts/content-editor/src/ui/blockCollection.d.ts +8 -0
  204. package/dist/_dts/content-editor/src/ui/documentLifecycle.d.ts +18 -0
  205. package/dist/_dts/content-editor/src/ui/editorLeaseUiState.d.ts +7 -0
  206. package/dist/_dts/content-editor/src/ui/editorRefresh.d.ts +82 -0
  207. package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +102 -127
  208. package/dist/_dts/content-editor/src/ui/editorTransactionState.d.ts +1 -1
  209. package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +126 -72
  210. package/dist/_dts/content-editor/src/ui/editorValueSnapshot.d.ts +18 -0
  211. package/dist/_dts/content-editor/src/ui/serverBlockAdmission.d.ts +26 -0
  212. package/dist/_dts/content-editor/src/ui/stores/autosaveStore.d.ts +16 -27
  213. package/dist/_dts/content-editor/src/ui/stores/blockVersionsStore.d.ts +24 -0
  214. package/dist/_dts/content-editor/src/ui/stores/linkedEntryLeaseStore.d.ts +54 -0
  215. package/dist/_dts/content-editor/src/ui/stores/linkedSaveHandoversStore.d.ts +11 -0
  216. package/dist/_dts/content-editor/src/ui/stores/remoteDraftsStore.d.ts +10 -0
  217. package/dist/_dts/content-editor/src/ui/stores/types.d.ts +63 -3
  218. package/dist/_dts/content-editor/src/useFooterComposerState.d.ts +2 -2
  219. package/dist/_dts/content-editor/src/useFooterNavigationLayout.d.ts +1 -1
  220. package/dist/_dts/content-model/src/content-types/builtin-schemas.d.ts +4 -4
  221. package/dist/_dts/content-model/src/content-types/builtins.d.ts +4 -4
  222. package/dist/_dts/content-model/src/definitions/shared.d.ts +11 -2
  223. package/dist/_dts/content-model/src/entry-slots/index.d.ts +1 -0
  224. package/dist/_dts/content-model/src/entry-slots/serializeAllowedBlocks.d.ts +2 -0
  225. package/dist/_dts/content-model/src/metadataConfig.d.ts +10 -38
  226. package/dist/_dts/content-model/src/templates/defaults.d.ts +0 -1
  227. package/dist/_dts/content-model/src/types.d.ts +0 -1
  228. package/dist/_dts/core/src/block-content-identity.d.ts +49 -1
  229. package/dist/_dts/core/src/branded.d.ts +12 -0
  230. package/dist/_dts/core/src/currency-format.d.ts +8 -2
  231. package/dist/_dts/core/src/demo-lifecycle-status.d.ts +2 -2
  232. package/dist/_dts/core/src/demo-warm-pool-target.d.ts +8 -0
  233. package/dist/_dts/core/src/edit-lease.d.ts +55 -0
  234. package/dist/_dts/core/src/editor-state.d.ts +38 -13
  235. package/dist/_dts/core/src/editor-value-sync.d.ts +79 -0
  236. package/dist/_dts/core/src/html-entities.d.ts +6 -0
  237. package/dist/_dts/core/src/index.d.ts +4 -0
  238. package/dist/_dts/core/src/uuid.d.ts +7 -5
  239. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +159 -153
  240. package/dist/_dts/editor/src/EditorProvider.d.ts +5 -0
  241. package/dist/_dts/editor/src/chrome/EditorChrome.d.ts +14 -0
  242. package/dist/_dts/editor/src/chrome/EditorStatusBar.d.ts +1 -0
  243. package/dist/_dts/editor/src/chrome/statusBarPresentation.d.ts +0 -1
  244. package/dist/_dts/editor/src/index.d.ts +1 -1
  245. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +10 -9
  246. package/dist/_dts/editor-blocks/src/BlockForm.d.ts +1 -1
  247. package/dist/_dts/editor-blocks/src/block-editor/BlockCard.d.ts +1 -1
  248. package/dist/_dts/editor-blocks/src/block-editor/BlockCardFrame.d.ts +1 -1
  249. package/dist/_dts/editor-blocks/src/block-editor/BlockSettingsModal.d.ts +1 -1
  250. package/dist/_dts/editor-blocks/src/block-editor/applyExtendedFieldDefaults.d.ts +3 -4
  251. package/dist/_dts/editor-blocks/src/block-editor/blockDraftBaselineSeed.d.ts +4 -8
  252. package/dist/_dts/editor-blocks/src/block-editor/editorBlockItem.d.ts +23 -0
  253. package/dist/_dts/editor-blocks/src/block-editor/generatedIconApplyCoordination.d.ts +2 -7
  254. package/dist/_dts/editor-blocks/src/block-editor/hooks/applyBlockStructureChange.d.ts +4 -0
  255. package/dist/_dts/editor-blocks/src/block-editor/hooks/buildInsertBlockHistoryCommand.d.ts +14 -5
  256. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockBaselineSync.d.ts +21 -19
  257. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockCreation.d.ts +2 -10
  258. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockDuplication.d.ts +8 -16
  259. package/dist/_dts/editor-blocks/src/block-editor/owner.d.ts +6 -16
  260. package/dist/_dts/editor-blocks/src/block-editor/types.d.ts +37 -9
  261. package/dist/_dts/editor-blocks/src/index.d.ts +2 -1
  262. package/dist/_dts/editor-blocks/src/widgets/entry-picker/loaders.d.ts +1 -1
  263. package/dist/_dts/editor-blocks/src/widgets/link/loaders.d.ts +1 -1
  264. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/loaders.d.ts +1 -1
  265. package/dist/_dts/editor-blocks/src/widgets/reference/loaders.d.ts +1 -1
  266. package/dist/_dts/editor-blocks/src/widgets/site-option-picker/loaders.d.ts +3 -2
  267. package/dist/_dts/media-core/src/fileStorage.d.ts +4 -0
  268. package/dist/_dts/media-editor/src/context.d.ts +1 -1
  269. package/dist/_dts/media-editor/src/createMediaEditorProvider.d.ts +1 -2
  270. package/dist/_dts/media-editor/src/provider.d.ts +3 -2
  271. package/dist/_dts/media-react/src/hooks/internal/classification.d.ts +1 -1
  272. package/dist/_dts/media-react/src/hooks/useApiMediaUploader.d.ts +3 -1
  273. package/dist/_dts/preview-next/src/client/blocks/composer/mergeDrafts.d.ts +8 -3
  274. package/dist/_dts/preview-next/src/client/blocks/composer/types.d.ts +6 -3
  275. package/dist/_dts/preview-next/src/client/blocks/linkedEntryRenderOverlay.d.ts +22 -2
  276. package/dist/_dts/preview-next/src/client/blocks/previewProjection/entryFieldRebinding.d.ts +13 -0
  277. package/dist/_dts/preview-next/src/client/blocks/previewProjection/index.d.ts +2 -1
  278. package/dist/_dts/preview-next/src/client/blocks/previewProjection/types.d.ts +11 -1
  279. package/dist/_dts/preview-next/src/client/blocks/renderPrecedence.d.ts +17 -0
  280. package/dist/_dts/preview-next/src/client/blocks/useLinkedSaveHandoverRetention.d.ts +20 -0
  281. package/dist/_dts/preview-next/src/client/index.d.ts +1 -1
  282. package/dist/_dts/preview-next/src/client/preview/EntryEditorPanel.d.ts +2 -1
  283. package/dist/_dts/preview-next/src/client/preview/EntrySlotBlockEditorPanel.d.ts +2 -1
  284. package/dist/_dts/preview-next/src/client/preview/PreviewAccessBanners.d.ts +7 -0
  285. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +2 -1
  286. package/dist/_dts/preview-next/src/client/preview/PreviewEntryControllerProvider.d.ts +24 -14
  287. package/dist/_dts/preview-next/src/client/preview/PreviewLeaseEditingMode.d.ts +2 -0
  288. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +9 -2
  289. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +1 -0
  290. package/dist/_dts/preview-next/src/client/preview/previewCustomizeAutosave.d.ts +5 -0
  291. package/dist/_dts/preview-next/src/client/preview/previewCustomizeWorkflowState.d.ts +3 -4
  292. package/dist/_dts/preview-next/src/client/preview/sdkConfig.d.ts +1 -0
  293. package/dist/_dts/preview-next/src/client/preview/usePreviewCustomizeWorkflowState.d.ts +4 -0
  294. package/dist/_dts/realtime/src/client.d.ts +3 -0
  295. package/dist/_dts/realtime/src/draftChannel.d.ts +91 -0
  296. package/dist/_dts/realtime/src/drafts.d.ts +210 -0
  297. package/dist/_dts/realtime/src/index.d.ts +3 -0
  298. package/dist/_dts/realtime/src/leaseChangeSubscriptions.d.ts +8 -0
  299. package/dist/_dts/realtime/src/types.d.ts +113 -0
  300. package/dist/_dts/realtime/src/useDraftChannel.d.ts +34 -0
  301. package/dist/_dts/realtime/src/useSiteRealtimeReload.d.ts +27 -0
  302. package/dist/_dts/sdk/src/public-api/contracts.d.ts +6 -55
  303. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +1 -0
  304. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +1 -0
  305. package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +2 -0
  306. package/dist/_dts/sdk/src/version.d.ts +1 -1
  307. package/dist/_dts/surfaces/src/index.d.ts +1 -0
  308. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +2 -2
  309. package/dist/client/{BookingMailingListNote-1n4Ch_u_.mjs → BookingMailingListNote-CzRt2dF_.mjs} +98 -96
  310. package/dist/client/DemoBookingPortalAccess-mxqwap3f.mjs +344 -0
  311. package/dist/client/{EventCombined.client-C0pgma9y.mjs → EventCombined.client-CDb11igO.mjs} +6 -6
  312. package/dist/client/{EventListing.client-4fhLOvHP.mjs → EventListing.client-EgYhzKPa.mjs} +2 -2
  313. package/dist/client/{LeafletStaticMap-DScC4F3w.mjs → LeafletStaticMap-gtmtaA2b.mjs} +1 -1
  314. package/dist/client/{TerminalPanel-B5ZUsYhe.mjs → TerminalPanel-DvNUP5ot.mjs} +1 -1
  315. package/dist/client/{ThemedButton-DoVIV1Ao.mjs → ThemedButton-C7CeUJjW.mjs} +1 -1
  316. package/dist/client/{accordion-CoT5g7zo.mjs → accordion-kjvt49rA.mjs} +1 -1
  317. package/dist/client/{bookingForm-BWxB46xD.mjs → bookingForm-pbRZordh.mjs} +212 -62
  318. package/dist/client/bookings.mjs +616 -225
  319. package/dist/client/{carousel-DtNYWFd3.mjs → carousel-f4Zbmicv.mjs} +1 -1
  320. package/dist/client/{cart-z4qZih1Y.mjs → cart-DO20An50.mjs} +3 -3
  321. package/dist/client/{checkout-DpL7euFH.mjs → checkout-Du5amDR_.mjs} +3 -3
  322. package/dist/client/{checkoutUrls-BEfR7kVu.mjs → checkoutUrls-CXhko2Rv.mjs} +1 -1
  323. package/dist/client/client.mjs +1753 -823
  324. package/dist/client/{context-C8TinPJc.mjs → context-eW97E945.mjs} +4 -3
  325. package/dist/client/{dates-vwwxTeB0.mjs → dates-jPCirRea.mjs} +56 -11
  326. package/dist/client/{eventCalendar-DIbHfJXO.mjs → eventCalendar-C2M-iE4j.mjs} +9 -9
  327. package/dist/client/{eventCombined-DoGMJ6cg.mjs → eventCombined-W6ns3LHg.mjs} +4 -4
  328. package/dist/client/{eventDetails-BjN9v6a1.mjs → eventDetails-CR-GT0f0.mjs} +4 -4
  329. package/dist/client/{eventListing-DajjWgOv.mjs → eventListing-BK8AfYZz.mjs} +4 -4
  330. package/dist/client/{eventRegistration-DMq9gMA-.mjs → eventRegistration-BJSd4KUu.mjs} +369 -242
  331. package/dist/client/{form-Qf6qTbos.mjs → form-BvpfbQaT.mjs} +3 -3
  332. package/dist/client/{headerSection-D7qJrqFX.mjs → headerSection-I5sUQ8x-.mjs} +3 -3
  333. package/dist/client/hooks.mjs +254 -53
  334. package/dist/client/{locationMap-CCF9-t_0.mjs → locationMap-BLvwf9_f.mjs} +3 -3
  335. package/dist/client/{media-CwBGetqC.mjs → media-Cl38iOMI.mjs} +10 -3
  336. package/dist/client/{newsletterForm-DzCLSP4S.mjs → newsletterForm-DrQ2weE8.mjs} +3 -3
  337. package/dist/client/{pricing-Cgxv2KLC.mjs → pricing-BES87mrR.mjs} +1 -1
  338. package/dist/client/{productDetail-ru9w5GHx.mjs → productDetail-Url9jcc5.mjs} +3 -3
  339. package/dist/client/{productList-zaapKSl-.mjs → productList-DE7ngEZJ.mjs} +3 -3
  340. package/dist/client/{propsDecoder-CwvvNOHx.mjs → propsDecoder-D1OtGXDV.mjs} +89 -17
  341. package/dist/client/rendering/client.mjs +1445 -658
  342. package/dist/client/rendering/islands.mjs +18 -18
  343. package/dist/client/rendering.mjs +2478 -1515
  344. package/dist/client/{routeIslandApiConfig-BwVFo0Y4.mjs → routeIslandApiConfig-BG9Y-SHg.mjs} +1 -1
  345. package/dist/client/{shop-mktkXvbV.mjs → shop-CJkuySJ3.mjs} +126 -79
  346. package/dist/client/{shop-commerce-De7gEnkA.mjs → shop-commerce-4rKj5n9h.mjs} +25 -13
  347. package/dist/client/{shop-commerce-store-B3MCxIBW.mjs → shop-commerce-store-Bxm75Pg6.mjs} +1 -1
  348. package/dist/client/{shopShared-TqExh235.mjs → shopShared-DpoQDWfz.mjs} +4 -4
  349. package/dist/client/{useEventFilters-n_OjkIjX.mjs → useEventFilters-D8HliSqR.mjs} +32 -17
  350. package/dist/preview-next/before-render.mjs +192 -83
  351. package/dist/preview-next/client/runtime.mjs +4 -4
  352. package/dist/preview-next/keepAlive.mjs +192 -83
  353. package/dist/preview-next/middleware.mjs +192 -83
  354. package/dist/{previewAuthStore-C_EHQ5XA.mjs → previewAuthStore-BXXF3hhW.mjs} +194 -83
  355. package/dist/{sdk-runtime-BIkJg5y1.mjs → sdk-runtime-C2a05WjL.mjs} +2 -2
  356. package/dist/{separator-C9qDP95Z.mjs → separator-CuNhBAhS.mjs} +1 -1
  357. package/dist/server/components.mjs +1720 -1392
  358. package/dist/server/config-validation.mjs +221 -37
  359. package/dist/server/config.mjs +221 -37
  360. package/dist/server/data.mjs +221 -37
  361. package/dist/server/index.mjs +195 -84
  362. package/dist/server/next.mjs +490 -196
  363. package/dist/server/page-converter.mjs +53 -14
  364. package/dist/server/prebuild.mjs +1 -1
  365. package/dist/server/rendering/server.mjs +1427 -1098
  366. package/dist/server/rendering.mjs +2693 -2365
  367. package/dist/server/routing.mjs +291 -55
  368. package/dist/server/server.mjs +281 -114
  369. package/package.json +1 -1
  370. package/dist/_dts/billing/src/plans/display.d.ts +0 -15
  371. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.mailing-list-note.d.ts +0 -3
  372. package/dist/_dts/content-editor/src/controller/buildBlockPublishedBaselines.d.ts +0 -4
  373. package/dist/_dts/content-editor/src/controller/buildPublishSuccessTransition.d.ts +0 -16
  374. package/dist/_dts/content-editor/src/controller/driver.d.ts +0 -14
  375. package/dist/_dts/content-editor/src/controller/seedDraftBaselinesFromBlocks.d.ts +0 -7
  376. package/dist/_dts/content-editor/src/controller/useEntrySyncHelpers.d.ts +0 -29
  377. package/dist/_dts/content-editor/src/hooks/autosaveScopePlanning.d.ts +0 -26
  378. package/dist/_dts/content-editor/src/hooks/useSimpleAutosave.d.ts +0 -64
  379. package/dist/_dts/content-editor/src/hooks/useStoreAutosave.d.ts +0 -48
  380. package/dist/_dts/content-editor/src/types.d.ts +0 -44
  381. package/dist/client/DiscountCodeDisclosure-CKJtz0mY.mjs +0 -137
@@ -1,12 +1,40 @@
1
1
  "use client";
2
- import { $i as resolveSdkFooterMode, $n as resolveRouteTarget, $r as parseBackgroundAppearanceColorToken, $t as recordsEqual, Aa as Dialog, Ai as isRecord$11, An as ThemeScope, Ao as __exportAll, At as useRichTextImagePicker, Bn as resolveVariantKey, Bt as stripTopLevelRoutingUi, Ci as siblingPath, Cn as DEFAULT_LAUNCH_READINESS_INPUT, Co as parseMailingListPlacementTargeting, Cr as compileEditorModelRuntime, Ct as EntryPickerWidgetProvider, Da as TabsContent, Di as eventCalendarListLayoutOptions, Dn as useMediaEditorOptional, Do as expectParsedBrandedId, Dr as componentRuntimeRulesForTheme, Dt as MediaField, Ea as Tabs, Ei as eventCalendarListLayoutCompatibleDisplayModeValues, En as MediaEditorContextProvider, Eo as assertNever$2, Er as resolvePageDesignEditorBoundaryForChoice, Et as FileField, Fa as DialogTitle, Fi as asDesignBlockId, Fn as projectRecurringSchedule, Fr as gradientToCss, Ft as LinkField, G as confirmAutosaveBatch, Gi as textColorStyle, Gn as getResponsiveScopeSpec, Gr as sectionFactsForContent, Gt as useOptionalEditorUiStoreInstance, Hn as validateManifestDraft, Hr as userPinnedDesignChoice, Ii as assertNever$1, In as SITE_CHROME_VISIBLE_HEADER_SELECTOR, Ir as GRADIENT_PRESETS, It as LinkWidgetProvider, J as idleEditorTransactionQueueState, Ji as ORDINARY_TEXT_MIN_CONTRAST_RATIO, Jn as readBlockComposition, Jr as sectionTransitionFamilies, Jt as createHistoryState, K as deriveTransactionCapabilities, Ki as defaultThemeTokens, Kn as escapeStyleContent, Kr as boundaryTreatmentForBoundaryOptionId, Kt as canRedoHistory, Li as makeBoundaryId, Ln as SITE_OVERLAY_HEADER_CLEARANCE_CSS_VAR, Lr as GRADIENT_PRESET_IDS, Ma as DialogDescription, Mi as isThemeV2NormalEditorRawStyleFieldName, Mn as createCustomBlockRegistry, Mt as RichTextWidgetProvider, Na as DialogFooter, Ni as pageDesignEditorBackgroundOverrideOwner, Nn as makeDefaultBlockComponent, Nt as EditorProvider, Oa as TabsList, Oi as bookingConsentCarrierSchema, On as useApiMediaUploader, Oo as parseMediaAssetId, Ot as ReferenceField, Pa as DialogHeader, Pi as stripStaleTransitionStyleGroup, Pn as getBlockDefinition, Pt as useEditor, Q as resolvePreviewSidebarTab, Qi as paletteModeSchema, Qn as resolvePageRouteTarget, Qr as backgroundAppearanceQuickColorTokenNames, Qt as unsafeAsLinkedContentEntryId, Rn as planSiteOverlayHeaderClearance, Rr as getGradientPreset, Rt as hideThemeV2RawStyleFields, Si as getAtPath, Sn as decodePublicProductCategorySelectorQuery, So as parseFooterModuleId, Sr as applyCompiledRuntimeFieldsToContent, St as EntryPickerField, Ti as calendarWindowQuerySchema, Tn as AMBIENT_BACKGROUND_ROLES, To as unsafeAsEditorBlockValues, Tr as planPageDesignLayoutLookCompatibility, Tt as ButtonWidgetProvider, Un as buildThemeRuntime, Ur as boundaryLayout, Ut as useEditorUiStore, Vn as compileManifestContentContract, Vr as autoDesignChoice, Vt as getBlockManifestFromSdkConfig, W as beginAutosaveBatch, Wn as DEFAULT_THEME_RESPONSIVE_MODE, Wr as composeBoundary, Wt as useEditorUiStoreInstance, Xa as X, Xn as defaultTransforms, Xr as sectionTransitionVariantForBoundaryOptionId, Xt as redoHistory, Y as rejectAutosaveBatch, Ya as cn, Yn as getDefaultComponentRegistry, Yr as sectionTransitionFamilyForBoundaryOptionId, Yt as pushHistoryEntry, Za as Upload, Zi as paletteColorsSchema, Zn as resolveEntryRouteTarget, Zr as backgroundAppearanceColorTokenNames, Zt as undoHistory, _ as reportPreviewDesignError, _a as SelectTrigger, _i as buildResolveImageUrlContext, _n as createStoreBackend, _o as ChevronLeft, _r as heroCtaRowFragment, _t as MailingListTargetingField, aa as hasEmptyOption, ai as runTransforms, ar as richTextFragment, bi as setContextResolveImageUrlContext, bn as getPageDesignEditorState, bo as buildMailingListSignupBlockSourceRef, br as bodyCopyFragment, bt as InlineTextField, ca as unmapValueFromSelect, ci as parseGeneratedIconSetId, cr as faqAccordionFragment, ct as EntryControllerProvider, d as PreviewDesignCoordinatorProvider, di as logger, dn as usePalette, dr as singleButtonFragment, dt as createSiteOptionApiLoader, ea as attachRenderableMediaAssetFields, ei as ctaButton, er as LINKED_CONTENT_ENTRY_META_KEY, et as renderSiteChromeBlock, fi as coerceInlineTextWithFallback, fo as Image, fr as formEmbedFragment, ft as createSiteOptionWidgetAdapters, g as PREVIEW_DESIGN_SAVE_ERROR_MESSAGE, ga as SelectItem, gi as RichText$1, gn as evaluateVisibility, go as ChevronRight, gr as ctaCopyFragment, gt as OfferingsPreviewWidgetProvider, h as PREVIEW_DESIGN_LOAD_ERROR_MESSAGE, ha as SelectContent, hi as Text$1, hn as FormRenderer, hr as testimonialsHeadingFragment, ht as OfferingsPreviewGroupOrderField, i as usePreviewDesignHistoryOrder, ia as useSdkConfig, ii as parseBackgroundContent, in as BUILT_IN_REFERENCE_KINDS, io as RotateCcw, ir as ImageResolveContextProvider, it as PREVIEW_EDITABLE_OUTLINE, ja as DialogContent, ji as corners, jn as containerResponsiveThemeCss, jr as surfaceResolutionContextFromTheme, jt as RichTextField, ka as TabsTrigger, ki as isObjectRecord, kn as isSupportedLoaderEndpoint, ko as parseSiteId, kr as designRuntimeRulesForTheme, kt as ReferenceWidgetProvider, la as FieldFrame, lr as faqHeadingFragment, m as usePreviewThemeOverlay, ma as Select, mi as isInlineTextEmpty, mr as testimonialsCarouselFragment, mt as SiteOptionWidgetProvider, n as useSiteChromeCustomizeOptional, na as isHeaderField, nn as createRoutingHelpers, nr as getLinkedContentEntryMeta, nt as PreviewInlineTextEditor, oa as mapCurrentValueForSelect, oi as parseBlockIconValue, on as parseReferenceKind, or as headingFragment, ot as useUISelector, p as PreviewThemeOverlayProvider, pi as inlineTextToPlainText, pn as createManifestFormAdapter, po as GripVertical, pr as formCopyFragment, pt as SiteOptionPickerField, q as enqueueTransaction, qa as Button, qi as parseThemeForPersistence, qn as mergeContentWithBlockStyleOverrides, qr as defaultSectionTransitionVariantForFamily, qt as canUndoHistory, r as PreviewDesignHistoryOrderProvider, ra as SdkConfigProvider, ri as planSiteChromePlacement, rn as createSnapshotFromPageRecord, rr as clientComponentRegistry, rt as PreviewTextEditor, sa as mapOptionValueForSelect, si as parseGeneratedIconAssetId, sr as cardFragment, st as EditableBlockProvider, t as SiteChromeCustomizeProvider, ta as getFieldIntent, ti as bindingSchema, tn as useDebouncedLatestSave, tr as coerceLinkedContentEntriesPayload, tt as PreviewRichTextEditor, ua as useField, ui as renderInlineText, un as PaletteProvider, ur as blogFeaturedPostFragment, ut as useEntryEditorController, va as SelectValue, vi as getCurrentResolveImageUrlContext, vn as MediaEditor, vr as ctaRowFragment, vt as loadMailingListAuthoringContext, wi as BlockApiProvider, wn as deriveLaunchReadiness, wo as unsafeAsEditorBlockId, wr as formatSiteChromeBackgroundTokenLabel, wt as ButtonVariantField, xi as SECTION_BACKGROUND_MIN_SOURCE_WIDTH, xo as sameMailingListPlacementTargeting, xr as defineFragment, xt as IconPickerField, yi as resolveImageUrlWithContext, yn as applyPageDesignEditorAction, yr as heroCopyFragment, yt as MailingListTargetingProvider, zn as visibleHeaderClearancePx, zr as parseGradientPresetId, zt as prepareBlockEditorManifest } from "./SiteChromeCustomizeContext-DQXZXiqS.mjs";
3
- import { i as useOptionalPreviewLayout, t as PreviewQueryProvider } from "./PreviewQueryProvider-Dd4dxOiU.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-C_EHQ5XA.mjs";
2
+ import { $a as DialogFooter, $n as canUndoHistory, $r as SECTION_BACKGROUND_MIN_SOURCE_WIDTH, $t as createStoreBackend, Aa as attachRenderableMediaAssetFields, Ao as GripVertical, Ar as parseGeneratedIconSetId, At as MailingListTargetingProvider, Bi as gradientToCss, Bo as baselineRevisionOf, Br as bookingConsentCarrierSchema, Bt as ReferenceWidgetProvider, Ca as makeBoundaryId, Ci as parseBackgroundContent, Cn as stripTopLevelRoutingUi, Cr as escapeStyleContent, Ct as createSiteOptionWidgetAdapters, Da as bodyCopyFragment, Di as planPageDesignLayoutLookCompatibility, Dn as createManifestFormAdapter, Dt as OfferingsPreviewWidgetProvider, Ea as ctaButton, Ei as formatSiteChromeBackgroundTokenLabel, En as isHeaderField, Er as getDefaultComponentRegistry, Et as OfferingsPreviewGroupOrderField, Fa as SelectContent, Fi as parseThemeForPersistence, Fr as RichText$1, Ft as ButtonVariantField, G as confirmAutosaveBatch, Go as buildMailingListSignupBlockSourceRef, Gr as resolvePageRouteTarget, Gt as useEditor, Hi as GRADIENT_PRESET_IDS, Hn as useEditorUiStore, Ho as recordsEqual, Hr as eventCalendarListLayoutCompatibleDisplayModeValues, Ht as RichTextField, Ia as SelectItem, Ii as resolveSdkFooterMode, In as BUILT_IN_REFERENCE_KINDS, Ir as getAtPath, It as ButtonWidgetProvider, J as idleEditorTransactionQueueState, Ja as TabsList, Jn as remoteDraftValues, Jo as parseMailingListPlacementTargeting, Jr as isRecord$11, K as deriveTransactionCapabilities, Ka as Tabs, Kn as activeLinkedSaveHandover, Ko as sameMailingListPlacementTargeting, Kr as resolveRouteTarget, Kt as LinkField, La as SelectTrigger, Lo as Button, Lr as siblingPath, Lt as FileField, Mn as getBlockManifestFromSdkConfig, Mr as renderInlineText, Mt as IconPickerField, Ni as surfaceResolutionContextFromTheme, Nn as createRoutingHelpers, No as ChevronRight, Nr as logger, Nt as EntryPickerField, Oa as defineFragment, Oi as resolvePageDesignEditorBoundaryForChoice, Or as parseBlockIconValue, Ot as MailingListTargetingField, Pa as Select, Pi as corners, Pn as createSnapshotFromPageRecord, Po as ChevronLeft, Pr as Text$1, Pt as EntryPickerWidgetProvider, Q as resolvePreviewSidebarTab, Qa as DialogDescription, Qn as canRedoHistory, Qr as setContextResolveImageUrlContext, Qt as FormRenderer, Ra as SelectValue, Rn as parseReferenceKind, Rr as defaultTransforms, Rt as MediaField, Sa as assertNever$1, Si as heroCopyFragment, Sn as prepareBlockEditorManifest, Sr as getResponsiveScopeSpec, St as createSiteOptionApiLoader, Ta as runTransforms, Ti as compileEditorModelRuntime, Tn as getFieldIntent, Tr as readBlockComposition, Tt as SiteOptionWidgetProvider, Ui as getGradientPreset, Un as useEditorUiStoreInstance, Ur as eventCalendarListLayoutOptions, Ut as RichTextWidgetProvider, Vi as GRADIENT_PRESETS, Vo as isEdited, Vr as isRichTextDoc, Vt as useRichTextImagePicker, W as beginAutosaveBatch, Wi as parseGradientPresetId, Wn as useOptionalEditorUiStoreInstance, Wo as canEditorWrite, Wr as resolveEntryRouteTarget, Wt as EditorProvider, Xa as Dialog, Xn as renderedFieldChanges, Xo as selectedContentVersionId, Xr as getCurrentResolveImageUrlContext, Xt as usePalette, Y as rejectAutosaveBatch, Ya as TabsTrigger, Yn as renderSourceFor, Yo as NO_BLOCK_VERSIONS, Yr as buildResolveImageUrlContext, Yt as PaletteProvider, Za as DialogContent, Zn as resolveRenderedValues, Zr as resolveImageUrlWithContext, _ as reportPreviewDesignError, _i as testimonialsCarouselFragment, _n as mapOptionValueForSelect, _r as resolveVariantKey, _t as VIEWING_PARTICIPATION, aa as boundaryTreatmentForBoundaryOptionId, ai as LINKED_CONTENT_ENTRY_META_KEY, an as deriveLaunchReadiness, ar as unsafeAsLinkedContentEntryId, as as parsePageId, ba as defaultThemeTokens, bi as heroCtaRowFragment, bn as useField, br as buildThemeRuntime, bt as EditLeaseModal, ca as sectionTransitionFamilyForBoundaryOptionId, ci as richTextFragment, cn as useMediaEditorOptional, cr as containerResponsiveThemeCss, cs as __exportAll, ct as EntryControllerProvider, d as PreviewDesignCoordinatorProvider, da as pageDesignEditorBackgroundOverrideOwner, di as faqAccordionFragment, dn as ImageResolveContextProvider, dr as getBlockDefinition, ea as autoDesignChoice, ei as planSiteChromePlacement, en as MediaEditor, eo as DialogHeader, er as createHistoryState, es as unsafeAsEditorBlockId, et as renderSiteChromeBlock, fa as stripStaleTransitionStyleGroup, fi as faqHeadingFragment, fn as BlockApiProvider, fr as projectRecurringSchedule, g as PREVIEW_DESIGN_SAVE_ERROR_MESSAGE, ga as textColorStyle, gi as formCopyFragment, gn as mapCurrentValueForSelect, gr as visibleHeaderClearancePx, gt as useRetentionTicks, h as PREVIEW_DESIGN_LOAD_ERROR_MESSAGE, ha as parseBackgroundAppearanceColorToken, hi as formEmbedFragment, hn as hasEmptyOption, hr as planSiteOverlayHeaderClearance, ht as createPageSurfaceEditorServices, i as usePreviewDesignHistoryOrder, ia as sectionFactsForContent, ii as plainTextToInlineText, in as DEFAULT_LAUNCH_READINESS_INPUT, ir as toEditorBlockItem, is as parseMediaAssetId, it as PREVIEW_EDITABLE_OUTLINE, ji as designRuntimeRulesForTheme, jn as blocksKeys, jt as InlineTextField, ka as bindingSchema, ki as componentRuntimeRulesForTheme, ko as Image, kr as parseGeneratedIconAssetId, kt as loadMailingListAuthoringContext, la as sectionTransitionVariantForBoundaryOptionId, li as headingFragment, ln as useApiMediaUploader, lr as createCustomBlockRegistry, m as usePreviewThemeOverlay, ma as backgroundAppearanceQuickColorTokenNames, mi as singleButtonFragment, mn as useSdkConfig, mo as Upload, mr as SITE_OVERLAY_HEADER_CLEARANCE_CSS_VAR, mt as createEditorApiClientFactory, n as useSiteChromeCustomizeOptional, na as boundaryLayout, ni as inlineTextToPlainText, nn as getPageDesignEditorState, nr as redoHistory, ns as expectParsedBrandedId, nt as PreviewInlineTextEditor, oa as defaultSectionTransitionVariantForFamily, oi as coerceLinkedContentEntriesPayload, on as AMBIENT_BACKGROUND_ROLES, or as isSupportedLoaderEndpoint, os as parsePageSurfaceId, ot as useUISelector, p as PreviewThemeOverlayProvider, pa as backgroundAppearanceColorTokenNames, pi as blogFeaturedPostFragment, pn as SdkConfigProvider, po as X, pr as SITE_CHROME_VISIBLE_HEADER_SELECTOR, pt as useDebouncedLatestSave, q as enqueueTransaction, qa as TabsContent, qn as planLinkedSaveHandoverRetention, qo as parseFooterModuleId, qr as isObjectRecord, qt as LinkWidgetProvider, r as PreviewDesignHistoryOrderProvider, ra as composeBoundary, ri as isInlineTextEmpty, rn as decodePublicProductCategorySelectorQuery, rr as undoHistory, rs as parseContentEntryId, rt as PreviewTextEditor, sa as sectionTransitionFamilies, si as getLinkedContentEntryMeta, sn as MediaEditorContextProvider, sr as ThemeScope, ss as parseSiteId, st as EditableBlockProvider, t as SiteChromeCustomizeProvider, ta as userPinnedDesignChoice, ti as coerceInlineTextWithFallback, tn as applyPageDesignEditorAction, to as DialogTitle, tr as pushHistoryEntry, ts as assertNever$2, tt as PreviewRichTextEditor, ua as isThemeV2NormalEditorRawStyleFieldName, ui as cardFragment, un as clientComponentRegistry, ur as makeDefaultBlockComponent, ut as useEntryEditorController, va as paletteColorsSchema, vi as testimonialsHeadingFragment, vn as unmapValueFromSelect, vr as compileManifestContentContract, wa as ORDINARY_TEXT_MIN_CONTRAST_RATIO, wi as applyCompiledRuntimeFieldsToContent, wn as evaluateVisibility, wr as mergeContentWithBlockStyleOverrides, wt as SiteOptionPickerField, xa as asDesignBlockId, xi as ctaRowFragment, xn as hideThemeV2RawStyleFields, xo as RotateCcw, xr as DEFAULT_THEME_RESPONSIVE_MODE, xt as EditorWriteSurface, ya as paletteModeSchema, yi as ctaCopyFragment, yn as FieldFrame, yr as validateManifestDraft, yt as EditLeaseDiscardedNotice, zo as cn, zr as calendarWindowQuerySchema, zt as ReferenceField } from "./SiteChromeCustomizeContext-CFJYh6vo.mjs";
3
+ import { i as useOptionalPreviewLayout, t as PreviewQueryProvider } from "./PreviewQueryProvider-5znTyJuz.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-BXXF3hhW.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";
8
+ import { useQueryClient } from "@tanstack/react-query";
8
9
  import { z } from "zod";
9
10
  import { createPortal } from "react-dom";
11
+ //#region ../core/src/edit-lease.ts
12
+ function parseEditLeaseScope(input) {
13
+ switch (input.nodeType) {
14
+ case "page": {
15
+ const id = parsePageId(input.nodeId);
16
+ return id.ok ? {
17
+ nodeType: "page",
18
+ nodeId: id.value
19
+ } : null;
20
+ }
21
+ case "content_entry": {
22
+ const id = parseContentEntryId(input.nodeId);
23
+ return id.ok ? {
24
+ nodeType: "content_entry",
25
+ nodeId: id.value
26
+ } : null;
27
+ }
28
+ case "page_surface": {
29
+ const id = parsePageSurfaceId(input.nodeId);
30
+ return id.ok ? {
31
+ nodeType: "page_surface",
32
+ nodeId: id.value
33
+ } : null;
34
+ }
35
+ }
36
+ }
37
+ //#endregion
10
38
  //#region ../ui/src/fixed-bottom-surface.tsx
11
39
  const SURFACE_CLASS_BY_VARIANT = {
12
40
  light: "z-40 border-t border-border bg-editor-chrome-surface text-foreground",
@@ -174,70 +202,6 @@ function ResizableSplitPane({ left, right, defaultSplit = 40, minLeftWidth = 300
174
202
  });
175
203
  }
176
204
  //#endregion
177
- //#region ../blocks/src/system/icons/generatedAssets.ts
178
- function isRecord$10(value) {
179
- return typeof value === "object" && value !== null && !Array.isArray(value);
180
- }
181
- function generatedIconAssetRefKey(ref) {
182
- return `${ref.setId}\u0000${ref.assetId}`;
183
- }
184
- function collectGeneratedIconAssetRefs(page) {
185
- const blocks = [];
186
- for (const block of page.blocks) {
187
- if (block.kind !== "block.feature-cards" || typeof block.id !== "string") continue;
188
- const content = isRecord$10(block.draftContent) ? block.draftContent : isRecord$10(block.content) ? block.content : null;
189
- const cards = Array.isArray(content?.cards) ? content.cards : [];
190
- const refs = /* @__PURE__ */ new Map();
191
- for (const card of cards) {
192
- if (!isRecord$10(card)) continue;
193
- const icon = parseBlockIconValue(card.icon);
194
- if (icon.kind !== "generated") continue;
195
- const ref = {
196
- setId: icon.setId,
197
- assetId: icon.assetId
198
- };
199
- refs.set(generatedIconAssetRefKey(ref), ref);
200
- }
201
- if (refs.size > 0) blocks.push({
202
- blockId: block.id,
203
- refs: [...refs.values()]
204
- });
205
- }
206
- return blocks;
207
- }
208
- function dedupeGeneratedIconAssetRefs(blocks) {
209
- return [...new Map(blocks.flatMap((block) => block.refs).map((ref) => [generatedIconAssetRefKey(ref), ref])).values()];
210
- }
211
- function mapGeneratedIconAssetsToBlocks(blocks, resolvedAssets) {
212
- const byKey = new Map(resolvedAssets.map((asset) => [generatedIconAssetRefKey(asset), asset]));
213
- return Object.fromEntries(blocks.flatMap((block) => {
214
- const assets = block.refs.flatMap((ref) => {
215
- const asset = byKey.get(generatedIconAssetRefKey(ref));
216
- if (!asset) return [];
217
- const setId = parseGeneratedIconSetId(asset.setId);
218
- const assetId = parseGeneratedIconAssetId(asset.assetId);
219
- if (!setId || !assetId) return [];
220
- return [{
221
- setId,
222
- assetId,
223
- src: asset.src,
224
- ...asset.width === void 0 ? {} : { width: asset.width },
225
- ...asset.height === void 0 ? {} : { height: asset.height }
226
- }];
227
- });
228
- return assets.length > 0 ? [[block.blockId, assets]] : [];
229
- }));
230
- }
231
- function mergeGeneratedIconAssetsIntoResolvedData(resolvedData, assetsByBlock) {
232
- if (Object.keys(assetsByBlock).length === 0) return resolvedData;
233
- const merged = { ...resolvedData };
234
- for (const [blockId, generatedIconAssets] of Object.entries(assetsByBlock)) merged[blockId] = {
235
- ...merged[blockId] ?? {},
236
- generatedIconAssets
237
- };
238
- return merged;
239
- }
240
- //#endregion
241
205
  //#region ../blocks/src/system/fragments/library/headerCta.ts
242
206
  const headerCtaFragment = defineFragment({
243
207
  id: "headerCta",
@@ -345,6 +309,70 @@ function getFragmentRegistry() {
345
309
  return fragmentRegistry;
346
310
  }
347
311
  //#endregion
312
+ //#region ../blocks/src/system/icons/generatedAssets.ts
313
+ function isRecord$10(value) {
314
+ return typeof value === "object" && value !== null && !Array.isArray(value);
315
+ }
316
+ function generatedIconAssetRefKey(ref) {
317
+ return `${ref.setId}\u0000${ref.assetId}`;
318
+ }
319
+ function collectGeneratedIconAssetRefs(page) {
320
+ const blocks = [];
321
+ for (const block of page.blocks) {
322
+ if (block.kind !== "block.feature-cards" || typeof block.id !== "string") continue;
323
+ const content = isRecord$10(block.draftContent) ? block.draftContent : isRecord$10(block.content) ? block.content : null;
324
+ const cards = Array.isArray(content?.cards) ? content.cards : [];
325
+ const refs = /* @__PURE__ */ new Map();
326
+ for (const card of cards) {
327
+ if (!isRecord$10(card)) continue;
328
+ const icon = parseBlockIconValue(card.icon);
329
+ if (icon.kind !== "generated") continue;
330
+ const ref = {
331
+ setId: icon.setId,
332
+ assetId: icon.assetId
333
+ };
334
+ refs.set(generatedIconAssetRefKey(ref), ref);
335
+ }
336
+ if (refs.size > 0) blocks.push({
337
+ blockId: block.id,
338
+ refs: [...refs.values()]
339
+ });
340
+ }
341
+ return blocks;
342
+ }
343
+ function dedupeGeneratedIconAssetRefs(blocks) {
344
+ return [...new Map(blocks.flatMap((block) => block.refs).map((ref) => [generatedIconAssetRefKey(ref), ref])).values()];
345
+ }
346
+ function mapGeneratedIconAssetsToBlocks(blocks, resolvedAssets) {
347
+ const byKey = new Map(resolvedAssets.map((asset) => [generatedIconAssetRefKey(asset), asset]));
348
+ return Object.fromEntries(blocks.flatMap((block) => {
349
+ const assets = block.refs.flatMap((ref) => {
350
+ const asset = byKey.get(generatedIconAssetRefKey(ref));
351
+ if (!asset) return [];
352
+ const setId = parseGeneratedIconSetId(asset.setId);
353
+ const assetId = parseGeneratedIconAssetId(asset.assetId);
354
+ if (!setId || !assetId) return [];
355
+ return [{
356
+ setId,
357
+ assetId,
358
+ src: asset.src,
359
+ ...asset.width === void 0 ? {} : { width: asset.width },
360
+ ...asset.height === void 0 ? {} : { height: asset.height }
361
+ }];
362
+ });
363
+ return assets.length > 0 ? [[block.blockId, assets]] : [];
364
+ }));
365
+ }
366
+ function mergeGeneratedIconAssetsIntoResolvedData(resolvedData, assetsByBlock) {
367
+ if (Object.keys(assetsByBlock).length === 0) return resolvedData;
368
+ const merged = { ...resolvedData };
369
+ for (const [blockId, generatedIconAssets] of Object.entries(assetsByBlock)) merged[blockId] = {
370
+ ...merged[blockId] ?? {},
371
+ generatedIconAssets
372
+ };
373
+ return merged;
374
+ }
375
+ //#endregion
348
376
  //#region ../blocks/src/pageRenderingMode.ts
349
377
  var MissingBlockOverrideError = class extends Error {
350
378
  constructor(blockKind) {
@@ -564,6 +592,7 @@ function buildPageRendererRootRuntime(dataContext) {
564
592
  const { siteId = null, siteName, pageId = null, pathname = null, bookingTimeZone, previewStage = "published", apiBaseUrl = null, portalToken = null, readAuthority, bookingOfferingPresets = [], appointmentServicePathPrefix = null, mailingList = { tag: "not_configured" }, eventRegistrationOverlayEnabled = false, loaderFailures = {} } = dataContext ?? {};
565
593
  return {
566
594
  siteId,
595
+ demoEmailSuppressed: resolveDemoEmailSuppression(dataContext),
567
596
  siteName,
568
597
  pageId,
569
598
  pathname,
@@ -579,6 +608,9 @@ function buildPageRendererRootRuntime(dataContext) {
579
608
  loaderFailures
580
609
  };
581
610
  }
611
+ function resolveDemoEmailSuppression(dataContext) {
612
+ return dataContext?.demoEmailSuppressed === true;
613
+ }
582
614
  //#endregion
583
615
  //#region ../blocks/src/pageRenderAudience.tsx
584
616
  /**
@@ -1001,15 +1033,17 @@ function planNewsletterBlockSubmission(placement) {
1001
1033
  sourceRef
1002
1034
  } : { tag: "unavailable" };
1003
1035
  }
1004
- if (placement.publishedPlacement && "kind" in placement.publishedPlacement) return { tag: "unpublished-settings" };
1005
- if (placement.publishedPlacement) return planNewsletterPreviewSubmission({
1006
- blockId: placement.blockId,
1007
- publishedContentId: placement.publishedPlacement.id,
1008
- renderedContent: placement.renderedContent,
1009
- publishedContent: placement.publishedPlacement.content
1010
- });
1011
- if (placement.stage === "preview") return { tag: "unpublished-form" };
1012
- return { tag: "unavailable" };
1036
+ const published = placement.publishedPlacement;
1037
+ if (published === null) return placement.stage === "preview" ? { tag: "unpublished-form" } : { tag: "unavailable" };
1038
+ switch (published.kind) {
1039
+ case "incomplete": return { tag: "unpublished-settings" };
1040
+ case "published": return planNewsletterPreviewSubmission({
1041
+ blockId: placement.blockId,
1042
+ publishedContentId: published.id,
1043
+ renderedContent: placement.renderedContent,
1044
+ publishedContent: published.content
1045
+ });
1046
+ }
1013
1047
  }
1014
1048
  /** Decide whether the visible draft can safely cite the published placement. */
1015
1049
  function planNewsletterPreviewSubmission(placement) {
@@ -1256,19 +1290,6 @@ function createBlockErrorBoundary() {
1256
1290
  const BlockErrorBoundary = createBlockErrorBoundary();
1257
1291
  //#endregion
1258
1292
  //#region ../blocks/src/pageRenderAdmission.ts
1259
- /** Pair a published version with the content it authorises at the render boundary. */
1260
- function readPublishedBlockPlacement(id, content) {
1261
- if (id == null && content == null) return null;
1262
- if (id == null || content == null) return {
1263
- kind: "incomplete",
1264
- id: id ?? null,
1265
- content: content ?? null
1266
- };
1267
- return {
1268
- id,
1269
- content
1270
- };
1271
- }
1272
1293
  function toEditorPresentationPage(page) {
1273
1294
  if (!page) return null;
1274
1295
  return {
@@ -2842,11 +2863,16 @@ function isNonEmptyString(value) {
2842
2863
  function hasText(value) {
2843
2864
  return isNonEmptyString(value);
2844
2865
  }
2845
- ({
2866
+ const FILE_STORAGE_BUCKETS = {
2846
2867
  publicSite: unsafeAsStorageBucketName("media"),
2847
2868
  privateSite: unsafeAsStorageBucketName("site-files-private"),
2848
- temporary: unsafeAsStorageBucketName("temp-uploads")
2849
- }).publicSite;
2869
+ temporary: unsafeAsStorageBucketName("temp-uploads"),
2870
+ siteAssets: unsafeAsStorageBucketName("site-assets"),
2871
+ siteFonts: unsafeAsStorageBucketName("site-fonts"),
2872
+ bookingRequirementDocuments: unsafeAsStorageBucketName("booking-requirement-documents")
2873
+ };
2874
+ FILE_STORAGE_BUCKETS.publicSite, FILE_STORAGE_BUCKETS.siteAssets, FILE_STORAGE_BUCKETS.siteFonts;
2875
+ FILE_STORAGE_BUCKETS.publicSite, FILE_STORAGE_BUCKETS.privateSite, FILE_STORAGE_BUCKETS.temporary, FILE_STORAGE_BUCKETS.siteAssets, FILE_STORAGE_BUCKETS.siteFonts, FILE_STORAGE_BUCKETS.bookingRequirementDocuments;
2850
2876
  const IMAGE_FILE_FORMATS = [
2851
2877
  "jpeg",
2852
2878
  "png",
@@ -3782,9 +3808,9 @@ function MediaEditorProvider({ siteId, apiClient, children, bucket = DEFAULT_MED
3782
3808
  });
3783
3809
  }, [baseAssetsSnapshotKey, siteId]);
3784
3810
  const repo = useMemo(() => {
3785
- const clientFn = ((request) => {
3811
+ const clientFn = (request) => {
3786
3812
  return apiClient(augmentRequest ? augmentRequest(request, { siteId }) : request);
3787
- });
3813
+ };
3788
3814
  return createCachedMediaRepo(createApiMediaRepo({ client: clientFn }));
3789
3815
  }, [
3790
3816
  apiClient,
@@ -5195,6 +5221,25 @@ function applyPreviewChromeSurfaceToElement(element, surface, options) {
5195
5221
  element.removeAttribute(SURFACE_DOCUMENT_DATA_ATTRIBUTE);
5196
5222
  }
5197
5223
  //#endregion
5224
+ //#region ../preview-next/src/client/preview/previewCustomizeAutosave.ts
5225
+ /** Work selection and checkpoint capture share the existing transaction objects. */
5226
+ function previewCustomizeCanAutosave(workflow) {
5227
+ return workflow.kind === "loaded" && (workflow.mutation.kind === "dirty" || workflow.mutation.kind === "failed") && workflow.mutation.actions.length > 0;
5228
+ }
5229
+ /** Preserve transaction identity and history while a checkpoint waits for an active save. */
5230
+ function previewCustomizePendingBatch(workflow) {
5231
+ if (workflow.kind !== "loaded") return { transactions: [] };
5232
+ switch (workflow.mutation.kind) {
5233
+ case "dirty":
5234
+ case "failed": return { transactions: workflow.mutation.actions };
5235
+ case "applying": return { transactions: workflow.mutation.queuedActions };
5236
+ case "idle":
5237
+ case "undoing":
5238
+ case "redoing":
5239
+ case "stale": return { transactions: [] };
5240
+ }
5241
+ }
5242
+ //#endregion
5198
5243
  //#region ../blocks/src/system/customize/serializeBackgroundOverride.ts
5199
5244
  function serializeBackgroundOverride(override) {
5200
5245
  switch (override.kind) {
@@ -6019,10 +6064,10 @@ function beginPreviewCustomizeApply(workflow, action) {
6019
6064
  }
6020
6065
  };
6021
6066
  }
6022
- function beginPreviewCustomizeAutosave(workflow) {
6067
+ function beginPreviewCustomizeAutosave(workflow, captured) {
6023
6068
  if (workflow.kind !== "loaded") return skippedPreviewCustomizeBeginResult("not-loaded");
6024
- if (workflow.mutation.kind !== "dirty" && workflow.mutation.kind !== "failed") return skippedPreviewCustomizeBeginResult("no-history-entry");
6025
- const nextMutation = previewCustomizeMutationFromQueueState(beginAutosaveBatch(previewCustomizeQueueStateFromMutation(workflow.mutation)));
6069
+ if (!previewCustomizeCanAutosave(workflow)) return skippedPreviewCustomizeBeginResult("no-history-entry");
6070
+ const nextMutation = previewCustomizeMutationFromQueueState(beginAutosaveBatch(previewCustomizeQueueStateFromMutation(workflow.mutation), captured));
6026
6071
  if (nextMutation.kind !== "applying") return skippedPreviewCustomizeBeginResult("no-history-entry");
6027
6072
  const actions = nextMutation.batch.transactions.map((intent) => intent.action);
6028
6073
  if (actions.length === 0) return skippedPreviewCustomizeBeginResult("no-history-entry");
@@ -6200,21 +6245,6 @@ function isPendingMutation(mutation) {
6200
6245
  default: return assertNever$1(mutation, "Unhandled preview customize mutation");
6201
6246
  }
6202
6247
  }
6203
- function pendingCustomizeIntents(mutation) {
6204
- switch (mutation.kind) {
6205
- case "dirty": return mutation.actions;
6206
- case "applying": return mutation.queuedActions;
6207
- case "failed": return mutation.actions;
6208
- case "idle":
6209
- case "undoing":
6210
- case "redoing":
6211
- case "stale": return [];
6212
- default: return assertNever$1(mutation, "Unhandled preview customize mutation");
6213
- }
6214
- }
6215
- function previewCustomizePendingActions(workflow) {
6216
- return workflow.kind === "loaded" ? pendingCustomizeIntents(workflow.mutation).map((intent) => intent.action) : [];
6217
- }
6218
6248
  function previewCustomizeTargetKey(action) {
6219
6249
  switch (action.kind) {
6220
6250
  case "set-layout": return `block:${action.blockId}:layout`;
@@ -6395,6 +6425,22 @@ function optimisticBoundaryChoice(action) {
6395
6425
  }
6396
6426
  }
6397
6427
  //#endregion
6428
+ //#region ../preview-next/src/client/preview/usePreviewCustomizeWorkflowState.ts
6429
+ /** Update the scheduler's authoritative workflow before its next serialized request. */
6430
+ function usePreviewCustomizeWorkflowState() {
6431
+ const [state, setRenderedState] = useState(unsupportedPreviewCustomizeWorkflowState);
6432
+ const stateRef = useRef(state);
6433
+ return [
6434
+ state,
6435
+ useCallback((next) => {
6436
+ const value = typeof next === "function" ? next(stateRef.current) : next;
6437
+ stateRef.current = value;
6438
+ setRenderedState(value);
6439
+ }, []),
6440
+ stateRef
6441
+ ];
6442
+ }
6443
+ //#endregion
6398
6444
  //#region ../blocks/src/system/customize/facets.ts
6399
6445
  function defineCustomizeFacet(definition) {
6400
6446
  return definition;
@@ -6600,56 +6646,37 @@ function currentLocalBlockContent(uiStore, targetBlockId) {
6600
6646
  const current = uiStore.getState().drafts.getCurrentValues(unsafeAsEditorBlockId(targetBlockId));
6601
6647
  return isRecord$5(current) ? current : null;
6602
6648
  }
6649
+ /**
6650
+ * The customize runtime drives these values and owns their undo, so they go in as a
6651
+ * history-free `edited` event (issue 1553). A block the store hasn't loaded is created
6652
+ * first, pristine at the content the runtime started from.
6653
+ */
6603
6654
  function replaceLocalBlockContentWithoutHistory(input) {
6604
6655
  const editorBlockId = unsafeAsEditorBlockId(input.targetBlockId);
6605
- const history = input.uiStore.getState().history;
6606
- const snapshot = history.getState().present;
6607
- const draft = snapshot.drafts[editorBlockId];
6608
- const nextDraft = draft ? applyDraftContentPatch(draft, input.nextContent, input.baselineEquivalentContent) : localRuntimeDraftForBlock({
6609
- editorBlockId,
6610
- targetBlockId: input.targetBlockId,
6611
- editorModel: input.editorModel,
6612
- previousContent: input.previousContent,
6613
- nextContent: input.nextContent
6614
- });
6615
- if (!nextDraft) return { kind: "missing-block-model" };
6616
- history.restorePresent({
6617
- ...snapshot,
6618
- drafts: {
6619
- ...snapshot.drafts,
6620
- [editorBlockId]: nextDraft
6621
- }
6622
- });
6656
+ const drafts = input.uiStore.getState().drafts;
6657
+ const draft = drafts.getBlockSnapshot(editorBlockId);
6658
+ if (!draft && !initRuntimeBlock(input.uiStore, editorBlockId, input)) return { kind: "missing-block-model" };
6659
+ drafts.editWithoutHistory(editorBlockId, shownContent(draft, input.nextContent, input.baselineEquivalentContent));
6623
6660
  return { kind: "applied" };
6624
6661
  }
6625
- function applyDraftContentPatch(draft, nextContent, baselineEquivalentContent) {
6626
- const nextValues = unsafeAsEditorBlockValues(nextContent);
6627
- const baselineEquivalentValues = baselineEquivalentContent ? unsafeAsEditorBlockValues(baselineEquivalentContent) : null;
6628
- const current = baselineEquivalentValues && recordsEqual(nextValues, baselineEquivalentValues) ? draft.baseline : nextValues;
6629
- return {
6630
- ...draft,
6631
- version: draft.version + 1,
6632
- current,
6633
- syncState: recordsEqual(draft.baseline, current) ? { kind: "baseline" } : { kind: "pending" }
6634
- };
6662
+ /** Content equivalent to the baseline shows the baseline itself, so the block is pristine again. */
6663
+ function shownContent(draft, nextContent, baselineEquivalentContent) {
6664
+ return draft && baselineEquivalentContent && recordsEqual(nextContent, baselineEquivalentContent) ? draft.sync.baseline.values : nextContent;
6635
6665
  }
6636
- function localRuntimeDraftForBlock(input) {
6666
+ function initRuntimeBlock(uiStore, editorBlockId, input) {
6637
6667
  const block = input.editorModel?.blocks.find((candidate) => candidate.blockId === input.targetBlockId) ?? null;
6638
- if (!block) return null;
6639
- return {
6640
- id: input.editorBlockId,
6641
- version: 1,
6642
- baseline: unsafeAsEditorBlockValues(input.previousContent),
6643
- current: unsafeAsEditorBlockValues(input.nextContent),
6644
- syncState: { kind: "pending" },
6645
- meta: {
6668
+ if (!block) return false;
6669
+ const state = uiStore.getState();
6670
+ state.admitServerBlocks([{
6671
+ block: {
6672
+ id: editorBlockId,
6646
6673
  kind: block.blockKind,
6647
- purpose: null,
6648
- orderIndex: null,
6649
- publishedContent: null,
6650
- optimisticHash: null
6651
- }
6652
- };
6674
+ content: input.previousContent,
6675
+ versions: state.blockVersions.require(editorBlockId)
6676
+ },
6677
+ action: "reconcile"
6678
+ }]);
6679
+ return true;
6653
6680
  }
6654
6681
  function isRecord$5(value) {
6655
6682
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -6674,17 +6701,13 @@ const PageDesignEditorStateContext = createContext({
6674
6701
  });
6675
6702
  function PreviewPageDesignEditorStateProvider({ apiClient, siteId, pageId, enabled, autosaveDelayMs, children }) {
6676
6703
  const [reloadKey, setReloadKey] = useState(0);
6677
- const [workflowState, setWorkflowState] = useState(unsupportedPreviewCustomizeWorkflowState);
6704
+ const [workflowState, setWorkflowState, workflowStateRef] = usePreviewCustomizeWorkflowState();
6678
6705
  const [backgroundImagePool, setBackgroundImagePool] = useState([]);
6679
6706
  const [backgroundImagePoolStatus, setBackgroundImagePoolStatus] = useState("idle");
6680
- const workflowStateRef = useRef(workflowState);
6681
6707
  const pendingDesignHistoryOrderRecordRef = useRef(false);
6682
6708
  const previewDesignHistoryOrder = usePreviewDesignHistoryOrder();
6683
6709
  const backgroundImagePoolRequestRef = useRef(null);
6684
6710
  const uiStore = useOptionalEditorUiStoreInstance();
6685
- useEffect(() => {
6686
- workflowStateRef.current = workflowState;
6687
- }, [workflowState]);
6688
6711
  useEffect(() => {
6689
6712
  if (!enabled || !pageId) {
6690
6713
  setWorkflowState(unsupportedPreviewCustomizeWorkflowState());
@@ -6754,9 +6777,9 @@ function PreviewPageDesignEditorStateProvider({ apiClient, siteId, pageId, enabl
6754
6777
  siteId
6755
6778
  ]);
6756
6779
  const autosave = useDebouncedLatestSave({
6757
- getSnapshot: () => previewCustomizePendingActions(workflowStateRef.current),
6758
- buildPayload: (actions) => actions,
6759
- shouldSkip: (actions) => actions.length === 0 || !enabled || !pageId,
6780
+ getSnapshot: () => previewCustomizePendingBatch(workflowStateRef.current),
6781
+ buildPayload: (batch) => batch.transactions.map((transaction) => transaction.action),
6782
+ shouldSkip: (batch) => batch.transactions.length === 0 || !enabled || !pageId || !previewCustomizeCanAutosave(workflowStateRef.current),
6760
6783
  delay: autosaveDelayMs,
6761
6784
  save: async (actions) => {
6762
6785
  if (!pageId) return null;
@@ -6769,9 +6792,9 @@ function PreviewPageDesignEditorStateProvider({ apiClient, siteId, pageId, enabl
6769
6792
  editorModel: currentPageState.kind === "loaded" ? currentPageState.editorModel : null
6770
6793
  });
6771
6794
  },
6772
- onSaving: () => {
6795
+ onSaving: (batch) => {
6773
6796
  setWorkflowState((current) => {
6774
- const begin = beginPreviewCustomizeAutosave(current);
6797
+ const begin = beginPreviewCustomizeAutosave(current, batch);
6775
6798
  if (begin.kind !== "started") return current;
6776
6799
  pendingDesignHistoryOrderRecordRef.current = begin.recordsHistoryEntry;
6777
6800
  return begin.state;
@@ -6794,7 +6817,7 @@ function PreviewPageDesignEditorStateProvider({ apiClient, siteId, pageId, enabl
6794
6817
  });
6795
6818
  useLayoutEffect(() => {
6796
6819
  return () => {
6797
- autosave.flush();
6820
+ autosave.flush().catch(() => {});
6798
6821
  };
6799
6822
  }, [autosave]);
6800
6823
  const value = useMemo(() => ({
@@ -7075,144 +7098,520 @@ const PAGE_CONTENT_TYPE_SCHEMA = {
7075
7098
  }
7076
7099
  };
7077
7100
  //#endregion
7078
- //#region ../preview-next/src/client/preview/PreviewEntryControllerProvider.tsx
7079
- function toEditorInitialBlock(block, index) {
7080
- return {
7081
- id: block.id,
7082
- draftContentId: block.draftContentId ?? null,
7083
- publishedContentId: block.publishedContentId ?? null,
7084
- kind: block.kind,
7085
- orderIndex: typeof block.orderIndex === "number" ? block.orderIndex : index,
7086
- content: block.content ?? null,
7087
- draftContent: block.draftContent ?? null,
7088
- publishedContent: block.publishedContent ?? null,
7089
- bindings: block.bindings ?? null,
7090
- optimisticHash: block.optimisticHash ?? null
7091
- };
7101
+ //#region ../preview-next/src/client/blocks/linkedEntryRenderOverlay.ts
7102
+ /**
7103
+ * What a tab rendering its own edits lays over the server render for one record:
7104
+ * its edit, or else its accepted save until the render catches up (rows H1, H3, H4).
7105
+ * A pristine record with no handover (even one kept after a discard, issue 1553 D2)
7106
+ * contributes nothing, so it never masks later server-rendered content.
7107
+ */
7108
+ function ownEditsOverlay(entry, handovers) {
7109
+ if (isEdited(entry.sync)) {
7110
+ const content = resolveRenderedValues("own-edits", entry, null);
7111
+ return content ? {
7112
+ content: { ...content },
7113
+ optimisticHash: baselineRevisionOf(entry.sync) ?? null
7114
+ } : null;
7115
+ }
7116
+ const handover = activeLinkedSaveHandover(handovers, entry.meta.entryId, entry.sync);
7117
+ const saved = entry.sync.baseline.values;
7118
+ return handover && saved ? {
7119
+ content: { ...saved },
7120
+ optimisticHash: handover.revision,
7121
+ handoverRevision: handover.revision
7122
+ } : null;
7092
7123
  }
7093
- function PreviewEntryControllerProvider({ children, siteId, pageId, routeId: providedRouteId, entryData, contentTypeSchema, draftContent, initialStatus = "draft", initialBlocks, pageMetadata, apiClient }) {
7094
- const { isEditingMode } = useEditor();
7095
- const schema = contentTypeSchema ?? PAGE_CONTENT_TYPE_SCHEMA;
7096
- const initialEntry = useMemo(() => {
7097
- if (entryData) {
7098
- const draftPath = entryData.draftPath ?? entryData.path ?? "";
7099
- const publishedPath = entryData.path ?? "";
7100
- return {
7101
- kind: "routable",
7102
- id: entryData.id,
7103
- draft: {
7104
- title: entryData.title ?? "",
7105
- slug: entryData.slug || "",
7106
- status: entryData.status ?? "draft",
7107
- publishAt: entryData.publishAt ?? null,
7108
- path: draftPath
7109
- },
7110
- published: {
7111
- title: entryData.title ?? "",
7112
- path: publishedPath,
7113
- status: entryData.status ?? "draft",
7114
- publishAt: entryData.publishAt ?? null
7115
- },
7116
- status: entryData.status ?? "draft",
7117
- route: {
7118
- draftMetaTitle: entryData.draftMetaTitle ?? null,
7119
- draftMetaDescription: entryData.draftMetaDescription ?? null,
7120
- publishedMetaTitle: entryData.metaTitle ?? null,
7121
- publishedMetaDescription: entryData.metaDescription ?? null,
7122
- ogImageId: entryData.ogImageId ?? null
7123
- }
7124
- };
7125
- }
7126
- if (!pageMetadata || !pageId) return void 0;
7127
- const routing = createRoutingHelpers(schema, { slug: null });
7128
- return createSnapshotFromPageRecord({
7129
- id: pageId,
7130
- draftTitle: pageMetadata.draftTitle,
7131
- draftPath: pageMetadata.draftPath,
7132
- draftStatus: pageMetadata.draftStatus,
7133
- title: pageMetadata.title,
7134
- path: pageMetadata.path,
7135
- status: pageMetadata.status,
7136
- publishedAt: pageMetadata.publishedAt,
7137
- draftMetaTitle: pageMetadata.draftMetaTitle,
7138
- draftMetaDescription: pageMetadata.draftMetaDescription,
7139
- publishedMetaTitle: pageMetadata.publishedMetaTitle,
7140
- publishedMetaDescription: pageMetadata.publishedMetaDescription,
7141
- ogImageId: pageMetadata.ogImageId
7142
- }, routing, {
7143
- title: "",
7144
- slug: null
7124
+ /** A viewer lays another tab's live draft over the render, and nothing else. */
7125
+ function liveDraftOverlay(entry, remote) {
7126
+ const content = remote ? resolveRenderedValues("live-drafts", entry, remote) : null;
7127
+ return content ? {
7128
+ content: { ...content },
7129
+ optimisticHash: baselineRevisionOf(entry.sync) ?? null
7130
+ } : null;
7131
+ }
7132
+ /**
7133
+ * The linked-entry values the preview renders, following the tab's render source
7134
+ * (its own edits, or another tab's live drafts while it only views). Entries only
7135
+ * another tab is editing are included too. A viewer never reads its own handovers,
7136
+ * so a later external write is never masked (row H8).
7137
+ */
7138
+ function linkedEntryRenderOverlaysFromStore(uiStore) {
7139
+ const state = uiStore.getState();
7140
+ const source = renderSourceFor(state.editability);
7141
+ const entries = state.linkedEntries.inspect();
7142
+ const local = entries.flatMap((entry) => {
7143
+ const remote = remoteDraftValues(state.remoteDrafts, {
7144
+ kind: "linked-entry",
7145
+ id: entry.meta.entryId
7145
7146
  });
7146
- }, [
7147
- entryData,
7148
- pageMetadata,
7149
- pageId,
7150
- schema
7151
- ]);
7152
- const normalizedInitialBlocks = useMemo(() => {
7153
- return (initialBlocks ?? []).map(toEditorInitialBlock);
7154
- }, [initialBlocks]);
7155
- const entityId = pageId || entryData?.id || "";
7156
- const entityType = entryData ? entryData.type : "page";
7157
- const entityLabel = entryData ? "Entry" : "Page";
7158
- const routeId = providedRouteId ?? void 0;
7159
- const initialContent = entryData ? draftContent ?? entryData.content ?? {} : null;
7160
- const common = {
7161
- apiClient,
7162
- type: entityType || "page",
7163
- siteId,
7164
- owner: {
7165
- kind: "contentEntry",
7166
- contentEntryId: entityId
7167
- },
7168
- routeId,
7169
- schema,
7170
- entityLabel,
7171
- initialEntry,
7172
- initialBlocks: normalizedInitialBlocks,
7173
- historyShortcutsEnabled: isEditingMode
7174
- };
7175
- return entryData ? /* @__PURE__ */ jsx(EntryControllerProvider, {
7176
- ...common,
7177
- kind: "content",
7178
- initialContent,
7179
- children
7180
- }) : /* @__PURE__ */ jsx(EntryControllerProvider, {
7181
- ...common,
7182
- kind: "page",
7183
- initialStatus,
7184
- children
7147
+ const overlay = source === "own-edits" ? ownEditsOverlay(entry, state.linkedSaveHandovers) : liveDraftOverlay(entry, remote);
7148
+ return overlay ? [[entry.meta.entryId, overlay]] : [];
7185
7149
  });
7150
+ const localIds = new Set(entries.map((entry) => entry.meta.entryId));
7151
+ const remoteOnly = [...state.remoteDrafts?.values() ?? []].flatMap((entry) => {
7152
+ if (entry.item.kind !== "linked-entry") return [];
7153
+ const entryId = unsafeAsLinkedContentEntryId(entry.item.id);
7154
+ return localIds.has(entryId) ? [] : [[entryId, { content: entry.item.values }]];
7155
+ });
7156
+ return new Map([...local, ...remoteOnly]);
7186
7157
  }
7187
- //#endregion
7188
- //#region ../preview-next/src/client/preview/usePreviewKeepAlive.ts
7189
- const DEFAULT_INTERVAL_MS = 600 * 1e3;
7190
- function withJitter(baseMs) {
7191
- const jitter = .1 * baseMs;
7192
- const delta = (Math.random() * 2 - 1) * jitter;
7193
- return Math.max(15e3, Math.round(baseMs + delta));
7158
+ function applyLinkedEntryRenderOverlay(value, overlays) {
7159
+ if (overlays.size === 0) return value;
7160
+ return overlayValue(value, overlays);
7194
7161
  }
7195
- function usePreviewKeepAlive({ enabled, fetcher, onExpired, intervalMs = DEFAULT_INTERVAL_MS }) {
7196
- useEffect(() => {
7197
- if (!enabled) return void 0;
7198
- let isActive = true;
7199
- async function keepAlive() {
7200
- try {
7201
- const response = await fetcher("/api/preview/keep-alive", { method: "POST" }, "keep-alive");
7202
- if (response.status === 401 && isActive) {
7203
- onExpired("keep-alive");
7204
- return;
7205
- }
7206
- if (!response.ok && isActive) console.warn("Preview keep-alive failed", await response.text());
7207
- } catch (error) {
7208
- if (isActive) console.warn("Preview keep-alive error", error);
7209
- }
7210
- }
7211
- keepAlive();
7212
- const id = window.setInterval(keepAlive, withJitter(intervalMs));
7213
- return () => {
7214
- isActive = false;
7215
- window.clearInterval(id);
7162
+ function applyLinkedEntryRenderOverlayToDataContext(dataContext, overlays) {
7163
+ if (!dataContext?.resolvedData || overlays.size === 0) return dataContext;
7164
+ const resolvedData = applyLinkedEntryRenderOverlay(dataContext.resolvedData, overlays);
7165
+ if (resolvedData === dataContext.resolvedData) return dataContext;
7166
+ return {
7167
+ ...dataContext,
7168
+ resolvedData
7169
+ };
7170
+ }
7171
+ function overlayValue(value, overlays) {
7172
+ if (Array.isArray(value)) {
7173
+ let changed = false;
7174
+ const next = value.map((item) => {
7175
+ const overlaid = overlayValue(item, overlays);
7176
+ if (overlaid !== item) changed = true;
7177
+ return overlaid;
7178
+ });
7179
+ return changed ? next : value;
7180
+ }
7181
+ if (!isRecord$4(value)) return value;
7182
+ const match = matchingOverlay(value, overlays);
7183
+ if (match) return overlaidEntry(value, match.meta, match.overlay);
7184
+ let changed = false;
7185
+ const next = {};
7186
+ for (const [key, child] of Object.entries(value)) {
7187
+ const overlaid = overlayValue(child, overlays);
7188
+ if (overlaid !== child) changed = true;
7189
+ next[key] = overlaid;
7190
+ }
7191
+ return changed ? next : value;
7192
+ }
7193
+ /**
7194
+ * The overlay for a rendered linked entry, if one applies. A handover stops at an
7195
+ * occurrence already rendered at the saved revision (issue 1553, DP6).
7196
+ */
7197
+ function matchingOverlay(value, overlays) {
7198
+ const meta = parseLinkedEntryMeta(value[LINKED_CONTENT_ENTRY_META_KEY]);
7199
+ const overlay = meta ? overlays.get(unsafeAsLinkedContentEntryId(meta.entryId)) : void 0;
7200
+ if (!meta || !overlay) return null;
7201
+ return overlay.handoverRevision !== void 0 && meta.optimisticHash === overlay.handoverRevision ? null : {
7202
+ meta,
7203
+ overlay
7204
+ };
7205
+ }
7206
+ function overlaidEntry(value, meta, overlay) {
7207
+ const displayProjections = resolveOverlayDisplayProjections(overlay.content, meta);
7208
+ const titleProjection = resolveOverlayTitleProjection({
7209
+ currentValue: value,
7210
+ content: overlay.content,
7211
+ meta,
7212
+ displayProjections
7213
+ });
7214
+ const title = titleProjection ? { title: titleProjection } : {};
7215
+ return {
7216
+ ...value,
7217
+ ...displayProjections,
7218
+ ...title,
7219
+ content: overlay.content,
7220
+ optimisticHash: overlayRevision(overlay, meta),
7221
+ [LINKED_CONTENT_ENTRY_META_KEY]: {
7222
+ ...meta,
7223
+ ...title,
7224
+ optimisticHash: overlayRevision(overlay, meta)
7225
+ }
7226
+ };
7227
+ }
7228
+ /**
7229
+ * Each linked entry's rendered revisions, one per occurrence in the loader data, read
7230
+ * before any overlay. Local handover retention compares them with the saved revision
7231
+ * (issue 1553, DP7).
7232
+ */
7233
+ function renderedLinkedRevisions(dataContext) {
7234
+ const occurrences = linkedEntryOccurrences(dataContext?.resolvedData);
7235
+ const entryIds = [...new Set(occurrences.map((meta) => meta.entryId))];
7236
+ return new Map(entryIds.map((entryId) => [unsafeAsLinkedContentEntryId(entryId), occurrences.filter((meta) => meta.entryId === entryId).map((meta) => meta.optimisticHash)]));
7237
+ }
7238
+ function linkedEntryOccurrences(value) {
7239
+ if (Array.isArray(value)) return value.flatMap(linkedEntryOccurrences);
7240
+ if (!isRecord$4(value)) return [];
7241
+ const meta = parseLinkedEntryMeta(value[LINKED_CONTENT_ENTRY_META_KEY]);
7242
+ const nested = Object.entries(value).filter(([key]) => key !== LINKED_CONTENT_ENTRY_META_KEY).flatMap(([, child]) => linkedEntryOccurrences(child));
7243
+ return meta ? [meta, ...nested] : nested;
7244
+ }
7245
+ function resolveOverlayDisplayProjections(content, meta) {
7246
+ const projections = {};
7247
+ for (const source of meta.fieldSources) {
7248
+ if (source.kind !== "content-field") continue;
7249
+ if (source.displayPath.startsWith("content.")) continue;
7250
+ if (source.displayPath.includes(".")) continue;
7251
+ if (!(source.fieldPath in content)) continue;
7252
+ projections[source.displayPath] = content[source.fieldPath];
7253
+ }
7254
+ return projections;
7255
+ }
7256
+ function resolveOverlayTitleProjection(input) {
7257
+ const projectedTitle = input.displayProjections.title;
7258
+ if (typeof projectedTitle === "string") return projectedTitle;
7259
+ if (input.meta.fieldSources.find((source) => source.displayPath === "title")?.kind === "read-only") {
7260
+ const currentTitle = input.currentValue.title;
7261
+ return typeof currentTitle === "string" ? currentTitle : input.meta.title;
7262
+ }
7263
+ return resolveOverlayTitle(input.content, input.meta);
7264
+ }
7265
+ function resolveOverlayTitle(content, meta) {
7266
+ const titleField = meta.contentType.titleField;
7267
+ if (titleField) {
7268
+ const value = content[titleField];
7269
+ if (typeof value === "string" && value.trim().length > 0) return value;
7270
+ }
7271
+ return meta.title;
7272
+ }
7273
+ function parseLinkedEntryMeta(value) {
7274
+ return getLinkedContentEntryMeta({ [LINKED_CONTENT_ENTRY_META_KEY]: value });
7275
+ }
7276
+ function isRecord$4(value) {
7277
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7278
+ }
7279
+ function overlayRevision(overlay, meta) {
7280
+ return overlay.optimisticHash === void 0 ? meta.optimisticHash : overlay.optimisticHash;
7281
+ }
7282
+ //#endregion
7283
+ //#region ../preview-next/src/client/blocks/renderPrecedence.ts
7284
+ /** A block's content as the preview renders it, from the tab's render source. */
7285
+ function renderedBlockContent(uiStore, blockId) {
7286
+ const state = uiStore.getState();
7287
+ return resolveRenderedValues(renderSourceFor(state.editability), state.drafts.getBlockSnapshot(blockId), remoteDraftValues(state.remoteDrafts, {
7288
+ kind: "block",
7289
+ id: blockId
7290
+ }));
7291
+ }
7292
+ /**
7293
+ * An entry template page renders the entry's own fields from `contentEntry`. The
7294
+ * server sent them as they were on load; the editor's rendered values (local
7295
+ * edits, then another tab's live draft) take over from there.
7296
+ */
7297
+ function withRenderedContentEntry(dataContext, content) {
7298
+ if (!dataContext?.contentEntry || !content) return dataContext;
7299
+ return {
7300
+ ...dataContext,
7301
+ contentEntry: {
7302
+ ...dataContext.contentEntry,
7303
+ ...content
7304
+ }
7305
+ };
7306
+ }
7307
+ /** Loader data fetched in the browser replaces the server's, block by block. */
7308
+ function mergeResolvedDataContext(dataContext, liveResolvedData) {
7309
+ if (!dataContext || !liveResolvedData) return dataContext;
7310
+ return {
7311
+ ...dataContext,
7312
+ resolvedData: {
7313
+ ...dataContext.resolvedData ?? {},
7314
+ ...liveResolvedData
7315
+ }
7316
+ };
7317
+ }
7318
+ //#endregion
7319
+ //#region ../preview-next/src/client/blocks/useLinkedSaveHandoverRetention.ts
7320
+ /**
7321
+ * The host's refresh of its server data: the same callback live drafts give a viewer
7322
+ * whose saved remote draft lags. Absent when the host supplies none.
7323
+ */
7324
+ const PreviewRefreshBaselinesContext = createContext(null);
7325
+ /** Changes whenever a handover is recorded or dropped, so the renderer re-renders. */
7326
+ function linkedSaveHandoversVersion(handovers) {
7327
+ return [...handovers].map(([entryId, handover]) => `${entryId}@${handover.revision}`).join("|");
7328
+ }
7329
+ /**
7330
+ * Local retention of this tab's linked-entry save handovers (issue 1553, DP7). The
7331
+ * renderer holds the rendered data, so it decides catch-up: a handover whose entry is
7332
+ * rendered at the saved revision everywhere drops with no refresh (row H1b); otherwise
7333
+ * the shared timing asks the host for one refresh, then drops it (row H2).
7334
+ */
7335
+ function useLinkedSaveHandoverRetention(uiStore, dataContext, liveResolvedData) {
7336
+ const rendered = useMemo(() => renderedLinkedRevisions(mergeResolvedDataContext(dataContext, liveResolvedData)), [dataContext, liveResolvedData]);
7337
+ const refreshBaselines = useContext(PreviewRefreshBaselinesContext);
7338
+ const refreshRef = useRef(refreshBaselines);
7339
+ useEffect(() => {
7340
+ refreshRef.current = refreshBaselines;
7341
+ });
7342
+ useRetentionTicks(uiStore, useCallback(() => {
7343
+ const state = uiStore.getState();
7344
+ if (state.linkedSaveHandovers.size === 0) return;
7345
+ const plan = planLinkedSaveHandoverRetention(state.linkedSaveHandovers, rendered, Date.now());
7346
+ if (!plan.changed) return;
7347
+ state.setLinkedSaveHandovers(plan.entries);
7348
+ if (plan.refresh) refreshRef.current?.();
7349
+ }, [rendered, uiStore]));
7350
+ }
7351
+ //#endregion
7352
+ //#region ../preview-next/src/client/preview/PreviewEntryControllerProvider.tsx
7353
+ function toEditorInitialBlock(block, index) {
7354
+ return {
7355
+ ...block,
7356
+ orderIndex: typeof block.orderIndex === "number" ? block.orderIndex : index
7357
+ };
7358
+ }
7359
+ function previewLiveDraftsConfig(liveDrafts, siteId, scope) {
7360
+ if (!liveDrafts) return null;
7361
+ return {
7362
+ client: liveDrafts.client,
7363
+ auth: {
7364
+ kind: "token",
7365
+ accessToken: liveDrafts.previewToken
7366
+ },
7367
+ siteId,
7368
+ scope,
7369
+ refreshBaselines: liveDrafts.refreshBaselines
7370
+ };
7371
+ }
7372
+ function previewEntryRoute(entryData) {
7373
+ return {
7374
+ draftMetaTitle: entryData.draftMetaTitle ?? null,
7375
+ draftMetaDescription: entryData.draftMetaDescription ?? null,
7376
+ publishedMetaTitle: entryData.metaTitle ?? null,
7377
+ publishedMetaDescription: entryData.metaDescription ?? null,
7378
+ ogImageId: entryData.ogImageId ?? null
7379
+ };
7380
+ }
7381
+ function snapshotFromPreviewEntry(entryData) {
7382
+ const title = entryData.title ?? "";
7383
+ const status = entryData.status ?? "draft";
7384
+ const publishAt = entryData.publishAt ?? null;
7385
+ return {
7386
+ kind: "routable",
7387
+ id: entryData.id,
7388
+ draft: {
7389
+ title,
7390
+ slug: entryData.slug || "",
7391
+ status,
7392
+ publishAt,
7393
+ path: entryData.draftPath ?? entryData.path ?? ""
7394
+ },
7395
+ published: {
7396
+ title,
7397
+ path: entryData.path ?? "",
7398
+ status,
7399
+ publishAt
7400
+ },
7401
+ status,
7402
+ route: previewEntryRoute(entryData)
7403
+ };
7404
+ }
7405
+ function snapshotFromPreviewPage(pageId, metadata, schema) {
7406
+ return createSnapshotFromPageRecord({
7407
+ id: pageId,
7408
+ draftTitle: metadata.draftTitle,
7409
+ draftPath: metadata.draftPath,
7410
+ draftStatus: metadata.draftStatus,
7411
+ title: metadata.title,
7412
+ path: metadata.path,
7413
+ status: metadata.status,
7414
+ publishedAt: metadata.publishedAt,
7415
+ draftMetaTitle: metadata.draftMetaTitle,
7416
+ draftMetaDescription: metadata.draftMetaDescription,
7417
+ publishedMetaTitle: metadata.publishedMetaTitle,
7418
+ publishedMetaDescription: metadata.publishedMetaDescription,
7419
+ ogImageId: metadata.ogImageId
7420
+ }, createRoutingHelpers(schema, { slug: null }), {
7421
+ title: "",
7422
+ slug: null
7423
+ });
7424
+ }
7425
+ function initialPreviewEntry(entryData, pageMetadata, pageId, schema) {
7426
+ if (entryData) return snapshotFromPreviewEntry(entryData);
7427
+ return pageMetadata && pageId ? snapshotFromPreviewPage(pageId, pageMetadata, schema) : void 0;
7428
+ }
7429
+ function previewEntity(pageId, pageNodeType, entryData, routeId) {
7430
+ return {
7431
+ id: pageId || entryData?.id || "",
7432
+ type: entryData?.type || "page",
7433
+ label: entryData && pageNodeType !== "page_surface" ? "Entry" : "Page",
7434
+ routeId: routeId ?? void 0
7435
+ };
7436
+ }
7437
+ function previewValues(entryData, pageMetadata) {
7438
+ if (!entryData) return {
7439
+ kind: "page",
7440
+ metadataRevision: pageMetadata?.draftUpdatedAt ?? null
7441
+ };
7442
+ const revision = entryData.editorRevision;
7443
+ if (!revision?.content) throw new Error("Preview draft is missing its editor revision");
7444
+ return {
7445
+ kind: "content",
7446
+ content: revision.contentValues,
7447
+ publishedContent: revision.publishedContent,
7448
+ contentRevision: revision.content,
7449
+ metadataRevision: revision.metadata
7450
+ };
7451
+ }
7452
+ function PreviewEntryControllerProvider({ children, siteId, pageId, pageNodeType = "page", routeId: providedRouteId, entryData, contentTypeSchema, initialStatus = "draft", initialBlocks, blockFieldExtensions, pageMetadata, apiClient, subscribeToLeaseChanges, onLeaseGranted, liveDrafts }) {
7453
+ const { isEditingMode, requestedEditingMode } = useEditor();
7454
+ const schema = contentTypeSchema ?? PAGE_CONTENT_TYPE_SCHEMA;
7455
+ const initialEntry = useMemo(() => initialPreviewEntry(entryData, pageMetadata, pageId, schema), [
7456
+ entryData,
7457
+ pageMetadata,
7458
+ pageId,
7459
+ schema
7460
+ ]);
7461
+ const normalizedInitialBlocks = useMemo(() => (initialBlocks ?? []).map(toEditorInitialBlock), [initialBlocks]);
7462
+ const entity = previewEntity(pageId, pageNodeType, entryData, providedRouteId);
7463
+ const leaseScope = requiredPreviewLeaseScope({
7464
+ nodeType: previewLeaseNodeType(pageNodeType, entryData),
7465
+ nodeId: entity.id
7466
+ });
7467
+ const values = previewValues(entryData, pageMetadata);
7468
+ const rendered = /* @__PURE__ */ jsx(RefreshBaselinesForRender, {
7469
+ liveDrafts,
7470
+ children
7471
+ });
7472
+ const editLease = usePreviewLeaseParticipation({
7473
+ requestedEditingMode,
7474
+ siteId,
7475
+ pageId,
7476
+ pageNodeType,
7477
+ leaseScope,
7478
+ subscribeToLeaseChanges,
7479
+ onLeaseGranted
7480
+ });
7481
+ const common = {
7482
+ apiClientFactory: useMemo(() => createEditorApiClientFactory(apiClient), [apiClient]),
7483
+ editLease,
7484
+ type: entity.type,
7485
+ siteId,
7486
+ owner: {
7487
+ kind: "contentEntry",
7488
+ contentEntryId: entity.id
7489
+ },
7490
+ routeId: entity.routeId,
7491
+ schema,
7492
+ entityLabel: entity.label,
7493
+ initialEntry,
7494
+ initialMetadataRevision: values.metadataRevision,
7495
+ initialBlocks: pageNodeType === "page_surface" ? void 0 : normalizedInitialBlocks,
7496
+ blockFieldExtensions,
7497
+ historyShortcutsEnabled: isEditingMode,
7498
+ liveDrafts: previewLiveDraftsConfig(liveDrafts, siteId, leaseScope)
7499
+ };
7500
+ if (pageNodeType === "page_surface" && pageId && pageMetadata) {
7501
+ if (values.kind !== "content") throw new Error("Preview draft is missing its editor revision");
7502
+ return /* @__PURE__ */ jsx(PreviewPageSurfaceController, {
7503
+ common,
7504
+ pageSurfaceId: pageId,
7505
+ pageMetadata,
7506
+ values,
7507
+ children: rendered
7508
+ });
7509
+ }
7510
+ return values.kind === "content" ? /* @__PURE__ */ jsx(EntryControllerProvider, {
7511
+ ...common,
7512
+ kind: "content",
7513
+ initialContent: values.content,
7514
+ initialPublishedContent: values.publishedContent,
7515
+ initialContentRevision: values.contentRevision,
7516
+ children: rendered
7517
+ }) : /* @__PURE__ */ jsx(EntryControllerProvider, {
7518
+ ...common,
7519
+ kind: "page",
7520
+ initialStatus,
7521
+ children: rendered
7522
+ });
7523
+ }
7524
+ /** Lease participation and its server-read invalidation share the same preview identity. */
7525
+ function usePreviewLeaseParticipation({ requestedEditingMode, siteId, pageId, pageNodeType, leaseScope, subscribeToLeaseChanges, onLeaseGranted }) {
7526
+ const queryClient = useQueryClient();
7527
+ return requestedEditingMode ? {
7528
+ siteId,
7529
+ scope: leaseScope,
7530
+ subscribeToLeaseChanges,
7531
+ onGranted: () => {
7532
+ onLeaseGranted?.();
7533
+ if (pageId) queryClient.invalidateQueries({ queryKey: previewBlocksQueryKey(siteId, pageId, pageNodeType) });
7534
+ }
7535
+ } : VIEWING_PARTICIPATION;
7536
+ }
7537
+ function RefreshBaselinesForRender({ liveDrafts, children }) {
7538
+ return /* @__PURE__ */ jsx(PreviewRefreshBaselinesContext.Provider, {
7539
+ value: liveDrafts?.refreshBaselines ?? null,
7540
+ children
7541
+ });
7542
+ }
7543
+ /**
7544
+ * An event's page in preview: its content is the page surface's, saved and
7545
+ * published through the page-surface services. Its published content is what
7546
+ * the draft is compared with, and a page with none has never been published,
7547
+ * so it has no Discard.
7548
+ */
7549
+ function PreviewPageSurfaceController({ common, pageSurfaceId, pageMetadata, values, children }) {
7550
+ const route = {
7551
+ draftTitle: pageMetadata.draftTitle,
7552
+ draftPath: pageMetadata.draftPath
7553
+ };
7554
+ const siteId = common.siteId;
7555
+ return /* @__PURE__ */ jsx(EntryControllerProvider, {
7556
+ ...common,
7557
+ kind: "content",
7558
+ owner: {
7559
+ kind: "pageSurface",
7560
+ pageSurfaceId
7561
+ },
7562
+ services: (client) => createPageSurfaceEditorServices({
7563
+ siteId,
7564
+ pageSurfaceId,
7565
+ route
7566
+ }, { apiClient: client }),
7567
+ initialContent: values.content,
7568
+ initialContentRevision: values.contentRevision,
7569
+ initialPublishedContent: values.publishedContent,
7570
+ children
7571
+ });
7572
+ }
7573
+ function previewLeaseNodeType(pageNodeType, entryData) {
7574
+ if (pageNodeType === "page_surface") return "page_surface";
7575
+ return entryData ? "content_entry" : "page";
7576
+ }
7577
+ /** The blocks a lease grant re-reads, so they reflect the latest server state. */
7578
+ function previewBlocksQueryKey(siteId, pageId, pageNodeType) {
7579
+ return pageNodeType === "page_surface" ? blocksKeys.surfaceSlots(siteId, pageId) : blocksKeys.list(siteId, pageId);
7580
+ }
7581
+ function requiredPreviewLeaseScope(input) {
7582
+ const scope = parseEditLeaseScope(input);
7583
+ if (!scope) throw new Error("Invalid preview editor lease scope");
7584
+ return scope;
7585
+ }
7586
+ //#endregion
7587
+ //#region ../preview-next/src/client/preview/usePreviewKeepAlive.ts
7588
+ const DEFAULT_INTERVAL_MS = 600 * 1e3;
7589
+ function withJitter(baseMs) {
7590
+ const jitter = .1 * baseMs;
7591
+ const delta = (Math.random() * 2 - 1) * jitter;
7592
+ return Math.max(15e3, Math.round(baseMs + delta));
7593
+ }
7594
+ function usePreviewKeepAlive({ enabled, fetcher, onExpired, intervalMs = DEFAULT_INTERVAL_MS }) {
7595
+ useEffect(() => {
7596
+ if (!enabled) return void 0;
7597
+ let isActive = true;
7598
+ async function keepAlive() {
7599
+ try {
7600
+ const response = await fetcher("/api/preview/keep-alive", { method: "POST" }, "keep-alive");
7601
+ if (response.status === 401 && isActive) {
7602
+ onExpired("keep-alive");
7603
+ return;
7604
+ }
7605
+ if (!response.ok && isActive) console.warn("Preview keep-alive failed", await response.text());
7606
+ } catch (error) {
7607
+ if (isActive) console.warn("Preview keep-alive error", error);
7608
+ }
7609
+ }
7610
+ keepAlive();
7611
+ const id = window.setInterval(keepAlive, withJitter(intervalMs));
7612
+ return () => {
7613
+ isActive = false;
7614
+ window.clearInterval(id);
7216
7615
  };
7217
7616
  }, [
7218
7617
  enabled,
@@ -7225,19 +7624,30 @@ function usePreviewKeepAlive({ enabled, fetcher, onExpired, intervalMs = DEFAULT
7225
7624
  //#region ../preview-next/src/client/preview/PreviewKeepAliveClient.tsx
7226
7625
  function PreviewKeepAliveClient({ baseFetch }) {
7227
7626
  const { canEdit } = usePreviewAuth();
7228
- const guardedFetch = usePreviewAuthFetch(baseFetch ?? fetch);
7229
- const { setEditingMode } = useEditor();
7230
7627
  usePreviewKeepAlive({
7231
7628
  enabled: canEdit,
7232
- fetcher: guardedFetch,
7629
+ fetcher: usePreviewAuthFetch(baseFetch ?? fetch),
7233
7630
  onExpired: useCallback((source) => {
7234
7631
  markPreviewAuthExpired(source);
7235
- setEditingMode(false);
7236
- }, [setEditingMode])
7632
+ }, [])
7237
7633
  });
7238
7634
  return null;
7239
7635
  }
7240
7636
  //#endregion
7637
+ //#region ../preview-next/src/client/preview/PreviewLeaseEditingMode.tsx
7638
+ /** Derives preview editing permission from the live auth and lease authorities. */
7639
+ function PreviewLeaseEditingMode() {
7640
+ const { canEdit } = usePreviewAuth();
7641
+ const editable = useEditorUiStore((state) => canEditorWrite(state.editability));
7642
+ const { setEditingAllowed } = useEditor();
7643
+ useEffect(() => setEditingAllowed(canEdit && editable), [
7644
+ canEdit,
7645
+ editable,
7646
+ setEditingAllowed
7647
+ ]);
7648
+ return null;
7649
+ }
7650
+ //#endregion
7241
7651
  //#region ../preview-next/src/client/preview/previewSetupGuidance.ts
7242
7652
  function resolvePreviewSetupBannerState(input) {
7243
7653
  if (input.authMode === "onboardingGrant") return input.dashboardUnlocked ? "dashboard_ready" : "awaiting_confirmation";
@@ -7500,25 +7910,25 @@ const INITIAL_ONBOARDING_CONFIRMATION_STATE = {
7500
7910
  resendFeedback: null,
7501
7911
  statusLoadFailed: false
7502
7912
  };
7503
- function isRecord$4(value) {
7913
+ function isRecord$3(value) {
7504
7914
  return value !== null && typeof value === "object";
7505
7915
  }
7506
7916
  function getErrorMessageFromEnvelope(payload, fallback) {
7507
- const error = isRecord$4(payload) ? payload.error : null;
7508
- const message = isRecord$4(error) ? error.message : null;
7917
+ const error = isRecord$3(payload) ? payload.error : null;
7918
+ const message = isRecord$3(error) ? error.message : null;
7509
7919
  return typeof message === "string" && message.trim().length > 0 ? message : fallback;
7510
7920
  }
7511
7921
  function isLaunchReadiness(value) {
7512
- 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");
7922
+ return isRecord$3(value) && Array.isArray(value.requirements) && typeof value.pendingRequiredCount === "number" && typeof value.pendingRecommendedCount === "number" && typeof value.pendingOptionalCount === "number" && isRecord$3(value.goLiveDecision) && (value.goLiveDecision.kind === "allowed" || value.goLiveDecision.kind === "blocked");
7513
7923
  }
7514
7924
  function isOnboardingPreviewStatusResponse(value) {
7515
- return isRecord$4(value) && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
7925
+ return isRecord$3(value) && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
7516
7926
  }
7517
7927
  function isResendOnboardingPreviewConfirmationResponse(value) {
7518
- return isRecord$4(value) && (value.result === "resent" || value.result === "already_confirmed") && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
7928
+ return isRecord$3(value) && (value.result === "resent" || value.result === "already_confirmed") && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
7519
7929
  }
7520
7930
  function getSuccessData(payload, isData) {
7521
- if (!isRecord$4(payload) || payload.success !== true || !isData(payload.data)) return null;
7931
+ if (!isRecord$3(payload) || payload.success !== true || !isData(payload.data)) return null;
7522
7932
  return payload.data;
7523
7933
  }
7524
7934
  function useOnboardingConfirmationCheck(input) {
@@ -7887,6 +8297,36 @@ function PreviewAuthBanner({ dashboardBaseUrl = null, surfaceId }) {
7887
8297
  })] });
7888
8298
  }
7889
8299
  //#endregion
8300
+ //#region ../preview-next/src/client/preview/PreviewAccessBanners.tsx
8301
+ function previewLeaseThing(isEntry, pageNodeType) {
8302
+ if (pageNodeType === "page_surface") return "this event page";
8303
+ return isEntry ? "this entry" : "this page";
8304
+ }
8305
+ function PreviewAccessBanners({ dashboardBaseUrl, surfaceId, isEntry, pageNodeType }) {
8306
+ const { state } = usePreviewAuth();
8307
+ const { requestedEditingMode, setEditingMode } = useEditor();
8308
+ const showDiscardedNotice = useEditorUiStore((editor) => canEditorWrite(editor.editability) && editor.leaseDiscardedChanges);
8309
+ const thing = previewLeaseThing(isEntry, pageNodeType);
8310
+ const active = state !== "expired";
8311
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
8312
+ /* @__PURE__ */ jsx(PreviewAuthBanner, {
8313
+ dashboardBaseUrl,
8314
+ surfaceId
8315
+ }),
8316
+ active && requestedEditingMode ? /* @__PURE__ */ jsx(EditLeaseModal, {
8317
+ thing,
8318
+ onKeepViewing: () => setEditingMode(false)
8319
+ }) : null,
8320
+ active && showDiscardedNotice ? /* @__PURE__ */ jsx(FixedBottomSurface, {
8321
+ variant: "light",
8322
+ width: "centered",
8323
+ offsetCssVar: "--builder-editor-chrome-offset",
8324
+ reserveOffsetCssVar: "--builder-preview-banner-offset",
8325
+ children: /* @__PURE__ */ jsx(EditLeaseDiscardedNotice, { thing })
8326
+ }) : null
8327
+ ] });
8328
+ }
8329
+ //#endregion
7890
8330
  //#region ../preview-next/src/client/preview/sidebarTabPreference.ts
7891
8331
  const STORAGE_KEY = "preview-sidebar-tab";
7892
8332
  function getPreviewSidebarTab() {
@@ -9402,10 +9842,10 @@ function resolveShellThemeRoles(props) {
9402
9842
  }
9403
9843
  const previewContainerResponsiveEnabled = process.env.NEXT_PUBLIC_ENABLE_PREVIEW_CONTAINER_RESPONSIVE !== "false";
9404
9844
  const PreviewEditorSidebar = React.lazy(async () => {
9405
- return { default: (await import("./PreviewEditorSidebar-DtpB3_sS.mjs")).PreviewEditorSidebar };
9845
+ return { default: (await import("./PreviewEditorSidebar-DvEPG3Z2.mjs")).PreviewEditorSidebar };
9406
9846
  });
9407
9847
  const PreviewEditorUI = React.lazy(async () => {
9408
- return { default: (await import("./PreviewEditorUI-DxTLgaHo.mjs")).PreviewEditorUI };
9848
+ return { default: (await import("./PreviewEditorUI-D6eb6fkx.mjs")).PreviewEditorUI };
9409
9849
  });
9410
9850
  const previewPaneContainmentStyle = {
9411
9851
  contain: "layout paint",
@@ -9639,6 +10079,7 @@ function PreviewShellLayout(props) {
9639
10079
  siteId,
9640
10080
  dashboardBaseUrl,
9641
10081
  pageId,
10082
+ pageNodeType: props.pageNodeType,
9642
10083
  entryData,
9643
10084
  contentTypeSchema,
9644
10085
  referenceContentTypeKeys,
@@ -9695,15 +10136,17 @@ function PreviewShellLayout(props) {
9695
10136
  apiClient
9696
10137
  })
9697
10138
  }),
9698
- /* @__PURE__ */ jsx(PreviewAuthBanner, {
10139
+ /* @__PURE__ */ jsx(PreviewAccessBanners, {
9699
10140
  dashboardBaseUrl,
9700
- surfaceId
10141
+ surfaceId,
10142
+ isEntry: Boolean(entryData),
10143
+ pageNodeType: props.pageNodeType
9701
10144
  }),
9702
10145
  /* @__PURE__ */ jsx("div", {
9703
10146
  className: "fixed inset-0 overflow-hidden bg-background",
9704
10147
  children: isOpen ? /* @__PURE__ */ jsx(ResizableSplitPane, {
9705
10148
  left: leftPane,
9706
- right: rightPane,
10149
+ right: /* @__PURE__ */ jsx(EditorWriteSurface, { children: rightPane }),
9707
10150
  defaultSplit: 100 - sidebarWidth,
9708
10151
  minLeftWidth: 400,
9709
10152
  minRightWidth: 320,
@@ -9730,6 +10173,7 @@ function resolveShellLayoutProps(input) {
9730
10173
  siteId: props.siteId,
9731
10174
  dashboardBaseUrl: props.dashboardBaseUrl ?? null,
9732
10175
  pageId: props.pageId,
10176
+ pageNodeType: props.pageNodeType,
9733
10177
  entryData: props.entryData ?? null,
9734
10178
  contentTypeSchema: props.contentTypeSchema,
9735
10179
  referenceContentTypeKeys: props.referenceContentTypeKeys ?? [],
@@ -9778,8 +10222,29 @@ function wrapPreviewSiteFontStorage(children, siteFontStorageUrl) {
9778
10222
  children
9779
10223
  });
9780
10224
  }
10225
+ function PreviewEditorBody({ props, designEditorEnabled, siteStyleAccess }) {
10226
+ const { apiClient } = useEntryEditorController();
10227
+ return /* @__PURE__ */ jsx(PreviewDesignHistoryOrderProvider, { children: /* @__PURE__ */ jsx(PreviewPageDesignEditorStateProvider, {
10228
+ apiClient,
10229
+ siteId: props.siteId,
10230
+ pageId: props.pageId,
10231
+ enabled: designEditorEnabled,
10232
+ children: /* @__PURE__ */ jsxs(MediaEditorProvider, {
10233
+ siteId: props.siteId,
10234
+ apiClient,
10235
+ bearerToken: props.previewToken,
10236
+ supabaseUrl: props.supabaseUrl,
10237
+ mediaAssets: props.mediaAssets,
10238
+ children: [/* @__PURE__ */ jsx(PreviewKeepAliveClient, { baseFetch: props.baseFetch }), wrapPreviewSiteFontStorage(renderShellLayout({
10239
+ props,
10240
+ apiClient,
10241
+ siteStyleAccess
10242
+ }), props.siteFontStorageUrl)]
10243
+ })
10244
+ }) });
10245
+ }
9781
10246
  function PreviewShell(props) {
9782
- const { children, apiBaseUrl, blockApiConfig, siteId, siteSlug, editableId, previewSession, previewToken, dashboardBaseUrl = null, surfaceId, themeId = null, themeSelectionId = null, themeSelectionVersion = null, themeSelectionUpdatedAt = null, themeSelectionButtonStyleSelection = null, themeSelectionHeaderSelection = null, themeSelectionFooterLookId = null, themeSelectionHeaderLogo, pageId, routeId, entryData, contentTypeSchema, referenceContentTypeKeys = [], draftContent, currentTemplate, initialStatus, initialBlocks, pageMetadata, isSiteLaunched, maintenanceModeEnabled, entrySubrouteContext, assistantPanel, sdkConfig, mediaAssets, bookingOfferingPresets, supabaseUrl, designEditorEligibility, hideSiteStyleConfigurator = false, baseFetch, onFooterSaved } = props;
10247
+ const { apiBaseUrl, blockApiConfig, siteId, siteSlug, editableId, previewSession, previewToken, pageId, routeId, entryData, contentTypeSchema, initialStatus, initialBlocks, pageMetadata, designEditorEligibility, hideSiteStyleConfigurator = false } = props;
9783
10248
  const apiClient = useMemo(() => createBearerAPIClient(previewToken, apiBaseUrl), [previewToken, apiBaseUrl]);
9784
10249
  const { designEditorEnabled, siteStyleAccess } = resolveShellAccess({
9785
10250
  previewSession,
@@ -9788,11 +10253,6 @@ function PreviewShell(props) {
9788
10253
  entryData,
9789
10254
  hideSiteStyleConfigurator
9790
10255
  });
9791
- const shellLayout = renderShellLayout({
9792
- props,
9793
- apiClient,
9794
- siteStyleAccess
9795
- });
9796
10256
  return /* @__PURE__ */ jsx(BlockApiProvider, {
9797
10257
  config: blockApiConfig,
9798
10258
  children: /* @__PURE__ */ jsx(PreviewQueryProvider, { children: /* @__PURE__ */ jsx(PreviewAuthInit, {
@@ -9802,32 +10262,31 @@ function PreviewShell(props) {
9802
10262
  siteSlug,
9803
10263
  pageId: editableId,
9804
10264
  children: /* @__PURE__ */ jsx(EditorProvider, {
9805
- initialEditingMode: true,
9806
- children: /* @__PURE__ */ jsx(PreviewEntryControllerProvider, {
10265
+ initialEditingMode: false,
10266
+ initialEditingAllowed: false,
10267
+ children: /* @__PURE__ */ jsxs(PreviewEntryControllerProvider, {
10268
+ blockFieldExtensions: props.sdkConfig?.blockFieldExtensions ?? null,
9807
10269
  siteId,
9808
10270
  pageId,
10271
+ pageNodeType: props.pageNodeType,
9809
10272
  routeId,
9810
10273
  entryData,
9811
10274
  contentTypeSchema,
9812
- draftContent,
9813
10275
  initialStatus,
9814
10276
  initialBlocks,
9815
10277
  pageMetadata,
9816
10278
  apiClient,
9817
- children: /* @__PURE__ */ jsx(PreviewDesignHistoryOrderProvider, { children: /* @__PURE__ */ jsx(PreviewPageDesignEditorStateProvider, {
9818
- apiClient,
9819
- siteId,
9820
- pageId,
9821
- enabled: designEditorEnabled,
9822
- children: /* @__PURE__ */ jsxs(MediaEditorProvider, {
9823
- siteId,
9824
- apiClient,
9825
- bearerToken: previewToken,
9826
- supabaseUrl,
9827
- mediaAssets,
9828
- children: [/* @__PURE__ */ jsx(PreviewKeepAliveClient, { baseFetch }), wrapPreviewSiteFontStorage(shellLayout, props.siteFontStorageUrl)]
9829
- })
9830
- }) })
10279
+ subscribeToLeaseChanges: props.subscribeToLeaseChanges,
10280
+ onLeaseGranted: props.onLeaseGranted,
10281
+ liveDrafts: props.liveDrafts ? {
10282
+ ...props.liveDrafts,
10283
+ previewToken
10284
+ } : void 0,
10285
+ children: [/* @__PURE__ */ jsx(PreviewLeaseEditingMode, {}), /* @__PURE__ */ jsx(PreviewEditorBody, {
10286
+ props,
10287
+ designEditorEnabled,
10288
+ siteStyleAccess
10289
+ })]
9831
10290
  })
9832
10291
  })
9833
10292
  }) })
@@ -9852,11 +10311,11 @@ function resolveShellAccess(input) {
9852
10311
  //#region ../preview-next/src/client/utils/path.ts
9853
10312
  const PATH_SEPARATOR_REGEX = /\./g;
9854
10313
  const BRACKET_ACCESS_REGEX = /\[([^\]]+)\]/g;
9855
- function isRecord$3(value) {
10314
+ function isRecord$2(value) {
9856
10315
  return typeof value === "object" && value !== null && !Array.isArray(value);
9857
10316
  }
9858
10317
  function isPathContainer(value) {
9859
- return Array.isArray(value) || isRecord$3(value);
10318
+ return Array.isArray(value) || isRecord$2(value);
9860
10319
  }
9861
10320
  function createPathContainer(nextIsIndex) {
9862
10321
  return nextIsIndex ? [] : {};
@@ -10028,15 +10487,317 @@ function runtimeFieldsByBlockId(blocks) {
10028
10487
  function applyRuntimeContentDecorationProjection(block, content, projection) {
10029
10488
  const blockId = designBlockIdFromBlockItem(block);
10030
10489
  const fields = blockId ? projection.fieldsByBlockId.get(blockId) : void 0;
10031
- return applyCompiledRuntimeFieldsToContent(isRecord$2(content) ? content : {}, fields);
10490
+ return applyCompiledRuntimeFieldsToContent(isRecord$1(content) ? content : {}, fields);
10032
10491
  }
10033
10492
  function designBlockIdFromBlockItem(block) {
10034
10493
  return typeof block.id === "string" && block.id.length > 0 ? asDesignBlockId(block.id) : null;
10035
10494
  }
10036
- function isRecord$2(value) {
10495
+ function isRecord$1(value) {
10037
10496
  return typeof value === "object" && value !== null && !Array.isArray(value);
10038
10497
  }
10039
10498
  //#endregion
10499
+ //#region ../field-primitives/src/bindings/index.ts
10500
+ const BINDING_TRANSFORMS = {
10501
+ RICHTEXT_FIRST_PARAGRAPH: "richtext.firstParagraph",
10502
+ DATE_FORMAT_SHORT: "date.formatShort",
10503
+ DATE_FORMAT_LONG: "date.formatLong",
10504
+ TEXT_INLINE_TEXT: "text.inlineText"
10505
+ };
10506
+ Object.values(BINDING_TRANSFORMS);
10507
+ //#endregion
10508
+ //#region ../blocks/src/bindings/types.ts
10509
+ /**
10510
+ * Shared types for template binding resolution.
10511
+ *
10512
+ * Used by SDK, site-renderer, and dashboard for resolving
10513
+ * bindings in template blocks to actual content values.
10514
+ */
10515
+ /**
10516
+ * Available transform function names.
10517
+ */
10518
+ const TRANSFORMS = BINDING_TRANSFORMS;
10519
+ const BINDING_SOURCES = [
10520
+ "field",
10521
+ "meta",
10522
+ "literal",
10523
+ "transform",
10524
+ "fallback"
10525
+ ];
10526
+ //#endregion
10527
+ //#region ../blocks/src/bindings/index.ts
10528
+ /**
10529
+ * Resolves a binding map to actual content values.
10530
+ *
10531
+ * Returns only keys whose binding resolved to a non-null, non-undefined value.
10532
+ * To merge resolved bindings over a base content object (the dashboard
10533
+ * template preview's use case), see {@link applyBindingsToContent}.
10534
+ *
10535
+ * @param bindings - Map of field keys to binding descriptors
10536
+ * @param context - Entry data context (fields and meta)
10537
+ * @returns Resolved content object with actual values
10538
+ *
10539
+ * @example
10540
+ * ```typescript
10541
+ * const content = applyBindings(
10542
+ * {
10543
+ * headline: { source: 'meta', path: 'title' },
10544
+ * body: { source: 'field', path: 'content' },
10545
+ * },
10546
+ * {
10547
+ * fields: { content: 'Hello world' },
10548
+ * meta: { title: 'My Post', slug: 'my-post' },
10549
+ * }
10550
+ * );
10551
+ * // Result: { headline: 'My Post', body: 'Hello world' }
10552
+ * ```
10553
+ */
10554
+ function applyBindings(bindings, context) {
10555
+ const result = {};
10556
+ for (const [key, bindingSpec] of Object.entries(bindings)) {
10557
+ if (isBindingDescriptor(bindingSpec)) {
10558
+ const value = resolveBindingValue(bindingSpec, context);
10559
+ if (value !== void 0 && value !== null) setBindingValue(result, key, value);
10560
+ continue;
10561
+ }
10562
+ if (typeof bindingSpec === "string") {
10563
+ const value = resolveBindingValue({
10564
+ source: "field",
10565
+ path: bindingSpec
10566
+ }, context);
10567
+ if (value !== void 0 && value !== null) setBindingValue(result, key, value);
10568
+ continue;
10569
+ }
10570
+ if (isRecord$11(bindingSpec)) {
10571
+ const nested = applyBindings(bindingSpec, context);
10572
+ if (Object.keys(nested).length > 0) setBindingValue(result, key, nested);
10573
+ }
10574
+ }
10575
+ return result;
10576
+ }
10577
+ /**
10578
+ * Resolve a binding map and merge the result over a base content object.
10579
+ *
10580
+ * Use this when a block has *some* hard-coded content (from a template's
10581
+ * `block.content`) and *some* values driven by template bindings against
10582
+ * an entry. The base provides defaults; resolved bindings override them.
10583
+ *
10584
+ * Same null-handling as {@link applyBindings}: keys whose binding resolves
10585
+ * to `null`/`undefined` do NOT overwrite the base. This means "no resolved
10586
+ * value" leaves the base value (or absence) intact, which is the correct
10587
+ * semantic for both the SDK/frontend render paths and the dashboard preview.
10588
+ *
10589
+ * Replaces the dashboard's bespoke `applyBindings` that lived in
10590
+ * `apps/dashboard/src/lib/templates/applyBindings.ts` — its divergent
10591
+ * "always-set-null" behaviour produced the `subheadline: null` regression
10592
+ * documented in Phase 1.
10593
+ *
10594
+ * @example
10595
+ * ```typescript
10596
+ * const content = applyBindingsToContent(
10597
+ * { eyebrow: 'Default eyebrow', headline: 'Default headline' },
10598
+ * { headline: { source: 'meta', path: 'title' } },
10599
+ * { fields: {}, meta: { title: 'Entry title' } },
10600
+ * );
10601
+ * // Result: { eyebrow: 'Default eyebrow', headline: 'Entry title' }
10602
+ * ```
10603
+ */
10604
+ function applyBindingsToContent(baseContent, bindings, context) {
10605
+ return mergeResolvedBindings(baseContent, applyBindings(bindings, context));
10606
+ }
10607
+ function mergeResolvedBindings(base, resolved) {
10608
+ const merged = { ...base };
10609
+ for (const [key, resolvedValue] of Object.entries(resolved)) {
10610
+ const baseValue = merged[key];
10611
+ merged[key] = isRecord$11(baseValue) && isRecord$11(resolvedValue) ? mergeResolvedBindings(baseValue, resolvedValue) : resolvedValue;
10612
+ }
10613
+ return merged;
10614
+ }
10615
+ function setBindingValue(target, path, value) {
10616
+ const segments = path.split(".").map((segment) => segment.trim()).filter(Boolean);
10617
+ if (segments.length === 0) return;
10618
+ const firstSegment = segments[0];
10619
+ if (!firstSegment) return;
10620
+ if (segments.length === 1) {
10621
+ target[firstSegment] = value;
10622
+ return;
10623
+ }
10624
+ const isIndex = (segment) => /^\d+$/.test(segment);
10625
+ let current = target;
10626
+ for (let i = 0; i < segments.length; i++) {
10627
+ const segment = segments[i];
10628
+ if (!segment) return;
10629
+ const last = i === segments.length - 1;
10630
+ const nextSegment = segments[i + 1];
10631
+ if (last) {
10632
+ if (Array.isArray(current) && isIndex(segment)) {
10633
+ current[Number(segment)] = value;
10634
+ return;
10635
+ }
10636
+ if (isRecord$11(current)) current[segment] = value;
10637
+ return;
10638
+ }
10639
+ const nextWantsArray = typeof nextSegment === "string" && isIndex(nextSegment);
10640
+ if (Array.isArray(current) && isIndex(segment)) {
10641
+ const index = Number(segment);
10642
+ const existing = current[index];
10643
+ if (nextWantsArray) {
10644
+ if (!Array.isArray(existing)) current[index] = [];
10645
+ } else if (!isRecord$11(existing)) current[index] = {};
10646
+ current = current[index];
10647
+ continue;
10648
+ }
10649
+ if (isRecord$11(current)) {
10650
+ const existing = current[segment];
10651
+ if (nextWantsArray) {
10652
+ if (!Array.isArray(existing)) current[segment] = [];
10653
+ } else if (!isRecord$11(existing)) current[segment] = {};
10654
+ current = current[segment];
10655
+ continue;
10656
+ }
10657
+ return;
10658
+ }
10659
+ }
10660
+ /**
10661
+ * Resolves a single binding descriptor to its value.
10662
+ */
10663
+ function resolveBindingValue(descriptor, context) {
10664
+ switch (descriptor.source) {
10665
+ case "field": return descriptor.path ? getPath(context.fields, descriptor.path) : void 0;
10666
+ case "meta": return descriptor.path ? getPath(context.meta, descriptor.path) : void 0;
10667
+ case "literal": return descriptor.value;
10668
+ case "transform": {
10669
+ const inputDescriptor = descriptor.input && isBindingDescriptorLike(descriptor.input) ? normalizeBindingInput(descriptor.input) : descriptor.path ? normalizeBindingInput(descriptor.path) : null;
10670
+ const inputValue = inputDescriptor ? resolveBindingValue(inputDescriptor, context) : void 0;
10671
+ return applyTransform(descriptor.transform, inputValue);
10672
+ }
10673
+ case "fallback":
10674
+ for (const option of descriptor.options ?? []) {
10675
+ const normalized = normalizeBindingInput(option);
10676
+ if (!normalized) continue;
10677
+ const value = resolveBindingValue(normalized, context);
10678
+ if (value !== void 0 && value !== null && value !== "") return value;
10679
+ }
10680
+ return null;
10681
+ default: return null;
10682
+ }
10683
+ }
10684
+ /**
10685
+ * Gets a nested path from an object.
10686
+ */
10687
+ function getPath(source, path) {
10688
+ const segments = path.split(".").map((segment) => segment.trim()).filter(Boolean);
10689
+ let current = source;
10690
+ for (const segment of segments) {
10691
+ if (!isRecord$11(current)) return void 0;
10692
+ current = current[segment];
10693
+ }
10694
+ return current;
10695
+ }
10696
+ /**
10697
+ * Applies a transform function to a value.
10698
+ */
10699
+ function applyTransform(name, value) {
10700
+ if (!name) return value;
10701
+ switch (name) {
10702
+ case TRANSFORMS.RICHTEXT_FIRST_PARAGRAPH: return extractFirstParagraph(value);
10703
+ case TRANSFORMS.DATE_FORMAT_SHORT: return formatDate(value, { dateStyle: "medium" });
10704
+ case TRANSFORMS.DATE_FORMAT_LONG: return formatDate(value, {
10705
+ dateStyle: "long",
10706
+ timeStyle: "short"
10707
+ });
10708
+ case TRANSFORMS.TEXT_INLINE_TEXT: return textToInlineText(value);
10709
+ default: return value;
10710
+ }
10711
+ }
10712
+ function textToInlineText(value) {
10713
+ if (typeof value !== "string") return null;
10714
+ return plainTextToInlineText(value);
10715
+ }
10716
+ /**
10717
+ * Extracts the first paragraph text from a TipTap/ProseMirror document.
10718
+ *
10719
+ * Accepts the canonical unwrapped form (`{ type: 'doc', content: [...] }`).
10720
+ */
10721
+ function extractFirstParagraph(value) {
10722
+ if (!isRichTextDoc(value)) return null;
10723
+ for (const node of value.content) {
10724
+ if (!isRecord$11(node)) continue;
10725
+ if (node.type !== "paragraph" || !Array.isArray(node.content)) continue;
10726
+ const text = node.content.filter((item) => item.type === "text").map((item) => typeof item.text === "string" ? item.text : "").join("").trim();
10727
+ if (text.length > 0) return text;
10728
+ }
10729
+ return null;
10730
+ }
10731
+ /**
10732
+ * Formats a date string using Intl.DateTimeFormat.
10733
+ */
10734
+ function formatDate(value, options) {
10735
+ if (typeof value !== "string") return null;
10736
+ const date = new Date(value);
10737
+ if (Number.isNaN(date.getTime())) return null;
10738
+ return new Intl.DateTimeFormat(void 0, options).format(date);
10739
+ }
10740
+ /**
10741
+ * Type guard to check if a value is a valid binding descriptor.
10742
+ */
10743
+ function isBindingDescriptor(value) {
10744
+ if (!isRecord$11(value) || typeof value.source !== "string") return false;
10745
+ if (!BINDING_SOURCES.includes(value.source)) return false;
10746
+ switch (value.source) {
10747
+ case "field":
10748
+ case "meta": return typeof value.path === "string";
10749
+ case "literal": return "value" in value;
10750
+ case "transform": return typeof value.transform === "string" && (value.input === void 0 || isBindingDescriptorLike(value.input)) && (value.path === void 0 || typeof value.path === "string");
10751
+ case "fallback": return Array.isArray(value.options);
10752
+ default: return false;
10753
+ }
10754
+ }
10755
+ /**
10756
+ * Type guard to check if a value is binding-descriptor-like (can be normalized).
10757
+ */
10758
+ function isBindingDescriptorLike(value) {
10759
+ return isBindingDescriptor(value) || typeof value === "string" || isRecord$11(value) && typeof value.source === "string" && typeof value.path === "string";
10760
+ }
10761
+ /**
10762
+ * Normalizes a binding input to a binding descriptor.
10763
+ *
10764
+ * Converts string shorthand to field descriptors and validates
10765
+ * that objects have valid binding source values.
10766
+ */
10767
+ function normalizeBindingInput(value) {
10768
+ if (isBindingDescriptor(value)) return value;
10769
+ if (typeof value === "string") return {
10770
+ source: "field",
10771
+ path: value
10772
+ };
10773
+ return null;
10774
+ }
10775
+ //#endregion
10776
+ //#region ../preview-next/src/client/blocks/previewProjection/entryFieldRebinding.ts
10777
+ /**
10778
+ * Only the entry fields that changed are bound in again: unchanged fields keep
10779
+ * the server's materialised value, which may be richer than the stored one
10780
+ * (media the loaders have hydrated, for instance).
10781
+ */
10782
+ function entryFieldRebindingProjection(changedFields) {
10783
+ return Object.keys(changedFields).length === 0 ? null : {
10784
+ kind: "entry-field-rebinding",
10785
+ source: "entry-draft",
10786
+ changedFields
10787
+ };
10788
+ }
10789
+ /**
10790
+ * Binds the changed entry fields into a block with template bindings. A binding
10791
+ * whose source did not change resolves to nothing and leaves the content as it is.
10792
+ */
10793
+ function applyEntryFieldRebindingProjection(block, content, projection) {
10794
+ if (!isRecord$11(block.bindings)) return content;
10795
+ return applyBindingsToContent(content ?? {}, block.bindings, {
10796
+ fields: { ...projection.changedFields },
10797
+ meta: {}
10798
+ });
10799
+ }
10800
+ //#endregion
10040
10801
  //#region ../preview-next/src/client/blocks/previewProjection/applyPreviewProjections.ts
10041
10802
  function applyPreviewStructureProjections(blockItems, projections) {
10042
10803
  return projections.reduce((current, projection) => {
@@ -10052,6 +10813,7 @@ function applyPreviewContentFieldProjections(blockId, content, projections) {
10052
10813
  }
10053
10814
  function applyPreviewRuntimeContentProjections(block, content, projections) {
10054
10815
  return projections.reduce((current, projection) => {
10816
+ if (projection.kind === "entry-field-rebinding") return applyEntryFieldRebindingProjection(block, current, projection);
10055
10817
  if (projection.kind !== "runtime-content-decoration") return current;
10056
10818
  return applyRuntimeContentDecorationProjection(block, current, projection);
10057
10819
  }, content);
@@ -10060,108 +10822,25 @@ function blockHasPreviewContentFieldProjection(blockId, projections) {
10060
10822
  return projections.some((projection) => projection.kind === "content-field-overrides" && blockHasContentFieldOverrideProjection(blockId, projection));
10061
10823
  }
10062
10824
  //#endregion
10063
- //#region ../preview-next/src/client/blocks/linkedEntryRenderOverlay.ts
10064
- function applyLinkedEntryRenderOverlay(value, overlays) {
10065
- if (overlays.size === 0) return value;
10066
- return overlayValue(value, overlays);
10067
- }
10068
- function applyLinkedEntryRenderOverlayToDataContext(dataContext, overlays) {
10069
- if (!dataContext?.resolvedData || overlays.size === 0) return dataContext;
10070
- const resolvedData = applyLinkedEntryRenderOverlay(dataContext.resolvedData, overlays);
10071
- if (resolvedData === dataContext.resolvedData) return dataContext;
10072
- return {
10073
- ...dataContext,
10074
- resolvedData
10075
- };
10076
- }
10077
- function overlayValue(value, overlays) {
10078
- if (Array.isArray(value)) {
10079
- let changed = false;
10080
- const next = value.map((item) => {
10081
- const overlaid = overlayValue(item, overlays);
10082
- if (overlaid !== item) changed = true;
10083
- return overlaid;
10084
- });
10085
- return changed ? next : value;
10086
- }
10087
- if (!isRecord$1(value)) return value;
10088
- const meta = parseLinkedEntryMeta(value[LINKED_CONTENT_ENTRY_META_KEY]);
10089
- if (meta) {
10090
- const overlay = overlays.get(unsafeAsLinkedContentEntryId(meta.entryId));
10091
- if (overlay) {
10092
- const displayProjections = resolveOverlayDisplayProjections(overlay.content, meta);
10093
- const titleProjection = resolveOverlayTitleProjection({
10094
- currentValue: value,
10095
- content: overlay.content,
10096
- meta,
10097
- displayProjections
10098
- });
10099
- return {
10100
- ...value,
10101
- ...displayProjections,
10102
- ...titleProjection ? { title: titleProjection } : {},
10103
- content: overlay.content,
10104
- optimisticHash: overlay.optimisticHash,
10105
- [LINKED_CONTENT_ENTRY_META_KEY]: {
10106
- ...meta,
10107
- ...titleProjection ? { title: titleProjection } : {},
10108
- optimisticHash: overlay.optimisticHash
10109
- }
10110
- };
10111
- }
10112
- }
10113
- let changed = false;
10114
- const next = {};
10115
- for (const [key, child] of Object.entries(value)) {
10116
- const overlaid = overlayValue(child, overlays);
10117
- if (overlaid !== child) changed = true;
10118
- next[key] = overlaid;
10119
- }
10120
- return changed ? next : value;
10121
- }
10122
- function resolveOverlayDisplayProjections(content, meta) {
10123
- const projections = {};
10124
- for (const source of meta.fieldSources) {
10125
- if (source.kind !== "content-field") continue;
10126
- if (source.displayPath.startsWith("content.")) continue;
10127
- if (source.displayPath.includes(".")) continue;
10128
- if (!(source.fieldPath in content)) continue;
10129
- projections[source.displayPath] = content[source.fieldPath];
10130
- }
10131
- return projections;
10132
- }
10133
- function resolveOverlayTitleProjection(input) {
10134
- const projectedTitle = input.displayProjections.title;
10135
- if (typeof projectedTitle === "string") return projectedTitle;
10136
- if (input.meta.fieldSources.find((source) => source.displayPath === "title")?.kind === "read-only") {
10137
- const currentTitle = input.currentValue.title;
10138
- return typeof currentTitle === "string" ? currentTitle : input.meta.title;
10139
- }
10140
- return resolveOverlayTitle(input.content, input.meta);
10141
- }
10142
- function resolveOverlayTitle(content, meta) {
10143
- const titleField = meta.contentType.titleField;
10144
- if (titleField) {
10145
- const value = content[titleField];
10146
- if (typeof value === "string" && value.trim().length > 0) return value;
10147
- }
10148
- return meta.title;
10149
- }
10150
- function parseLinkedEntryMeta(value) {
10151
- return getLinkedContentEntryMeta({ [LINKED_CONTENT_ENTRY_META_KEY]: value });
10152
- }
10153
- function isRecord$1(value) {
10154
- return typeof value === "object" && value !== null && !Array.isArray(value);
10155
- }
10156
- //#endregion
10157
10825
  //#region ../preview-next/src/client/blocks/composer/mergeDrafts.ts
10158
10826
  const EMPTY_LINKED_ENTRY_OVERLAY = /* @__PURE__ */ new Map();
10827
+ /**
10828
+ * Draft snapshots as the preview renders them: `current` follows the tab's render
10829
+ * source (its own edits, or another tab's live drafts while it only views).
10830
+ */
10159
10831
  function getDraftSnapshots(uiStore) {
10160
- const snapshots = uiStore.getState().drafts.inspect();
10161
- return new Map(snapshots.map((snap) => [snap.id, snap]));
10832
+ const state = uiStore.getState();
10833
+ const source = renderSourceFor(state.editability);
10834
+ return new Map(state.drafts.inspect().map((snap) => [snap.id, {
10835
+ id: snap.id,
10836
+ baseline: snap.sync.baseline.values,
10837
+ current: resolveRenderedValues(source, snap, remoteDraftValues(state.remoteDrafts, {
10838
+ kind: "block",
10839
+ id: snap.id
10840
+ }))
10841
+ }]));
10162
10842
  }
10163
- function mergeBlockWithDraft(block, draftMap, index, projections = [], linkedEntryOverlays = EMPTY_LINKED_ENTRY_OVERLAY) {
10164
- const { draftContentId = null, publishedContentId = null } = block;
10843
+ function mergeBlockWithDraft(block, draftMap, index, projections = [], linkedEntryOverlays = EMPTY_LINKED_ENTRY_OVERLAY, versions = NO_BLOCK_VERSIONS) {
10165
10844
  const id = block.id ?? null;
10166
10845
  const editorBlockId = id ? unsafeAsEditorBlockId(id) : null;
10167
10846
  const snap = editorBlockId ? draftMap.get(editorBlockId) ?? null : null;
@@ -10169,14 +10848,12 @@ function mergeBlockWithDraft(block, draftMap, index, projections = [], linkedEnt
10169
10848
  const baseline = blockBaseline(block, snap);
10170
10849
  return {
10171
10850
  id,
10172
- draftContentId,
10173
- publishedContentId,
10174
10851
  kind: block.kind,
10175
10852
  purpose: "content",
10176
10853
  orderIndex: block.orderIndex ?? index,
10177
- content: renderContent(block, baseline, projections, linkedEntryOverlays),
10178
- draftContent: renderContent(block, draftContent, projections, linkedEntryOverlays),
10179
- publishedContent: block.publishedContent ?? null,
10854
+ content: renderBlockContent(block, baseline, projections, linkedEntryOverlays),
10855
+ draftContent: renderBlockContent(block, draftContent, projections, linkedEntryOverlays),
10856
+ versions,
10180
10857
  bindings: block.bindings ?? null
10181
10858
  };
10182
10859
  }
@@ -10184,19 +10861,18 @@ function readProjectedDraftRenderContent(block, editorBlockId, snap, projections
10184
10861
  return applyPreviewContentFieldProjections(editorBlockId, snap?.current ?? blockBaseline(block, snap), projections);
10185
10862
  }
10186
10863
  function blockBaseline(block, snapshot) {
10187
- return snapshot?.baseline ?? block.content ?? block.publishedContent ?? null;
10864
+ return snapshot?.baseline ?? block.content ?? null;
10188
10865
  }
10189
- function renderContent(block, content, projections, linkedEntryOverlays) {
10866
+ function renderBlockContent(block, content, projections, linkedEntryOverlays = EMPTY_LINKED_ENTRY_OVERLAY) {
10190
10867
  return applyPreviewRuntimeContentProjections(block, applyLinkedEntryRenderOverlay(content, linkedEntryOverlays), projections);
10191
10868
  }
10192
10869
  //#endregion
10193
10870
  //#region ../preview-next/src/client/blocks/composer/transformBlock.ts
10194
10871
  function transformToPageBlock(enriched) {
10195
- const publishedPlacement = readPublishedBlockPlacement(enriched.publishedContentId, enriched.publishedContent);
10196
10872
  return {
10197
10873
  id: enriched.id,
10198
- publishedPlacement,
10199
- contentVersionId: enriched.draftContentId ?? enriched.publishedContentId,
10874
+ publishedPlacement: enriched.versions.publishedPlacement,
10875
+ contentVersionId: selectedContentVersionId(enriched.versions),
10200
10876
  kind: enriched.kind,
10201
10877
  purpose: enriched.purpose,
10202
10878
  content: enriched.content ?? {},
@@ -10233,45 +10909,46 @@ function composePageFromBlocks(args, cacheRef) {
10233
10909
  const { page, blockItems, projections = [], uiStore } = args;
10234
10910
  const draftMap = getDraftSnapshots(uiStore);
10235
10911
  const aiProjections = previewProjectionsFromAiOverlays(uiStore.getState().aiOverlays);
10236
- const linkedEntryOverlays = getLinkedEntryRenderOverlays(uiStore);
10912
+ const entryProjections = entryDraftProjections(uiStore);
10913
+ const linkedEntryOverlays = linkedEntryRenderOverlaysFromStore(uiStore);
10237
10914
  return composePreviewRenderPage({
10238
10915
  page,
10239
10916
  blockItems,
10240
10917
  draftSnapshots: Array.from(draftMap.values()),
10241
- projections: [...aiProjections, ...projections],
10242
- linkedEntryOverlays
10918
+ projections: [
10919
+ ...entryProjections,
10920
+ ...aiProjections,
10921
+ ...projections
10922
+ ],
10923
+ linkedEntryOverlays,
10924
+ blockVersions: uiStore.getState().blockVersions.get
10243
10925
  }, cacheRef);
10244
10926
  }
10245
10927
  function composePreviewRenderPage(args, cacheRef) {
10246
- const { page, blockItems, draftSnapshots, projections, linkedEntryOverlays } = args;
10928
+ const { page, blockItems, draftSnapshots, projections, linkedEntryOverlays, blockVersions } = args;
10247
10929
  if (!page) return page;
10248
10930
  if (!blockItems.length) return {
10249
10931
  ...page,
10250
10932
  blocks: page.blocks.map((block) => ({
10251
10933
  ...block,
10934
+ content: renderBlockContent(block, block.content ?? null, projections, linkedEntryOverlays) ?? void 0,
10935
+ draftContent: block.draftContent ? renderBlockContent(block, block.draftContent, projections, linkedEntryOverlays) : block.draftContent,
10252
10936
  publishedPlacement: null,
10253
10937
  contentVersionId: null
10254
10938
  }))
10255
10939
  };
10256
10940
  const draftMap = draftSnapshotMap(draftSnapshots);
10257
- 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);
10941
+ const renderedBlocks = applyCacheOptimization([...applyPreviewStructureProjections(blockItems, projections).map((block, index) => mergeBlockWithDraft(block, draftMap, index, projections, linkedEntryOverlays, (block.id ? blockVersions(unsafeAsEditorBlockId(block.id)) : null) ?? NO_BLOCK_VERSIONS))].sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0)), cacheRef);
10258
10942
  return {
10259
10943
  ...page,
10260
10944
  blocks: renderedBlocks
10261
10945
  };
10262
10946
  }
10263
- function getLinkedEntryRenderOverlays(uiStore) {
10264
- const linkedEntries = uiStore.getState().linkedEntries.inspect();
10265
- const overlays = /* @__PURE__ */ new Map();
10266
- for (const linkedEntry of linkedEntries) {
10267
- const content = linkedEntry.current ?? linkedEntry.baseline;
10268
- if (!content) continue;
10269
- overlays.set(linkedEntry.meta.entryId, {
10270
- content,
10271
- optimisticHash: linkedEntry.meta.optimisticHash
10272
- });
10273
- }
10274
- return overlays;
10947
+ /** Entry fields changed in the editor (locally or live from another tab) are bound in first. */
10948
+ function entryDraftProjections(uiStore) {
10949
+ const state = uiStore.getState();
10950
+ const projection = entryFieldRebindingProjection(renderedFieldChanges(renderSourceFor(state.editability), state.content?.getSnapshot() ?? null, remoteDraftValues(state.remoteDrafts, { kind: "content" })));
10951
+ return projection ? [projection] : [];
10275
10952
  }
10276
10953
  function draftSnapshotMap(snapshots) {
10277
10954
  return new Map(snapshots.map((snap) => [snap.id, snap]));
@@ -11842,22 +12519,27 @@ function EditablePageRenderer(props) {
11842
12519
  snapshots.map((s) => `${s.id}:${s.version}`).join("|"),
11843
12520
  linkedEntries.map((entry) => `${entry.meta.entryId}:${entry.version}`).join("|"),
11844
12521
  `overlay:${overlayRevision}`,
11845
- `generated-icons:${state.generatedIconAssets?.revision ?? 0}`
12522
+ `generated-icons:${state.generatedIconAssets?.revision ?? 0}`,
12523
+ linkedSaveHandoversVersion(state.linkedSaveHandovers),
12524
+ `block-versions:${state.blockVersions.revision}`
11846
12525
  ].join("|");
11847
12526
  });
11848
- const linkedEntryOverlays = useMemo(() => {
11849
- const overlays = /* @__PURE__ */ new Map();
11850
- for (const linkedEntry of uiStore.getState().linkedEntries.inspect()) {
11851
- const content = linkedEntry.current ?? linkedEntry.baseline;
11852
- if (!content) continue;
11853
- overlays.set(linkedEntry.meta.entryId, {
11854
- content,
11855
- optimisticHash: linkedEntry.meta.optimisticHash
11856
- });
11857
- }
11858
- return overlays;
11859
- }, [uiStore, renderStateVersion]);
11860
- const linkedEntryDataContext = useMemo(() => applyLinkedEntryRenderOverlayToDataContext(pageRendererProps.dataContext, linkedEntryOverlays), [linkedEntryOverlays, pageRendererProps.dataContext]);
12527
+ const remoteDrafts = useEditorUiStore((state) => state.remoteDrafts);
12528
+ const contentSnapshot = useEditorUiStore((state) => state.content.getSnapshot());
12529
+ const renderSource = useEditorUiStore((state) => renderSourceFor(state.editability));
12530
+ const linkedEntryOverlays = useMemo(() => linkedEntryRenderOverlaysFromStore(uiStore), [
12531
+ uiStore,
12532
+ renderStateVersion,
12533
+ remoteDrafts,
12534
+ renderSource
12535
+ ]);
12536
+ const entryDataContext = useMemo(() => withRenderedContentEntry(pageRendererProps.dataContext, resolveRenderedValues(renderSource, contentSnapshot, remoteDraftValues(remoteDrafts, { kind: "content" }))), [
12537
+ contentSnapshot,
12538
+ pageRendererProps.dataContext,
12539
+ remoteDrafts,
12540
+ renderSource
12541
+ ]);
12542
+ const linkedEntryDataContext = useMemo(() => applyLinkedEntryRenderOverlayToDataContext(entryDataContext, linkedEntryOverlays), [linkedEntryOverlays, entryDataContext]);
11861
12543
  const aiProjections = useMemo(() => previewProjectionsFromAiOverlays(uiStore.getState().aiOverlays), [uiStore, renderStateVersion]);
11862
12544
  const previewTheme = pageRendererProps.rendering?.kind === "overrides-only" ? null : pageRendererProps.theme;
11863
12545
  const runtimePreviewSource = useMemo(() => resolveRuntimePreviewSourceForTheme(pageDesignState, previewTheme), [pageDesignState, previewTheme]);
@@ -11878,7 +12560,10 @@ function EditablePageRenderer(props) {
11878
12560
  pageRendererProps.page,
11879
12561
  renderProjections,
11880
12562
  uiStore,
11881
- renderStateVersion
12563
+ renderStateVersion,
12564
+ remoteDrafts,
12565
+ contentSnapshot,
12566
+ renderSource
11882
12567
  ]) ?? {
11883
12568
  name: "",
11884
12569
  path: "",
@@ -11925,7 +12610,7 @@ function EditablePageRenderer(props) {
11925
12610
  blockId,
11926
12611
  children: rendered
11927
12612
  });
11928
- const rawContent = uiStore.getState().drafts.getBlockSnapshot(editorBlockId)?.current ?? block.content ?? {};
12613
+ const rawContent = renderedBlockContent(uiStore, editorBlockId) ?? block.content ?? {};
11929
12614
  const content = applyPreviewRuntimeContentProjections(block, applyPreviewContentFieldProjections(editorBlockId, rawContent, aiProjections) ?? rawContent, renderProjections);
11930
12615
  return /* @__PURE__ */ jsx(EditableBlockProvider, {
11931
12616
  blockId,
@@ -11960,23 +12645,17 @@ function EditablePageRenderer(props) {
11960
12645
  dataContext: linkedEntryDataContext,
11961
12646
  apiClient: blockDataApiClient
11962
12647
  });
11963
- const generatedIconAssetOverlay = useMemo(() => {
11964
- const byBlock = {};
11965
- for (const block of renderPage.blocks) {
11966
- if (!block.id) continue;
11967
- const assets = uiStore.getState().generatedIconAssets?.getForBlock(unsafeAsEditorBlockId(block.id)) ?? [];
11968
- if (assets.length > 0) byBlock[block.id] = assets;
11969
- }
11970
- return byBlock;
11971
- }, [
12648
+ useLinkedSaveHandoverRetention(uiStore, entryDataContext, liveResolvedData);
12649
+ const generatedIconAssetOverlay = useMemo(() => generatedIconAssetsByBlock(uiStore, renderPage.blocks), [
11972
12650
  renderPage.blocks,
11973
12651
  renderStateVersion,
11974
12652
  uiStore
11975
12653
  ]);
11976
- const dataContext = useMemo(() => mergeGeneratedIconAssetsIntoDataContext(mergeResolvedDataContext(linkedEntryDataContext, liveResolvedData), generatedIconAssetOverlay), [
12654
+ const dataContext = useMemo(() => mergeGeneratedIconAssetsIntoDataContext(applyLinkedEntryRenderOverlayToDataContext(mergeResolvedDataContext(linkedEntryDataContext, liveResolvedData), linkedEntryOverlays), generatedIconAssetOverlay), [
11977
12655
  generatedIconAssetOverlay,
11978
12656
  linkedEntryDataContext,
11979
- liveResolvedData
12657
+ liveResolvedData,
12658
+ linkedEntryOverlays
11980
12659
  ]);
11981
12660
  return /* @__PURE__ */ jsx(EditorPageRenderer, {
11982
12661
  ...pageRendererProps,
@@ -12008,8 +12687,7 @@ function usePreviewBlockResolvedData(args) {
12008
12687
  id: block.id,
12009
12688
  kind: block.kind,
12010
12689
  content: block.content ?? null,
12011
- draftContent: block.draftContent ?? null,
12012
- publishedContent: block.publishedContent ?? null
12690
+ draftContent: block.draftContent ?? null
12013
12691
  }))
12014
12692
  });
12015
12693
  }, [
@@ -12085,15 +12763,13 @@ function buildPreviewBlockDataContext(dataContext) {
12085
12763
  }
12086
12764
  };
12087
12765
  }
12088
- function mergeResolvedDataContext(dataContext, liveResolvedData) {
12089
- if (!dataContext || !liveResolvedData) return dataContext;
12090
- return {
12091
- ...dataContext,
12092
- resolvedData: {
12093
- ...dataContext.resolvedData ?? {},
12094
- ...liveResolvedData
12095
- }
12096
- };
12766
+ /** Each rendered block's generated icon assets, for blocks that have any. */
12767
+ function generatedIconAssetsByBlock(uiStore, blocks) {
12768
+ const assets = uiStore.getState().generatedIconAssets;
12769
+ return Object.fromEntries(blocks.flatMap((block) => {
12770
+ const forBlock = block.id ? assets?.getForBlock(unsafeAsEditorBlockId(block.id)) ?? [] : [];
12771
+ return block.id && forBlock.length > 0 ? [[block.id, forBlock]] : [];
12772
+ }));
12097
12773
  }
12098
12774
  function createPreviewBlockDataApiClient(dashboardApiClient, context) {
12099
12775
  const batcher = createMicrobatcher({
@@ -12229,20 +12905,22 @@ var SdkPreviewModeRuntime_exports = /* @__PURE__ */ __exportAll({ SdkPreviewMode
12229
12905
  function isSdkCustomBlockArray(value) {
12230
12906
  return Array.isArray(value);
12231
12907
  }
12908
+ function recordOrNull(value) {
12909
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
12910
+ }
12232
12911
  function toPreviewBlock(block, index) {
12233
- const publishedContent = block.publishedContent;
12234
- return {
12912
+ return toEditorBlockItem({
12235
12913
  id: block.id,
12236
- draftContentId: typeof block.draftContentId === "string" ? block.draftContentId : null,
12237
- publishedContentId: typeof block.publishedContentId === "string" ? block.publishedContentId : null,
12238
12914
  kind: block.kind,
12239
12915
  purpose: block.purpose,
12240
12916
  orderIndex: index,
12241
12917
  content: block.content ?? null,
12242
12918
  draftContent: block.draftContent ?? null,
12243
- publishedContent: publishedContent && typeof publishedContent === "object" && !Array.isArray(publishedContent) ? publishedContent : null,
12244
- bindings: block.bindings ?? null
12245
- };
12919
+ bindings: block.bindings ?? null,
12920
+ draftContentId: typeof block.draftContentId === "string" ? block.draftContentId : null,
12921
+ publishedContentId: typeof block.publishedContentId === "string" ? block.publishedContentId : null,
12922
+ publishedContent: recordOrNull(block.publishedContent)
12923
+ });
12246
12924
  }
12247
12925
  function getSdkConfigForPreview(value) {
12248
12926
  if (!value || typeof value !== "object") return null;