@riverbankcms/sdk 0.139.0 → 0.140.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 (196) hide show
  1. package/README.md +1 -1
  2. package/dist/{PreviewEditorSidebar-BDeenhi3.mjs → PreviewEditorSidebar-CUyTzd5z.mjs} +4 -4
  3. package/dist/{PreviewEditorUI-DSRhgjF5.mjs → PreviewEditorUI-Agkw4v5i.mjs} +3 -3
  4. package/dist/{PreviewQueryProvider-D2K8GLUG.mjs → PreviewQueryProvider-CN0ewic5.mjs} +1 -1
  5. package/dist/{SdkPreviewModeRuntime-CL7wSnYu.mjs → SdkPreviewModeRuntime-DdbeAdS8.mjs} +22 -8
  6. package/dist/{SiteChromeCustomizeContext-BhDn-5ir.mjs → SiteChromeCustomizeContext-CqGOz-Kv.mjs} +2053 -1110
  7. package/dist/_dts/ai/src/contracts/proposals.d.ts +165 -165
  8. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +212 -212
  9. package/dist/_dts/api/src/accessAdmin.d.ts +74 -104
  10. package/dist/_dts/api/src/aiEndpoints.d.ts +5 -1
  11. package/dist/_dts/api/src/authSubmission.d.ts +46 -0
  12. package/dist/_dts/api/src/billing.d.ts +8 -4
  13. package/dist/_dts/api/src/billingEndpointDefinitions.d.ts +23 -0
  14. package/dist/_dts/api/src/billingEndpointTypes.d.ts +26 -0
  15. package/dist/_dts/api/src/blocks.d.ts +2 -0
  16. package/dist/_dts/api/src/bookingRecords.d.ts +1 -2
  17. package/dist/_dts/api/src/commercePortalEndpoints.d.ts +8 -1
  18. package/dist/_dts/api/src/communications.d.ts +0 -1
  19. package/dist/_dts/api/src/contentRuntime.d.ts +8 -3
  20. package/dist/_dts/api/src/endpoints.d.ts +93 -64
  21. package/dist/_dts/api/src/event-destination-policy.d.ts +2 -1
  22. package/dist/_dts/api/src/footerSettings.d.ts +9 -6
  23. package/dist/_dts/api/src/index.d.ts +5 -6
  24. package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -1
  25. package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -1
  26. package/dist/_dts/api/src/mailingListIntegration.d.ts +8 -2
  27. package/dist/_dts/api/src/navigation/dashboardSettingsNav.d.ts +1 -1
  28. package/dist/_dts/api/src/navigation/types.d.ts +1 -1
  29. package/dist/_dts/api/src/onboarding/confirmationResend.d.ts +25 -0
  30. package/dist/_dts/api/src/onboarding/surfaceData.d.ts +32 -32
  31. package/dist/_dts/api/src/publicBookingAvailabilityEndpointDefinitions.d.ts +8 -0
  32. package/dist/_dts/api/src/publicExperience/commerceEndpoints.d.ts +1 -0
  33. package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +11 -3
  34. package/dist/_dts/api/src/publicExperience/sharedTypes.d.ts +3 -29
  35. package/dist/_dts/api/src/publicOnboardingAttemptEndpointDefinitions.d.ts +65 -0
  36. package/dist/_dts/api/src/saveOutcome.d.ts +20 -0
  37. package/dist/_dts/api/src/sdkContracts.d.ts +3 -22
  38. package/dist/_dts/api/src/sdkPushContracts.d.ts +18 -0
  39. package/dist/_dts/api/src/sdkThemeWire.d.ts +44 -44
  40. package/dist/_dts/api/src/settings/permissions.d.ts +12 -0
  41. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +9 -5
  42. package/dist/_dts/api/src/siteOnboarding.d.ts +2 -9
  43. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +2 -4
  44. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +3 -1
  45. package/dist/_dts/api/src/siteSettings.d.ts +20 -7
  46. package/dist/_dts/api/src/types.d.ts +77 -77
  47. package/dist/_dts/api/src/wholeSeriesRuns.d.ts +2 -37
  48. package/dist/_dts/billing/src/membership/index.d.ts +3 -0
  49. package/dist/_dts/billing/src/plans/types.d.ts +3 -0
  50. package/dist/_dts/billing/src/site-arrangements.d.ts +14 -3
  51. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +16 -4
  52. package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +2 -0
  53. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +5 -0
  54. package/dist/_dts/blocks/src/portal/types.d.ts +2 -4
  55. package/dist/_dts/blocks/src/portal/waitlist-types.d.ts +35 -0
  56. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +2 -0
  57. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +42 -0
  58. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +4 -0
  59. package/dist/_dts/blocks/src/system/data/index.d.ts +2 -2
  60. package/dist/_dts/blocks/src/system/data/prefetchBlockData.d.ts +2 -1
  61. package/dist/_dts/blocks/src/system/data/types.d.ts +9 -0
  62. package/dist/_dts/blocks/src/system/registry.d.ts +1 -0
  63. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +0 -28
  64. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
  65. package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +7 -3
  66. package/dist/_dts/blocks/src/system/runtime/api/types/portal.d.ts +1 -1
  67. package/dist/_dts/blocks/src/system/runtime/api/types/waitlist-claims.d.ts +7 -2
  68. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +30 -6
  69. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +15 -3
  70. package/dist/_dts/blocks/src/system/runtime/nodes/appointment-services.d.ts +43 -0
  71. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +1 -2
  72. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +2 -0
  73. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.d.ts +14 -0
  74. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.d.ts +56 -0
  75. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +6 -8
  76. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.d.ts +8 -0
  77. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +8 -7
  78. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +10 -2
  79. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventSourceRecovery.d.ts +18 -0
  80. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.client.d.ts +1 -1
  81. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +24 -6
  82. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.server.d.ts +4 -2
  83. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +6 -0
  84. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +1 -0
  85. package/dist/_dts/blocks/src/system/runtime/resolver.d.ts +1 -0
  86. package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +2 -6
  87. package/dist/_dts/blocks/src/system/runtime/shared/index.d.ts +2 -2
  88. package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.d.ts +2 -0
  89. package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +4 -0
  90. package/dist/_dts/commerce/src/purchase/orderItemMetadata.d.ts +27 -4
  91. package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +2 -1
  92. package/dist/_dts/content-editor/src/hooks/useBlockAutosave.d.ts +3 -1
  93. package/dist/_dts/content-editor/src/useFooterComposerState.d.ts +3 -0
  94. package/dist/_dts/core/src/branded.d.ts +0 -8
  95. package/dist/_dts/core/src/index.d.ts +1 -0
  96. package/dist/_dts/core/src/mailing-list-setup-parser.d.ts +1 -1
  97. package/dist/_dts/core/src/mailing-list-setup.d.ts +14 -1
  98. package/dist/_dts/core/src/mailing-list-submission.d.ts +7 -27
  99. package/dist/_dts/core/src/participants.d.ts +2 -29
  100. package/dist/_dts/core/src/public-experience.d.ts +4 -0
  101. package/dist/_dts/core/src/public-profile.d.ts +27 -1
  102. package/dist/_dts/core/src/site-route-target.d.ts +9 -2
  103. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +293 -606
  104. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/MailingListGlobalSettingsSummary.d.ts +10 -0
  105. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/MailingListTargetingField.d.ts +3 -2
  106. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/context.d.ts +3 -2
  107. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/loaders.d.ts +3 -2
  108. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/targetingState.d.ts +19 -0
  109. package/dist/_dts/sdk/src/public-api/contracts.d.ts +14 -20
  110. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +2 -0
  111. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +2 -0
  112. package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +7 -1
  113. package/dist/_dts/sdk/src/rendering/helpers/templateContent.d.ts +1 -0
  114. package/dist/_dts/sdk/src/version.d.ts +1 -1
  115. package/dist/_dts/theme-core/src/accordions/types.d.ts +3 -3
  116. package/dist/_dts/theme-core/src/cards/types.d.ts +21 -21
  117. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  118. package/dist/_dts/theme-core/src/header/interactionPalette.d.ts +8 -2
  119. package/dist/_dts/theme-core/src/header/legacyHeaderVariant.d.ts +2 -2
  120. package/dist/_dts/theme-core/src/inputs/types.d.ts +2 -2
  121. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +54 -54
  122. package/dist/_dts/theme-core/src/runtime/buildThemeRuntimeFromBridge.d.ts +1 -4
  123. package/dist/_dts/theme-core/src/schema.d.ts +84 -84
  124. package/dist/_dts/theme-core/src/shared/componentStyles.d.ts +1 -1
  125. package/dist/_dts/theme-core/src/site-styles/backgroundAppearance.d.ts +2 -2
  126. package/dist/_dts/theme-core/src/surfaces/foregroundInteraction.d.ts +77 -0
  127. package/dist/_dts/theme-core/src/surfaces/index.d.ts +1 -0
  128. package/dist/_dts/theme-core/src/typography/generateTypographyCss.d.ts +2 -2
  129. package/dist/_dts/ui/src/lib/use-delayed-flag.d.ts +9 -0
  130. package/dist/_dts/ui/src/pending-button.d.ts +10 -0
  131. package/dist/client/{BookingConsentAgreement-CZvTDtsK.mjs → BookingConsentAgreement-CuKa82V4.mjs} +4 -4
  132. package/dist/client/{DiscountCodeDisclosure-D-DsLCMU.mjs → DiscountCodeDisclosure-BbYieKWB.mjs} +1 -1
  133. package/dist/client/{EventCombined.client-dWqgd5ZO.mjs → EventCombined.client-LTfR1Aby.mjs} +6 -6
  134. package/dist/client/{EventListing.client-BMRa9IYp.mjs → EventListing.client-DUHpYSuo.mjs} +2 -2
  135. package/dist/client/{LeafletStaticMap-D21W9kBZ.mjs → LeafletStaticMap-CHRupL6m.mjs} +1 -1
  136. package/dist/client/{accordion-FxF_ta47.mjs → accordion-6HiIFxNL.mjs} +1 -1
  137. package/dist/client/{bookingForm-YnwW4TGw.mjs → bookingForm-Dlmid43H.mjs} +7 -7
  138. package/dist/client/bookings.mjs +325 -140
  139. package/dist/client/{carousel-vng7fFT5.mjs → carousel-DmkZRRq_.mjs} +2 -2
  140. package/dist/client/{carousel.client-59G_WMr4.mjs → carousel.client-DQTjCVQT.mjs} +1 -1
  141. package/dist/client/{cart-DEPDsjNk.mjs → cart-CIC24330.mjs} +3 -3
  142. package/dist/client/{checkout-CZRWu9rW.mjs → checkout-D1Zw9imo.mjs} +3 -3
  143. package/dist/client/{checkoutUrls-BuseL0dw.mjs → checkoutUrls-FL6lRkrt.mjs} +1 -1
  144. package/dist/client/client.mjs +1717 -882
  145. package/dist/client/{colorStyles-CrxJrPjJ.mjs → colorStyles-3013aRAY.mjs} +3 -1
  146. package/dist/client/{context-DvU_WUmd.mjs → context-Cy1OayHx.mjs} +6 -19
  147. package/dist/client/{dates-wnPMiRl5.mjs → dates-aDcfoLHr.mjs} +2 -2
  148. package/dist/client/{eventCalendar-BA3Q5L15.mjs → eventCalendar-FQxMPAjf.mjs} +8 -8
  149. package/dist/client/{eventCombined-51wgR-1R.mjs → eventCombined-Dr3ac6Hb.mjs} +3 -3
  150. package/dist/client/{eventDetails-modaetpm.mjs → eventDetails-D-AzUHFQ.mjs} +4 -4
  151. package/dist/client/{eventListing-D8t2J3Kv.mjs → eventListing-B3XxBf3i.mjs} +3 -3
  152. package/dist/client/{eventRegistration-CYqtkCE_.mjs → eventRegistration-I6EaokFD.mjs} +500 -152
  153. package/dist/client/{form-CBKXN5In.mjs → form-BbWckVWY.mjs} +3 -3
  154. package/dist/client/{headerSection-DylDqNrs.mjs → headerSection-C9qU4Y7x.mjs} +2 -2
  155. package/dist/client/hooks.mjs +445 -180
  156. package/dist/client/{locationMap-CvWrG0vZ.mjs → locationMap-CLCShvlG.mjs} +3 -3
  157. package/dist/client/{media-BOHuueS5.mjs → media-DHpfFwd3.mjs} +1 -1
  158. package/dist/client/{newsletterForm-Btwk70zw.mjs → newsletterForm-Briukxzi.mjs} +130 -87
  159. package/dist/client/{pricing-Uzw-GQ6Y.mjs → pricing-Copadu-2.mjs} +1 -1
  160. package/dist/client/{productDetail-JLcUYKnd.mjs → productDetail-oujlRd-r.mjs} +3 -3
  161. package/dist/client/{productList-FM0cbUzj.mjs → productList-BRiIRUcd.mjs} +3 -3
  162. package/dist/client/{propsDecoder-DYzafZb2.mjs → propsDecoder-CB2KS_ko.mjs} +130 -24
  163. package/dist/client/rendering/client.mjs +911 -400
  164. package/dist/client/rendering/islands.mjs +19 -19
  165. package/dist/client/rendering.mjs +1696 -818
  166. package/dist/client/{scrollToBlock-CvXszexS.mjs → scrollToBlock-B1IS1_ua.mjs} +1 -1
  167. package/dist/client/{shop-BIcjvy5a.mjs → shop-Vn6yNFED.mjs} +6 -6
  168. package/dist/client/{shop-commerce-BZQsy7xw.mjs → shop-commerce-BVTqipYp.mjs} +7 -7
  169. package/dist/client/{shop-commerce-store-D5V7XAb5.mjs → shop-commerce-store-BVnJVy7v.mjs} +1 -1
  170. package/dist/client/{shopShared-DowkXevB.mjs → shopShared-COIeK77T.mjs} +4 -4
  171. package/dist/client/{useEventFilters-oMoTw_JE.mjs → useEventFilters-DzIUcS9n.mjs} +7 -7
  172. package/dist/preview-next/before-render.mjs +119 -64
  173. package/dist/preview-next/client/runtime.mjs +4 -4
  174. package/dist/preview-next/keepAlive.mjs +119 -64
  175. package/dist/preview-next/middleware.mjs +119 -64
  176. package/dist/{previewAuthStore-COUyAKaX.mjs → previewAuthStore-Gjb6r6vz.mjs} +119 -64
  177. package/dist/{sdk-runtime-D4k2LSGF.mjs → sdk-runtime-CnCLvZRv.mjs} +2 -2
  178. package/dist/{separator-UGtpag4Z.mjs → separator-DKDRJ1oH.mjs} +1 -1
  179. package/dist/server/components.mjs +787 -323
  180. package/dist/server/config-validation.mjs +328 -79
  181. package/dist/server/config.mjs +332 -83
  182. package/dist/server/data.mjs +441 -180
  183. package/dist/server/index.mjs +126 -66
  184. package/dist/server/next.mjs +1031 -595
  185. package/dist/server/page-converter.mjs +183 -74
  186. package/dist/server/prebuild.mjs +1 -1
  187. package/dist/server/rendering/server.mjs +1068 -592
  188. package/dist/server/rendering.mjs +802 -324
  189. package/dist/server/routing.mjs +506 -214
  190. package/dist/server/server.mjs +468 -244
  191. package/dist/server/theme-bridge.mjs +433 -100
  192. package/dist/server/theme.mjs +8 -2
  193. package/dist/styles/index.css +237 -43
  194. package/package.json +1 -1
  195. package/dist/_dts/blocks/src/system/runtime/shared/components/BookingOptionCompactRow.d.ts +0 -29
  196. package/dist/_dts/blocks/src/system/runtime/shared/components/BookingOptionList.d.ts +0 -13
@@ -1,14 +1,14 @@
1
1
  "use client";
2
- import { a as buildBookingPaymentSelectionViewModel, i as usePolling, n as StepIndicator$1, o as resolveBookingPaymentDueNowCents, r as SpinnerNode, s as formatPrice, t as BookingConsentAgreement } from "./BookingConsentAgreement-CZvTDtsK.mjs";
3
- import { C as WIZARD_STEPS, Jt as formatBookingTime, Kt as formatBookingDateTime, Nt as assertNever, O as resolveEventRegistrationScopedEvents, S as resolveRegistrationTarget, T as getWizardStepsForContext, Wt as formatBookingDate, _ as toWholeSeriesRegistrationEvents, at as groupPublicEventsByRun, b as resolveDiscountContext, cn as publicEventPricingOptions, dn as formatCurrencyAmount, en as toBookingTimeZone, fn as parseCurrencyCode, g as toRegistrationEvents, h as getRegistrationStartAt, ln as publicEventPricingStrategy, nn as toScheduledBookingDateTime, on as publicEventPricingCurrency, t as defineIslandPropsDecoder, un as publicEventPricingType, ut as themeButtonClassName, v as findEventByOccurrenceId, w as getStepNumber, x as resolveEventRequiresPayment, y as findPreSelectedEvent } from "./propsDecoder-DYzafZb2.mjs";
4
- import { a as canJoinEventWaitlistOnAnyMode, c as formatTicketTypeRemaining, f as getRemainingPlaces, h as selectMostOpenCapacitySource, i as canJoinEventWaitlist, m as selectEventCapacitySource, o as formatEventRemainingPlaces, p as isEventFull, r as formatEventPriceDisplay, s as formatRemainingPlaces, u as getEventAvailability } from "./pricing-Uzw-GQ6Y.mjs";
5
- import { n as useBlockApi, r as BlockApiError, t as BlockApiProvider } from "./context-DvU_WUmd.mjs";
2
+ import { a as buildBookingPaymentSelectionViewModel, i as usePolling, n as StepIndicator$1, o as resolveBookingPaymentDueNowCents, r as SpinnerNode, s as formatPrice, t as BookingConsentAgreement } from "./BookingConsentAgreement-CuKa82V4.mjs";
3
+ import { C as resolveRegistrationTarget, E as getWizardStepsForContext, Gt as formatBookingDate, Pt as assertNever, S as resolveEventRequiresPayment, T as getStepNumber, Yt as formatBookingTime, _ as toRegistrationEvents, b as findPreSelectedEvent, dn as publicEventPricingType, dt as themeButtonClassName, fn as formatCurrencyAmount, g as getRegistrationStartAt, h as buildEventRegistrationDisplayFromScopedEvents, k as resolveEventRegistrationScopedEvents, ln as publicEventPricingOptions, ot as groupPublicEventsByRun, pn as parseCurrencyCode, qt as formatBookingDateTime, rn as toScheduledBookingDateTime, sn as publicEventPricingCurrency, t as defineIslandPropsDecoder, tn as toBookingTimeZone, un as publicEventPricingStrategy, v as toWholeSeriesRegistrationEvents, w as WIZARD_STEPS, x as resolveDiscountContext, y as findEventByOccurrenceId } from "./propsDecoder-CB2KS_ko.mjs";
4
+ import { a as canJoinEventWaitlistOnAnyMode, c as formatTicketTypeRemaining, f as getRemainingPlaces, h as selectMostOpenCapacitySource, i as canJoinEventWaitlist, m as selectEventCapacitySource, o as formatEventRemainingPlaces, p as isEventFull, r as formatEventPriceDisplay, s as formatRemainingPlaces, u as getEventAvailability } from "./pricing-Copadu-2.mjs";
5
+ import { n as useBlockApi, r as BlockApiError, t as BlockApiProvider } from "./context-Cy1OayHx.mjs";
6
6
  import { n as isSpamProtectionEnabled, r as AltchaWidget, t as getChallengeUrl } from "./src-B833rYRr.mjs";
7
- import { a as CheckIcon, i as StateIcon, n as useDiscountCodeUi, r as TerminalPanel, t as scrollToBlock } from "./scrollToBlock-CvXszexS.mjs";
8
- import { t as DiscountCodeDisclosure } from "./DiscountCodeDisclosure-D-DsLCMU.mjs";
7
+ import { a as CheckIcon, i as StateIcon, n as useDiscountCodeUi, r as TerminalPanel, t as scrollToBlock } from "./scrollToBlock-B1IS1_ua.mjs";
8
+ import { t as DiscountCodeDisclosure } from "./DiscountCodeDisclosure-BbYieKWB.mjs";
9
9
  import { t as FeedbackMessage } from "./FeedbackMessage-CtLvvS_d.mjs";
10
10
  import { n as getFieldValidationControlProps, t as FieldValidationMessage } from "./FieldValidationMessage-AYanWFb-.mjs";
11
- import { t as buildCheckoutReturnUrls } from "./checkoutUrls-BuseL0dw.mjs";
11
+ import { t as buildCheckoutReturnUrls } from "./checkoutUrls-FL6lRkrt.mjs";
12
12
  import { t as createBodyThemePortalRoot } from "./themePortalRoot-AGs4cE7t.mjs";
13
13
  import { n as consumeSearchParams } from "./urlParams-D71VXFGx.mjs";
14
14
  import { t as CrossIcon } from "./CrossIcon-Dn1KRKW5.mjs";
@@ -503,6 +503,90 @@ function missingPaymentSelection() {
503
503
  };
504
504
  }
505
505
  //#endregion
506
+ //#region ../blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.ts
507
+ /** Recovery may select held places; checkout still owns admission and payment validation. */
508
+ function checkoutRecoveryOptionAvailability(availability) {
509
+ if (availability.kind === "available" || availability.reason === "sold_out" || availability.reason === "overallCapacityUnavailable") return {
510
+ kind: "available",
511
+ remainingPlaces: null
512
+ };
513
+ return availability;
514
+ }
515
+ /**
516
+ * A form-only projection for the explicit existing-checkout path. It permits
517
+ * collecting the original selection without claiming a new place is available.
518
+ * The public checkout service identifies the customer and remains the admission
519
+ * authority; no reservation/customer data is exposed through this projection.
520
+ */
521
+ function getCheckoutRecoveryFormEligibility(eligibility) {
522
+ if (!eligibility || eligibility.registration.kind !== "none" && eligibility.registration.kind !== "pending_payment" || eligibility.availability.kind === "unavailable" && eligibility.availability.reason !== "full" && eligibility.availability.reason !== "selectionRequired") return eligibility;
523
+ const amountCents = eligibility.price ?? 0;
524
+ if (amountCents <= 0 || !eligibility.currency || eligibility.availability.kind === "unavailable" && eligibility.availability.reason === "selectionRequired") return eligibility.registration.kind === "pending_payment" ? {
525
+ ...eligibility,
526
+ registration: { kind: "none" },
527
+ ticketTypes: eligibility.ticketTypes.map((option) => ({
528
+ ...option,
529
+ availability: checkoutRecoveryOptionAvailability(option.availability)
530
+ }))
531
+ } : eligibility;
532
+ const currency = eligibility.currency;
533
+ const paymentOptions = eligibility.paymentTerms.allowedOptions.map((option) => {
534
+ switch (option.kind) {
535
+ case "upfront": return {
536
+ kind: "payInFull",
537
+ amountCents,
538
+ currency
539
+ };
540
+ case "deferred_manual": return {
541
+ kind: "deferredManual",
542
+ amountCents,
543
+ currency
544
+ };
545
+ case "instalment_plan": return {
546
+ kind: "instalmentPlan",
547
+ amountCents,
548
+ currency
549
+ };
550
+ case "flexible_balance": return {
551
+ kind: "flexibleBalance",
552
+ amountCents,
553
+ currency
554
+ };
555
+ }
556
+ });
557
+ return {
558
+ ...eligibility,
559
+ registration: { kind: "none" },
560
+ availability: {
561
+ kind: "available",
562
+ remainingPlaces: null,
563
+ waitlistEnabled: eligibility.waitlistEnabled
564
+ },
565
+ eligible: paymentOptions.length > 0,
566
+ isFull: false,
567
+ canJoinWaitlist: false,
568
+ isFree: false,
569
+ requiresPayment: true,
570
+ canPayDirectly: paymentOptions.length > 0,
571
+ paymentOptions,
572
+ eligiblePasses: [],
573
+ eligibleMemberships: [],
574
+ ticketTypes: eligibility.ticketTypes.map((option) => ({
575
+ ...option,
576
+ availability: checkoutRecoveryOptionAvailability(option.availability)
577
+ }))
578
+ };
579
+ }
580
+ function isSoldOutEventSelectable(event, waitlistAvailable) {
581
+ return waitlistAvailable || canRecoverEventCheckout(event);
582
+ }
583
+ function canJoinWaitlistOutsideRecovery(event, attendanceMode, checkoutRecovery) {
584
+ return !checkoutRecovery && event !== null && canJoinEventWaitlist(event, { attendanceMode });
585
+ }
586
+ function canRecoverEventCheckout(event) {
587
+ return event !== null && (event.registrationSubject.kind === "wholeSeries" || event.pricing.kind !== "free" && event.pricing.kind !== "external");
588
+ }
589
+ //#endregion
506
590
  //#region ../blocks/src/system/runtime/nodes/event-registration/utils.ts
507
591
  function getPortalSubjectEmail(profile) {
508
592
  return profile?.email ?? null;
@@ -688,7 +772,7 @@ const EventSelectionStep = ({ events, selectedEvent, onSelect, showVenue, showCa
688
772
  const remaining = getRemainingPlaces(selectMostOpenCapacitySource(event));
689
773
  const isSoldOut = isEventFull(event);
690
774
  const canJoinWaitlist = canJoinEventWaitlistOnAnyMode(event);
691
- const isUnavailable = isSoldOut && !canJoinWaitlist;
775
+ const isUnavailable = isSoldOut && !isSoldOutEventSelectable(event, canJoinWaitlist);
692
776
  const isLowCapacity = remaining.kind === "low";
693
777
  const capacityLabel = formatEventRemainingPlaces(event, { full: "Sold out" });
694
778
  const timeZone = event.timeZone ?? null;
@@ -733,6 +817,33 @@ const EventSelectionStep = ({ events, selectedEvent, onSelect, showVenue, showCa
733
817
  });
734
818
  };
735
819
  //#endregion
820
+ //#region ../blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.ts
821
+ /** Recovery belongs to the selected booking subject; changing events resets its scope. */
822
+ function useCheckoutRecovery(event, setStep) {
823
+ const [recoveryEventId, setRecoveryEventId] = useState(null);
824
+ return {
825
+ checkoutRecovery: event !== null && recoveryEventId === event.selectionId,
826
+ startCheckoutRecovery: useCallback(() => {
827
+ if (!event) return;
828
+ setRecoveryEventId(event.selectionId);
829
+ setStep("select-tickets");
830
+ }, [event, setStep])
831
+ };
832
+ }
833
+ /** Authenticated pending bookings enter the same form-only recovery path as guests. */
834
+ function useCheckoutRecoveryEligibility(eligibility, step, checkoutRecovery, startCheckoutRecovery) {
835
+ const registrationKind = eligibility?.registration.kind;
836
+ useEffect(() => {
837
+ if ((step === "select-event" || step === "select-tickets" || step === "enter-details" || step === "select-payment") && registrationKind === "pending_payment" && !checkoutRecovery) startCheckoutRecovery();
838
+ }, [
839
+ registrationKind,
840
+ step,
841
+ checkoutRecovery,
842
+ startCheckoutRecovery
843
+ ]);
844
+ return useMemo(() => checkoutRecovery ? getCheckoutRecoveryFormEligibility(eligibility) : eligibility, [checkoutRecovery, eligibility]);
845
+ }
846
+ //#endregion
736
847
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.ts
737
848
  function resolveRegistrationRecoveryAction(step, action) {
738
849
  if (step === "payment-failed") return "payment-options";
@@ -1373,6 +1484,10 @@ const eventRegistrationErrors = {
1373
1484
  message: "We’re checking your booking and payment. Please don’t try to book again yet. If you’ve already paid, you don’t need to pay again.",
1374
1485
  action: "payment-status"
1375
1486
  },
1487
+ paymentProviderUnavailable: {
1488
+ message: "We couldn’t reach the payment provider. Please try again in a minute.",
1489
+ action: "retry"
1490
+ },
1376
1491
  paymentPageUnavailable: {
1377
1492
  message: "We couldn’t open the payment page. Please refresh this page and try again. If this keeps happening, contact the organiser for help.",
1378
1493
  action: "retry"
@@ -1495,11 +1610,6 @@ function ensureWaitlistClaimLocationTracking() {
1495
1610
  } catch {}
1496
1611
  window.addEventListener("popstate", emitWaitlistClaimLocationChange);
1497
1612
  }
1498
- function getWaitlistClaimTokenFromUrl() {
1499
- if (typeof window === "undefined") return null;
1500
- const token = new URLSearchParams(window.location.search).get("waitlist_claim")?.trim() ?? "";
1501
- return token.length > 0 ? token : null;
1502
- }
1503
1613
  const useWaitlistClaimDeps = { useBlockApi };
1504
1614
  function subscribeToWaitlistClaimToken(callback) {
1505
1615
  if (typeof window === "undefined") return () => {};
@@ -1509,28 +1619,42 @@ function subscribeToWaitlistClaimToken(callback) {
1509
1619
  window.removeEventListener(WAITLIST_CLAIM_LOCATION_EVENT, callback);
1510
1620
  };
1511
1621
  }
1512
- function getWaitlistClaimTokenSnapshot() {
1513
- return getWaitlistClaimTokenFromUrl();
1622
+ function getWaitlistClaimLocationSnapshot() {
1623
+ return typeof window === "undefined" ? "" : window.location.search;
1624
+ }
1625
+ function parseWaitlistClaimCredential(search) {
1626
+ const params = new URLSearchParams(search);
1627
+ const token = params.get("waitlist_claim")?.trim();
1628
+ if (token) return {
1629
+ kind: "emailedToken",
1630
+ token
1631
+ };
1632
+ const entryId = params.get("waitlistEntry")?.trim();
1633
+ return entryId ? {
1634
+ kind: "portalOwnedEntry",
1635
+ entryId
1636
+ } : null;
1514
1637
  }
1515
1638
  function useWaitlistClaim() {
1516
1639
  return useWaitlistClaimWithDeps(useWaitlistClaimDeps);
1517
1640
  }
1518
1641
  function useWaitlistClaimWithDeps(deps) {
1519
- return useResolvedWaitlistClaim(deps, useSyncExternalStore(subscribeToWaitlistClaimToken, getWaitlistClaimTokenSnapshot, () => null));
1642
+ const locationSearch = useSyncExternalStore(subscribeToWaitlistClaimToken, getWaitlistClaimLocationSnapshot, () => "");
1643
+ return useResolvedWaitlistClaim(deps, useMemo(() => parseWaitlistClaimCredential(locationSearch), [locationSearch]));
1520
1644
  }
1521
- function useResolvedWaitlistClaim(deps, token) {
1645
+ function useResolvedWaitlistClaim(deps, credential) {
1522
1646
  const api = deps.useBlockApi();
1523
- const [state, dispatch] = useReducer(waitlistClaimReducer, Boolean(token), createInitialWaitlistClaimState);
1647
+ const [state, dispatch] = useReducer(waitlistClaimReducer, Boolean(credential), createInitialWaitlistClaimState);
1524
1648
  useEffect(() => {
1525
1649
  let cancelled = false;
1526
1650
  async function resolveClaim() {
1527
- if (!token) {
1651
+ if (!credential) {
1528
1652
  dispatch({ type: "cleared" });
1529
1653
  return;
1530
1654
  }
1531
1655
  dispatch({ type: "started" });
1532
1656
  try {
1533
- const result = await api.resolveWaitlistClaim({ claimToken: token });
1657
+ const result = credential.kind === "portalOwnedEntry" ? await api.resolveWaitlistClaim({ waitlistEntryId: credential.entryId }) : await api.resolveWaitlistClaim({ claimToken: credential.token });
1534
1658
  if (cancelled) return;
1535
1659
  dispatch({
1536
1660
  type: "resolved",
@@ -1548,9 +1672,10 @@ function useResolvedWaitlistClaim(deps, token) {
1548
1672
  return () => {
1549
1673
  cancelled = true;
1550
1674
  };
1551
- }, [api, token]);
1675
+ }, [api, credential]);
1552
1676
  return {
1553
- token,
1677
+ token: credential?.kind === "emailedToken" ? credential.token : null,
1678
+ entryId: credential?.kind === "portalOwnedEntry" ? credential.entryId : null,
1554
1679
  claim: getWaitlistClaim(state),
1555
1680
  error: getWaitlistClaimError(state),
1556
1681
  loginMessage: getWaitlistClaimLoginMessage(state),
@@ -2032,15 +2157,12 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
2032
2157
  * landed — a success, or a hand-off to checkout — because until then nobody
2033
2158
  * knows whether the first one committed.
2034
2159
  *
2035
- * Reusing it after a failure is safe even if the customer edits their
2036
- * details. The server consults the command record before it re-checks
2037
- * anything, so a submission that already booked is answered with the booking
2038
- * that exists — not refused for spending a credit or a claim that this very
2039
- * command already spent, and not treated as a second booking because a name
2040
- * or a note changed in between.
2160
+ * Identical retries retain the command after a lost response. Changed form
2161
+ * details get a new command so the server applies the new booking intent.
2041
2162
  */
2042
- const commandIdRef = useRef(null);
2043
- return async (method, passId, membershipId, selection, submitOptions) => {
2163
+ const commandRef = useRef(null);
2164
+ const inFlightRef = useRef(null);
2165
+ const submit = async (method, passId, membershipId, selection, submitOptions) => {
2044
2166
  const target = options.registrationTarget;
2045
2167
  if (!target) return {
2046
2168
  ok: false,
@@ -2048,44 +2170,34 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
2048
2170
  message: "Select an event to continue."
2049
2171
  };
2050
2172
  options.setStep("submitting");
2051
- const registrationCommandId = commandIdRef.current ?? deps.createClientCommandId();
2052
- commandIdRef.current = registrationCommandId;
2173
+ const registrationCommandId = commandRef.current?.id ?? deps.createClientCommandId();
2053
2174
  try {
2054
- const prepared = prepareSubmitContext(options, registrationCommandId, target, method, passId, membershipId, selection);
2175
+ let prepared = prepareSubmitContext(options, registrationCommandId, target, method, passId, membershipId, selection);
2055
2176
  if (prepared.subject.kind === "wholeSeries" && method === "stripe") {
2056
- commandIdRef.current = null;
2177
+ commandRef.current = null;
2057
2178
  return await submitWholeSeriesCheckout(options, deps, {
2058
2179
  ...prepared,
2059
2180
  subject: prepared.subject
2060
2181
  }, submitOptions);
2061
2182
  }
2183
+ const request = buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId);
2184
+ const intentKey = registrationRequestIntentKey(request);
2185
+ if (commandRef.current !== null && commandRef.current.intentKey !== intentKey) prepared = {
2186
+ ...prepared,
2187
+ registrationCommandId: deps.createClientCommandId()
2188
+ };
2189
+ commandRef.current = {
2190
+ id: prepared.registrationCommandId,
2191
+ intentKey
2192
+ };
2062
2193
  const result = await options.api.registerForEvent({
2063
- registrationCommandId: prepared.registrationCommandId,
2064
- subject: prepared.subject,
2065
- ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
2066
- selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
2067
- email: options.formData.email.trim().toLowerCase(),
2068
- name: options.formData.name.trim(),
2069
- phone: options.formData.phone.trim() || void 0,
2070
- notes: options.formData.notes.trim() || void 0,
2071
- consentAccepted: options.formData.consentAccepted,
2072
- altchaSolution: options.altchaSolution,
2073
- paymentMethod: method,
2074
- customerPassId: method === "pass" ? passId : void 0,
2075
- customerMembershipId: method === "membership" ? membershipId : void 0,
2076
- bundleProductId: prepared.bundleProductId,
2077
- claimToken: options.claimToken ?? void 0,
2078
- guests: prepared.guestsPayload
2194
+ ...request,
2195
+ registrationCommandId: prepared.registrationCommandId
2079
2196
  });
2080
- commandIdRef.current = null;
2081
- if (needsOccurrenceCheckout(result, method)) return await submitOccurrenceCheckout(options, deps, prepared, result, method, submitOptions);
2082
- options.setRegistrationResult(toRegistrationResult(result));
2083
- options.setStep("success");
2084
- return {
2085
- ok: true,
2086
- outcome: { kind: "completed" }
2087
- };
2197
+ commandRef.current = null;
2198
+ return await completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions);
2088
2199
  } catch (error) {
2200
+ if (error instanceof BlockApiError && error.tag === "registrationPreparationChanged") commandRef.current = null;
2089
2201
  const { message, action } = registrationErrorPresentation(error);
2090
2202
  options.setErrorAction?.(action);
2091
2203
  options.setErrorMessage(message);
@@ -2097,6 +2209,24 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
2097
2209
  };
2098
2210
  }
2099
2211
  };
2212
+ return (...args) => {
2213
+ if (inFlightRef.current) return inFlightRef.current;
2214
+ const pending = Promise.resolve().then(() => submit(...args));
2215
+ inFlightRef.current = pending;
2216
+ pending.finally(() => {
2217
+ if (inFlightRef.current === pending) inFlightRef.current = null;
2218
+ });
2219
+ return pending;
2220
+ };
2221
+ }
2222
+ async function completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions) {
2223
+ if (needsOccurrenceCheckout(result, method)) return await submitOccurrenceCheckout(options, deps, prepared, result, method, submitOptions);
2224
+ options.setRegistrationResult(toRegistrationResult(result));
2225
+ options.setStep("success");
2226
+ return {
2227
+ ok: true,
2228
+ outcome: { kind: "completed" }
2229
+ };
2100
2230
  }
2101
2231
  function toTicketSelectionRequests(lines) {
2102
2232
  return lines.map((line) => ({
@@ -2171,6 +2301,7 @@ async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions)
2171
2301
  altchaSolution: options.altchaSolution,
2172
2302
  guests: prepared.guestsPayload,
2173
2303
  claimToken: options.claimToken ?? void 0,
2304
+ waitlistEntryId: options.waitlistEntryId ?? void 0,
2174
2305
  discountCode: options.discountCode.trim() || void 0,
2175
2306
  collectionOptionKind: prepared.selectionSnapshot.collectionOptionKind,
2176
2307
  checkoutAttemptId,
@@ -2192,14 +2323,14 @@ async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions)
2192
2323
  }
2193
2324
  if (result.bypassed) return completeBypassedCheckout(options);
2194
2325
  if (!result.checkoutUrl) throw new Error("Checkout URL missing");
2195
- savePendingCheckout(options, deps, prepared, checkoutAttemptId, {
2326
+ savePendingCheckout(options, deps, prepared, result.checkoutAttemptId, {
2196
2327
  scope: "wholeSeries",
2197
2328
  registrationId: result.registrationId
2198
2329
  });
2199
2330
  return redirectToCheckout(result.checkoutUrl, submitOptions);
2200
2331
  }
2201
2332
  function needsOccurrenceCheckout(result, method) {
2202
- return result.scope === "occurrence" && !result.alreadyRegistered && result.status === "confirmed" && result.pendingPayment && [
2333
+ return result.scope === "occurrence" && result.status === "confirmed" && result.pendingPayment && [
2203
2334
  "stripe",
2204
2335
  "pass_bundle",
2205
2336
  "membership_bundle"
@@ -2219,6 +2350,7 @@ async function submitOccurrenceCheckout(options, deps, prepared, registration, m
2219
2350
  kind: "occurrence",
2220
2351
  attendeeId: registration.attendeeId
2221
2352
  },
2353
+ registrationCommandId: prepared.registrationCommandId,
2222
2354
  checkoutType: method === "pass_bundle" ? "pass_bundle" : method === "membership_bundle" ? "membership_bundle" : "event",
2223
2355
  productId: prepared.bundleProductId,
2224
2356
  discountCode: options.discountCode.trim() || void 0,
@@ -2261,6 +2393,31 @@ function redirectToCheckout(checkoutUrl, submitOptions) {
2261
2393
  }
2262
2394
  };
2263
2395
  }
2396
+ function registrationRequestIntentKey(request) {
2397
+ const { registrationCommandId: _command, altchaSolution: _proof, ...intent } = request;
2398
+ return JSON.stringify(intent);
2399
+ }
2400
+ function buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId) {
2401
+ return {
2402
+ registrationCommandId: prepared.registrationCommandId,
2403
+ subject: prepared.subject,
2404
+ ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
2405
+ selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
2406
+ email: options.formData.email.trim().toLowerCase(),
2407
+ name: options.formData.name.trim(),
2408
+ phone: options.formData.phone.trim() || void 0,
2409
+ notes: options.formData.notes.trim() || void 0,
2410
+ consentAccepted: options.formData.consentAccepted,
2411
+ altchaSolution: options.altchaSolution,
2412
+ paymentMethod: method,
2413
+ customerPassId: method === "pass" ? passId : void 0,
2414
+ customerMembershipId: method === "membership" ? membershipId : void 0,
2415
+ bundleProductId: prepared.bundleProductId,
2416
+ claimToken: options.claimToken ?? void 0,
2417
+ waitlistEntryId: options.waitlistEntryId ?? void 0,
2418
+ guests: prepared.guestsPayload
2419
+ };
2420
+ }
2264
2421
  //#endregion
2265
2422
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationWizardContext.ts
2266
2423
  function getEventSelectionDefaults(event) {
@@ -2499,14 +2656,28 @@ function useEventRegistrationWizardWithDeps(options, deps) {
2499
2656
  }), [options.occurrenceContext, selectedEvent]);
2500
2657
  const registrationOccurrenceId = getRegistrationOccurrenceId(registrationTarget);
2501
2658
  const currentEvent = selectedEvent ?? preSelectedEvent;
2659
+ const setStep = useCallback((nextStep) => {
2660
+ dispatchFlow({
2661
+ type: "set-step",
2662
+ step: nextStep
2663
+ });
2664
+ }, []);
2665
+ const { checkoutRecovery, startCheckoutRecovery } = useCheckoutRecovery(currentEvent, setStep);
2502
2666
  const currentEventUsesTicketTypes = usesTieredPricing(currentEvent);
2503
- const currentCanJoinWaitlist = currentEvent ? canJoinEventWaitlist(currentEvent, { attendanceMode: selectedAttendanceMode }) : false;
2667
+ const currentCanJoinWaitlist = canJoinWaitlistOutsideRecovery(currentEvent, selectedAttendanceMode, checkoutRecovery);
2504
2668
  const usesTicketTypeSelections = currentEventUsesTicketTypes && !currentCanJoinWaitlist;
2505
2669
  const eventTicketTypesForSelection = useMemo(() => getVisibleTicketTypes({
2506
2670
  event: currentEvent,
2507
2671
  eligibility: null,
2508
2672
  selectedAttendanceMode
2509
- }), [currentEvent, selectedAttendanceMode]);
2673
+ }).map((option) => checkoutRecovery ? {
2674
+ ...option,
2675
+ availability: checkoutRecoveryOptionAvailability(option.availability)
2676
+ } : option), [
2677
+ currentEvent,
2678
+ selectedAttendanceMode,
2679
+ checkoutRecovery
2680
+ ]);
2510
2681
  const normalizedSelectedTicketLines = useMemo(() => normalizeTicketSelectionLines(selectedTicketLines), [selectedTicketLines]);
2511
2682
  const ticketTypeSelectionTotal = useMemo(() => getTicketSelectionTotal(normalizedSelectedTicketLines), [normalizedSelectedTicketLines]);
2512
2683
  const ticketsCount = usesTicketTypeSelections ? ticketTypeSelectionTotal : flowState.ticketsCount;
@@ -2544,17 +2715,11 @@ function useEventRegistrationWizardWithDeps(options, deps) {
2544
2715
  isAuthenticated: portalAuthState === "authenticated",
2545
2716
  occurrenceId: registrationOccurrenceId
2546
2717
  });
2547
- const eligibility = eligibilityResult.eligibility;
2718
+ const eligibility = useCheckoutRecoveryEligibility(eligibilityResult.eligibility, step, checkoutRecovery, startCheckoutRecovery);
2548
2719
  const eligibilityLoading = eligibilityResult.isLoading;
2549
2720
  const eligibilityError = eligibilityResult.error;
2550
2721
  const portalCreditState = eligibilityResult.creditState;
2551
2722
  const registrationState = eligibility?.registration ?? { kind: "none" };
2552
- const setStep = useCallback((nextStep) => {
2553
- dispatchFlow({
2554
- type: "set-step",
2555
- step: nextStep
2556
- });
2557
- }, []);
2558
2723
  const setTicketsCount = useCallback((nextTicketsCount) => {
2559
2724
  dispatchFlow({
2560
2725
  type: "set-tickets-count",
@@ -2662,10 +2827,14 @@ function useEventRegistrationWizardWithDeps(options, deps) {
2662
2827
  event: currentEvent,
2663
2828
  eligibility,
2664
2829
  selectedAttendanceMode
2665
- }), [
2830
+ }).map((option) => checkoutRecovery ? {
2831
+ ...option,
2832
+ availability: checkoutRecoveryOptionAvailability(option.availability)
2833
+ } : option), [
2666
2834
  currentEvent,
2667
2835
  selectedAttendanceMode,
2668
- eligibility
2836
+ eligibility,
2837
+ checkoutRecovery
2669
2838
  ]);
2670
2839
  const singleSelectedPricingOptionId = getSingleSelectedPricingOptionId(normalizedSelectedTicketLines);
2671
2840
  const selectedTicketType = useMemo(() => findSelectedTicketType({
@@ -2689,8 +2858,12 @@ function useEventRegistrationWizardWithDeps(options, deps) {
2689
2858
  const event = currentEvent;
2690
2859
  if (!usesTieredPricing(event)) return false;
2691
2860
  if ((event.deliveryMode ?? "in_person") === "hybrid" && !selectedAttendanceMode) return false;
2692
- return !canJoinEventWaitlist(event, { attendanceMode: selectedAttendanceMode });
2693
- }, [currentEvent, selectedAttendanceMode]);
2861
+ return checkoutRecovery || !canJoinEventWaitlist(event, { attendanceMode: selectedAttendanceMode });
2862
+ }, [
2863
+ currentEvent,
2864
+ selectedAttendanceMode,
2865
+ checkoutRecovery
2866
+ ]);
2694
2867
  const hasValidTicketSelection = hasValidPricingOptionSelection({
2695
2868
  selectionRequired: ticketTypeSelectionRequired,
2696
2869
  lines: normalizedSelectedTicketLines,
@@ -2894,6 +3067,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
2894
3067
  guests,
2895
3068
  discountCode: discountUi.discountCode,
2896
3069
  claimToken: waitlistClaim.token,
3070
+ waitlistEntryId: waitlistClaim.entryId,
2897
3071
  setPendingRegistrationReference,
2898
3072
  setStep,
2899
3073
  setRegistrationResult: (result) => setRegistrationResult(result),
@@ -2956,6 +3130,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
2956
3130
  scopedEvents,
2957
3131
  preSelectedEvent,
2958
3132
  hasPreSelectedContext,
3133
+ checkoutRecovery,
3134
+ startCheckoutRecovery,
2959
3135
  step,
2960
3136
  setStep,
2961
3137
  selectedEvent,
@@ -3159,6 +3335,51 @@ function getMagicLinkErrorMessage(error) {
3159
3335
  return error instanceof Error ? error.message : "Failed to send. Please try again.";
3160
3336
  }
3161
3337
  //#endregion
3338
+ //#region ../blocks/src/system/runtime/nodes/event-registration/ErrorStep.tsx
3339
+ /**
3340
+ * Error Step
3341
+ *
3342
+ * Displays an error message with a retry button when registration fails.
3343
+ */
3344
+ const labels = {
3345
+ none: "",
3346
+ retry: "Try again",
3347
+ places: "Choose places",
3348
+ start: "Start again",
3349
+ details: "Check my details",
3350
+ "payment-options": "View payment options",
3351
+ "payment-status": "Check payment status",
3352
+ portal: "View my bookings",
3353
+ event: "View event"
3354
+ };
3355
+ const ErrorStep = ({ message, onRetry, action = "retry", canJoinWaitlist = false }) => {
3356
+ const offerWaitlist = action === "places" && canJoinWaitlist;
3357
+ return /* @__PURE__ */ jsx(TerminalPanel, {
3358
+ tone: "error",
3359
+ className: "er-center",
3360
+ titleClassName: "er-title--lg er-message",
3361
+ icon: /* @__PURE__ */ jsx(StateIcon, {
3362
+ variant: "error",
3363
+ children: /* @__PURE__ */ jsx(CrossIcon, {})
3364
+ }),
3365
+ title: "We couldn’t complete your booking",
3366
+ body: /* @__PURE__ */ jsx("p", {
3367
+ className: "er-text--muted er-message",
3368
+ children: offerWaitlist ? "Sorry, this event is now full. You can join the waiting list, and we’ll email you if a place becomes available." : message
3369
+ }),
3370
+ actions: action === "none" ? void 0 : action === "portal" || action === "payment-status" ? /* @__PURE__ */ jsx("a", {
3371
+ href: "/portal",
3372
+ className: "er-retry-btn",
3373
+ children: labels[action]
3374
+ }) : /* @__PURE__ */ jsx("button", {
3375
+ type: "button",
3376
+ onClick: onRetry,
3377
+ className: "er-retry-btn",
3378
+ children: offerWaitlist ? "Join the waiting list" : labels[action]
3379
+ })
3380
+ });
3381
+ };
3382
+ //#endregion
3162
3383
  //#region ../blocks/src/system/runtime/nodes/event-registration/EventRegistrationSummaryBar.tsx
3163
3384
  function getScheduleSummary(wizard, summaryEvent) {
3164
3385
  if (summaryEvent.registrationSubject.kind !== "wholeSeries") {
@@ -3442,7 +3663,7 @@ function SelectTicketsActions(props) {
3442
3663
  const currentEvent = wizard.selectedEvent ?? wizard.preSelectedEvent;
3443
3664
  const registrationOptionsPending = wizard.registrationOptionsState.tag === "idle" || wizard.registrationOptionsState.tag === "loading";
3444
3665
  const registrationOptionsFailed = wizard.registrationOptionsState.tag === "failed";
3445
- const isSoldOutWithoutWaitlist = !hasWaitlistClaim && isFullWithNoWaitlist(currentEvent, wizard.selectedAttendanceMode);
3666
+ const isSoldOutWithoutWaitlist = !wizard.checkoutRecovery && !hasWaitlistClaim && isFullWithNoWaitlist(currentEvent, wizard.selectedAttendanceMode);
3446
3667
  const isCheckingExistingRegistration = wizard.portalAuthState === "authenticated" && wizard.existingRegistrationLoading;
3447
3668
  const hasExistingRegistration = isExistingRegistrationBlocking$1(wizard);
3448
3669
  const ticketTypeSelectionBlocked = wizard.ticketTypeSelectionRequired && !wizard.hasValidTicketSelection;
@@ -4032,6 +4253,31 @@ function resolveTicketSelectionPricing(event) {
4032
4253
  currency: event ? publicEventPricingCurrency(event.pricing) : null
4033
4254
  };
4034
4255
  }
4256
+ function CheckoutRecoveryEntry(props) {
4257
+ return props.onContinue ? /* @__PURE__ */ jsx("button", {
4258
+ type: "button",
4259
+ className: "er-back-btn",
4260
+ onClick: props.onContinue,
4261
+ children: "Continue an existing booking"
4262
+ }) : null;
4263
+ }
4264
+ function getTicketSelectionCapacity(event, attendanceMode, checkoutRecovery) {
4265
+ if (checkoutRecovery) return {
4266
+ availableSpots: null,
4267
+ isSoldOut: false,
4268
+ canJoinWaitlist: false,
4269
+ eventAvailabilityLabel: null
4270
+ };
4271
+ const source = event ? selectEventCapacitySource(event, attendanceMode) : null;
4272
+ const availability = source ? getEventAvailability(source) : null;
4273
+ const canJoinWaitlist = source ? canJoinEventWaitlist(source) : false;
4274
+ return {
4275
+ availableSpots: availability?.available,
4276
+ isSoldOut: availability?.isFull ?? false,
4277
+ canJoinWaitlist,
4278
+ eventAvailabilityLabel: !canJoinWaitlist && source ? formatRemainingPlaces(source) : null
4279
+ };
4280
+ }
4035
4281
  /**
4036
4282
  * Ticket Selection Step
4037
4283
  *
@@ -4040,15 +4286,11 @@ function resolveTicketSelectionPricing(event) {
4040
4286
  *
4041
4287
  * Can use either a full PublicEvent or just occurrence context (when on event page).
4042
4288
  */
4043
- const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, selectedAttendanceMode = null, onAttendanceModeChange, ticketsCount, maxTickets, visibleTicketTypes: visibleTicketTypesOverride, ticketSelections = [], onTicketSelectionsChange, slidingScale = null, selectedSlidingAmountInput = "", slidingScaleSelectionMessage = null, onSlidingAmountChange, onTicketsChange, bookingUnit = { kind: "ticket" } }) => {
4289
+ const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, selectedAttendanceMode = null, onAttendanceModeChange, ticketsCount, maxTickets, visibleTicketTypes: visibleTicketTypesOverride, ticketSelections = [], onTicketSelectionsChange, slidingScale = null, selectedSlidingAmountInput = "", slidingScaleSelectionMessage = null, onSlidingAmountChange, onTicketsChange, bookingUnit = { kind: "ticket" }, checkoutRecovery = false, onCheckoutRecovery }) => {
4044
4290
  const unit = bookingUnit.kind;
4045
4291
  const deliveryMode = event?.deliveryMode ?? "in_person";
4046
4292
  const attendanceModes = event?.attendanceModes ?? [];
4047
- const capacitySource = event ? selectEventCapacitySource(event, selectedAttendanceMode) : null;
4048
- const availability = capacitySource ? getEventAvailability(capacitySource) : null;
4049
- const availableSpots = availability?.available;
4050
- const isSoldOut = availability?.isFull ?? false;
4051
- const canJoinWaitlist = capacitySource ? canJoinEventWaitlist(capacitySource) : false;
4293
+ const { availableSpots, isSoldOut, canJoinWaitlist, eventAvailabilityLabel } = getTicketSelectionCapacity(event, selectedAttendanceMode, checkoutRecovery);
4052
4294
  const { mode: eventPricingMode, currency: eventPricingCurrency } = resolveTicketSelectionPricing(event);
4053
4295
  const usesTicketTypes = eventPricingMode === "tiered" && !canJoinWaitlist;
4054
4296
  const visibleTicketTypes = usesTicketTypes ? visibleTicketTypesOverride ?? getVisibleTicketTypes({
@@ -4067,7 +4309,6 @@ const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, sel
4067
4309
  selectedTicketTypeRemainingCapacity: implicitTicketType?.availability.remainingPlaces ?? null,
4068
4310
  hasSelectedTicketType: implicitTicketType !== null
4069
4311
  });
4070
- const eventAvailabilityLabel = !canJoinWaitlist && capacitySource ? formatRemainingPlaces(capacitySource) : null;
4071
4312
  if (deliveryMode === "hybrid" && !selectedAttendanceMode) return /* @__PURE__ */ jsxs("div", {
4072
4313
  className: "rb-reg-stack er-stack",
4073
4314
  children: [
@@ -4088,13 +4329,17 @@ const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, sel
4088
4329
  });
4089
4330
  if (isSoldOut && !canJoinWaitlist) return /* @__PURE__ */ jsxs("div", {
4090
4331
  className: "rb-reg-stack er-stack",
4091
- children: [/* @__PURE__ */ jsx("h3", {
4092
- className: "er-title",
4093
- children: "Sold out"
4094
- }), /* @__PURE__ */ jsx("p", {
4095
- className: "er-text er-text--muted",
4096
- children: "Sorry you missed out! This event is fully booked."
4097
- })]
4332
+ children: [
4333
+ /* @__PURE__ */ jsx("h3", {
4334
+ className: "er-title",
4335
+ children: "Sold out"
4336
+ }),
4337
+ /* @__PURE__ */ jsx("p", {
4338
+ className: "er-text er-text--muted",
4339
+ children: "Sorry you missed out! This event is fully booked."
4340
+ }),
4341
+ /* @__PURE__ */ jsx(CheckoutRecoveryEntry, { onContinue: onCheckoutRecovery })
4342
+ ]
4098
4343
  });
4099
4344
  if (!eventPricingCurrency) return /* @__PURE__ */ jsx("div", {
4100
4345
  className: "rb-reg-stack er-stack",
@@ -4162,9 +4407,13 @@ const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, sel
4162
4407
  })]
4163
4408
  })
4164
4409
  ] }),
4165
- canJoinWaitlist && /* @__PURE__ */ jsx("p", {
4410
+ canJoinWaitlist && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", {
4166
4411
  className: "er-text er-text--muted",
4167
4412
  children: "This event is currently full. Continue to join the waitlist if a place opens up."
4413
+ }), /* @__PURE__ */ jsx(CheckoutRecoveryEntry, { onContinue: onCheckoutRecovery })] }),
4414
+ checkoutRecovery && /* @__PURE__ */ jsx("p", {
4415
+ className: "er-text er-text--muted",
4416
+ children: "Enter the details from your earlier booking. We’ll check your checkout before continuing to payment."
4168
4417
  })
4169
4418
  ]
4170
4419
  });
@@ -5072,12 +5321,14 @@ function EventRegistrationWizardContent(props) {
5072
5321
  onBookForSomeoneElse: wizard.handleBookForSomeoneElse
5073
5322
  }), /* @__PURE__ */ jsx(TicketSelectionStep, {
5074
5323
  event: wizard.selectedEvent,
5324
+ checkoutRecovery: wizard.checkoutRecovery,
5325
+ onCheckoutRecovery: canRecoverEventCheckout(wizard.selectedEvent) ? wizard.startCheckoutRecovery : void 0,
5075
5326
  occurrenceContext: wizard.occurrenceContext,
5076
5327
  selectedAttendanceMode: wizard.selectedAttendanceMode,
5077
5328
  onAttendanceModeChange: wizard.setSelectedAttendanceMode,
5078
5329
  ticketsCount: wizard.ticketsCount,
5079
5330
  maxTickets: wizard.maxTicketsNum,
5080
- visibleTicketTypes: wizard.eligibility ? wizard.visibleTicketTypes : void 0,
5331
+ visibleTicketTypes: wizard.visibleTicketTypes,
5081
5332
  ticketSelections: wizard.selectedTicketLines,
5082
5333
  onTicketSelectionsChange: wizard.setSelectedTicketLines,
5083
5334
  slidingScale: wizard.selectedEventSlidingScale,
@@ -5096,66 +5347,6 @@ function EventRegistrationWizardContent(props) {
5096
5347
  }
5097
5348
  }
5098
5349
  //#endregion
5099
- //#region ../blocks/src/system/runtime/nodes/event-registration/StepIndicator.tsx
5100
- /**
5101
- * Step indicator component for the event registration wizard.
5102
- * Thin wrapper around the shared StepIndicator: styled by the shared
5103
- * registration-surface classes, with 'er'-prefixed classes kept in the
5104
- * markup as the stable hook surface for per-site theme CSS.
5105
- */
5106
- function StepIndicator(props) {
5107
- return /* @__PURE__ */ jsx(StepIndicator$1, {
5108
- ...props,
5109
- classPrefix: "er",
5110
- emitSharedClasses: true
5111
- });
5112
- }
5113
- //#endregion
5114
- //#region ../blocks/src/system/runtime/nodes/event-registration/ErrorStep.tsx
5115
- /**
5116
- * Error Step
5117
- *
5118
- * Displays an error message with a retry button when registration fails.
5119
- */
5120
- const labels = {
5121
- none: "",
5122
- retry: "Try again",
5123
- places: "Choose places",
5124
- start: "Start again",
5125
- details: "Check my details",
5126
- "payment-options": "View payment options",
5127
- "payment-status": "Check payment status",
5128
- portal: "View my bookings",
5129
- event: "View event"
5130
- };
5131
- const ErrorStep = ({ message, onRetry, action = "retry", canJoinWaitlist = false }) => {
5132
- const offerWaitlist = action === "places" && canJoinWaitlist;
5133
- return /* @__PURE__ */ jsx(TerminalPanel, {
5134
- tone: "error",
5135
- className: "er-center",
5136
- titleClassName: "er-title--lg er-message",
5137
- icon: /* @__PURE__ */ jsx(StateIcon, {
5138
- variant: "error",
5139
- children: /* @__PURE__ */ jsx(CrossIcon, {})
5140
- }),
5141
- title: "We couldn’t complete your booking",
5142
- body: /* @__PURE__ */ jsx("p", {
5143
- className: "er-text--muted er-message",
5144
- children: offerWaitlist ? "Sorry, this event is now full. You can join the waiting list, and we’ll email you if a place becomes available." : message
5145
- }),
5146
- actions: action === "none" ? void 0 : action === "portal" || action === "payment-status" ? /* @__PURE__ */ jsx("a", {
5147
- href: "/portal",
5148
- className: "er-retry-btn",
5149
- children: labels[action]
5150
- }) : /* @__PURE__ */ jsx("button", {
5151
- type: "button",
5152
- onClick: onRetry,
5153
- className: "er-retry-btn",
5154
- children: offerWaitlist ? "Join the waiting list" : labels[action]
5155
- })
5156
- });
5157
- };
5158
- //#endregion
5159
5350
  //#region ../blocks/src/system/runtime/nodes/event-registration/PaymentFailedStep.tsx
5160
5351
  /**
5161
5352
  * Payment Failed Step
@@ -5186,6 +5377,21 @@ const PaymentFailedStep = ({ onRetry }) => {
5186
5377
  });
5187
5378
  };
5188
5379
  //#endregion
5380
+ //#region ../blocks/src/system/runtime/nodes/event-registration/StepIndicator.tsx
5381
+ /**
5382
+ * Step indicator component for the event registration wizard.
5383
+ * Thin wrapper around the shared StepIndicator: styled by the shared
5384
+ * registration-surface classes, with 'er'-prefixed classes kept in the
5385
+ * markup as the stable hook surface for per-site theme CSS.
5386
+ */
5387
+ function StepIndicator(props) {
5388
+ return /* @__PURE__ */ jsx(StepIndicator$1, {
5389
+ ...props,
5390
+ classPrefix: "er",
5391
+ emitSharedClasses: true
5392
+ });
5393
+ }
5394
+ //#endregion
5189
5395
  //#region ../blocks/src/system/runtime/nodes/event-registration/SuccessStep.tsx
5190
5396
  /**
5191
5397
  * Success Step
@@ -5458,7 +5664,8 @@ function EventRegistrationSurface(props) {
5458
5664
  }), /* @__PURE__ */ jsx(EventRegistrationTerminalState, {
5459
5665
  wizard,
5460
5666
  supportEmail: props.supportEmail,
5461
- successMessage: props.successMessage
5667
+ successMessage: props.successMessage,
5668
+ buttonClass: props.buttonClass
5462
5669
  })]
5463
5670
  });
5464
5671
  }
@@ -5856,6 +6063,84 @@ function RegistrationClosedState({ title, body }) {
5856
6063
  });
5857
6064
  }
5858
6065
  //#endregion
6066
+ //#region ../blocks/src/system/runtime/nodes/event-registration/useEventSourceRecovery.ts
6067
+ const RECOVERY_DELAYS_MS = [
6068
+ 0,
6069
+ 250,
6070
+ 750
6071
+ ];
6072
+ const defaultRecoveryDeps = {
6073
+ useApi: useBlockApi,
6074
+ wait: waitForRetry
6075
+ };
6076
+ function useEventSourceRecovery(source, deps = defaultRecoveryDeps) {
6077
+ const api = deps.useApi();
6078
+ const wait = deps.wait;
6079
+ const [cycle, setCycle] = useState(0);
6080
+ const [state, setState] = useState(() => source.kind === "loaded" ? {
6081
+ kind: "ready",
6082
+ events: source.events
6083
+ } : { kind: "loading" });
6084
+ const retry = useCallback(() => {
6085
+ setState({ kind: "loading" });
6086
+ setCycle((value) => value + 1);
6087
+ }, []);
6088
+ useEffect(() => {
6089
+ if (source.kind === "loaded") {
6090
+ setState({
6091
+ kind: "ready",
6092
+ events: source.events
6093
+ });
6094
+ return;
6095
+ }
6096
+ if (!source.request) {
6097
+ setState({
6098
+ kind: "exhausted",
6099
+ retry
6100
+ });
6101
+ return;
6102
+ }
6103
+ const controller = new AbortController();
6104
+ const isCurrent = () => !controller.signal.aborted;
6105
+ (async () => {
6106
+ for (const delayMs of RECOVERY_DELAYS_MS) try {
6107
+ await wait(delayMs, controller.signal);
6108
+ const events = await api.getPublicEvents(source.request ?? void 0);
6109
+ if (isCurrent()) setState({
6110
+ kind: "ready",
6111
+ events
6112
+ });
6113
+ return;
6114
+ } catch {
6115
+ if (!isCurrent()) return;
6116
+ }
6117
+ if (isCurrent()) setState({
6118
+ kind: "exhausted",
6119
+ retry
6120
+ });
6121
+ })();
6122
+ return () => controller.abort();
6123
+ }, [
6124
+ api,
6125
+ cycle,
6126
+ retry,
6127
+ source,
6128
+ wait
6129
+ ]);
6130
+ return state;
6131
+ }
6132
+ function waitForRetry(milliseconds, signal) {
6133
+ if (signal.aborted) return Promise.reject(/* @__PURE__ */ new Error("Recovery aborted"));
6134
+ if (milliseconds === 0) return Promise.resolve();
6135
+ return new Promise((resolve, reject) => {
6136
+ const timeout = setTimeout(resolve, milliseconds);
6137
+ signal.addEventListener("abort", () => {
6138
+ clearTimeout(timeout);
6139
+ reject(/* @__PURE__ */ new Error("Recovery aborted"));
6140
+ }, { once: true });
6141
+ });
6142
+ }
6143
+ //#endregion
5859
6144
  //#region ../blocks/src/system/runtime/nodes/event-registration.client.tsx
5860
6145
  function toEventRegistrationClientProps(props, display) {
5861
6146
  return {
@@ -5889,8 +6174,71 @@ const EventRegistrationIslandClient = (props) => {
5889
6174
  title: props.render.display.titleText,
5890
6175
  body: props.render.display.bodyText
5891
6176
  });
5892
- return /* @__PURE__ */ jsx(EventRegistrationClient, { ...toEventRegistrationClientProps(props, props.render.display) });
6177
+ return /* @__PURE__ */ jsx(RecoverableEventRegistrationClient, {
6178
+ props,
6179
+ display: props.render.display
6180
+ });
5893
6181
  };
6182
+ function RecoverableEventRegistrationClient({ props, display }) {
6183
+ const recovery = useEventSourceRecovery(props.render.hydration.eventSource);
6184
+ if (recovery.kind === "loading") return /* @__PURE__ */ jsxs("div", {
6185
+ id: EVENT_REGISTRATION_ANCHOR_ID,
6186
+ className: "rb-reg-surface er-container er-registration-shell",
6187
+ "aria-busy": "true",
6188
+ role: "status",
6189
+ children: [
6190
+ /* @__PURE__ */ jsx("p", {
6191
+ className: "er-registration-shell__eyebrow",
6192
+ children: "Registration"
6193
+ }),
6194
+ /* @__PURE__ */ jsx("h3", {
6195
+ className: "er-title er-registration-shell__title",
6196
+ children: display.titleText
6197
+ }),
6198
+ /* @__PURE__ */ jsx("p", {
6199
+ className: "er-text er-text--muted",
6200
+ children: "Loading event dates…"
6201
+ }),
6202
+ /* @__PURE__ */ jsxs("div", {
6203
+ className: "er-event-grid er-registration-shell__cards",
6204
+ "aria-hidden": "true",
6205
+ children: [/* @__PURE__ */ jsx("div", { className: "er-event-card er-registration-shell__card" }), /* @__PURE__ */ jsx("div", { className: "er-event-card er-registration-shell__card" })]
6206
+ })
6207
+ ]
6208
+ });
6209
+ if (recovery.kind === "exhausted") return /* @__PURE__ */ jsxs("div", {
6210
+ id: EVENT_REGISTRATION_ANCHOR_ID,
6211
+ className: "rb-reg-surface er-container er-registration-shell",
6212
+ role: "alert",
6213
+ children: [/* @__PURE__ */ jsx("p", { children: "We couldn’t load the event dates. Please try again." }), /* @__PURE__ */ jsx("button", {
6214
+ type: "button",
6215
+ className: themeButtonClassName({
6216
+ variant: props.render.hydration.buttonVariant ?? "primary",
6217
+ size: "md"
6218
+ }),
6219
+ onClick: recovery.retry,
6220
+ children: "Try again"
6221
+ })]
6222
+ });
6223
+ const events = resolveEventRegistrationScopedEvents(recovery.events, {
6224
+ occurrenceContext: props.render.hydration.occurrenceContext,
6225
+ subject: props.render.hydration.subject
6226
+ });
6227
+ const recoveredDisplay = buildEventRegistrationDisplayFromScopedEvents({
6228
+ ...props.render.hydration,
6229
+ events,
6230
+ className: display.className,
6231
+ buttonText: display.summaryButtonText
6232
+ }, events);
6233
+ if (recoveredDisplay.state === "registration-closed") return /* @__PURE__ */ jsx(RegistrationClosedState, {
6234
+ title: recoveredDisplay.titleText,
6235
+ body: recoveredDisplay.bodyText
6236
+ });
6237
+ return /* @__PURE__ */ jsx(EventRegistrationClient, {
6238
+ ...toEventRegistrationClientProps(props, display),
6239
+ events
6240
+ });
6241
+ }
5894
6242
  //#endregion
5895
6243
  //#region src/rendering/islands/enhancers/eventRegistration.tsx
5896
6244
  const decode = defineIslandPropsDecoder("event-registration");