@riverbankcms/sdk 0.139.0 → 0.141.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 (232) hide show
  1. package/README.md +1 -1
  2. package/dist/{PreviewEditorSidebar-BDeenhi3.mjs → PreviewEditorSidebar-Q-fy9GYw.mjs} +4 -4
  3. package/dist/{PreviewEditorUI-DSRhgjF5.mjs → PreviewEditorUI-LYGzgk85.mjs} +3 -3
  4. package/dist/{PreviewQueryProvider-D2K8GLUG.mjs → PreviewQueryProvider-CN0ewic5.mjs} +1 -1
  5. package/dist/{SdkPreviewModeRuntime-CL7wSnYu.mjs → SdkPreviewModeRuntime-CoPYI5Jq.mjs} +90 -50
  6. package/dist/{SiteChromeCustomizeContext-BhDn-5ir.mjs → SiteChromeCustomizeContext-D8LePX8x.mjs} +2731 -1303
  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 +17 -31
  20. package/dist/_dts/api/src/domainConnection.d.ts +4 -0
  21. package/dist/_dts/api/src/endpoints.d.ts +93 -64
  22. package/dist/_dts/api/src/event-destination-policy.d.ts +2 -1
  23. package/dist/_dts/api/src/footerCompositionContracts.d.ts +25 -0
  24. package/dist/_dts/api/src/footerSettings.d.ts +9 -6
  25. package/dist/_dts/api/src/index.d.ts +6 -7
  26. package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -1
  27. package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -1
  28. package/dist/_dts/api/src/launchReadiness.d.ts +1 -0
  29. package/dist/_dts/api/src/mailingListIntegration.d.ts +8 -2
  30. package/dist/_dts/api/src/navigation/dashboardSettingsNav.d.ts +1 -1
  31. package/dist/_dts/api/src/navigation/dashboardSiteNav.d.ts +2 -1
  32. package/dist/_dts/api/src/navigation/types.d.ts +1 -1
  33. package/dist/_dts/api/src/onboarding/confirmationResend.d.ts +25 -0
  34. package/dist/_dts/api/src/onboarding/surfaceData.d.ts +32 -32
  35. package/dist/_dts/api/src/publicBookingAvailabilityEndpointDefinitions.d.ts +8 -0
  36. package/dist/_dts/api/src/publicExperience/commerceEndpoints.d.ts +1 -0
  37. package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +11 -3
  38. package/dist/_dts/api/src/publicExperience/sharedTypes.d.ts +3 -29
  39. package/dist/_dts/api/src/publicOnboardingAttemptEndpointDefinitions.d.ts +65 -0
  40. package/dist/_dts/api/src/saveOutcome.d.ts +20 -0
  41. package/dist/_dts/api/src/sdkContracts.d.ts +3 -22
  42. package/dist/_dts/api/src/sdkPushContracts.d.ts +18 -0
  43. package/dist/_dts/api/src/sdkThemeWire.d.ts +44 -44
  44. package/dist/_dts/api/src/settings/permissions.d.ts +12 -0
  45. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +10 -29
  46. package/dist/_dts/api/src/siteOnboarding.d.ts +9 -9
  47. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +2 -4
  48. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +3 -1
  49. package/dist/_dts/api/src/siteSettings.d.ts +20 -7
  50. package/dist/_dts/api/src/types.d.ts +77 -77
  51. package/dist/_dts/api/src/wholeSeriesRuns.d.ts +2 -37
  52. package/dist/_dts/billing/src/membership/index.d.ts +3 -0
  53. package/dist/_dts/billing/src/plans/types.d.ts +3 -0
  54. package/dist/_dts/billing/src/site-arrangements.d.ts +23 -3
  55. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +20 -4
  56. package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +2 -0
  57. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +7 -0
  58. package/dist/_dts/blocks/src/portal/types.d.ts +2 -4
  59. package/dist/_dts/blocks/src/portal/waitlist-types.d.ts +35 -0
  60. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +2 -0
  61. package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +2 -0
  62. package/dist/_dts/blocks/src/system/blocks/events/eventSelectionFields.d.ts +122 -0
  63. package/dist/_dts/blocks/src/system/blocks/events/shared/calendarWindow.d.ts +2 -1
  64. package/dist/_dts/blocks/src/system/blocks/events/shared/eventSelection.d.ts +11 -0
  65. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +42 -0
  66. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +4 -0
  67. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +2 -2
  68. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +47 -47
  69. package/dist/_dts/blocks/src/system/data/index.d.ts +2 -2
  70. package/dist/_dts/blocks/src/system/data/prefetchBlockData.d.ts +7 -1
  71. package/dist/_dts/blocks/src/system/data/types.d.ts +9 -0
  72. package/dist/_dts/blocks/src/system/data/utils.d.ts +1 -1
  73. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +27 -1
  74. package/dist/_dts/blocks/src/system/registry.d.ts +1 -0
  75. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +0 -28
  76. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
  77. package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +7 -3
  78. package/dist/_dts/blocks/src/system/runtime/api/types/portal.d.ts +1 -1
  79. package/dist/_dts/blocks/src/system/runtime/api/types/waitlist-claims.d.ts +7 -2
  80. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +42 -186
  81. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +21 -93
  82. package/dist/_dts/blocks/src/system/runtime/hooks/useEventFilters.d.ts +2 -1
  83. package/dist/_dts/blocks/src/system/runtime/nodes/appointment-services.d.ts +48 -1
  84. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +1 -2
  85. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +2 -0
  86. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.d.ts +14 -0
  87. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.d.ts +56 -0
  88. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.d.ts +4 -0
  89. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.state.d.ts +5 -0
  90. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +6 -8
  91. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.d.ts +8 -0
  92. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.d.ts +3 -0
  93. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.state.d.ts +10 -3
  94. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventCheckoutHandoffRestore.d.ts +9 -0
  95. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +8 -7
  96. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +14 -7
  97. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventSourceRecovery.d.ts +18 -0
  98. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useSettledCommerceView.d.ts +37 -0
  99. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.client.d.ts +1 -1
  100. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +24 -6
  101. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.server.d.ts +4 -2
  102. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +4 -3
  103. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +3 -0
  104. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.interactive.d.ts +11 -101
  105. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +7 -2
  106. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/listOptions.d.ts +2 -0
  107. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +6 -0
  108. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +1 -0
  109. package/dist/_dts/blocks/src/system/runtime/resolver.d.ts +1 -0
  110. package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +2 -6
  111. package/dist/_dts/blocks/src/system/runtime/shared/index.d.ts +2 -2
  112. package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.d.ts +2 -0
  113. package/dist/_dts/blocks/src/system/transforms/registry/eventCalendar.d.ts +12 -0
  114. package/dist/_dts/commerce/src/purchase/bookingInstalmentSchedule.d.ts +4 -0
  115. package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +4 -0
  116. package/dist/_dts/commerce/src/purchase/orderItemMetadata.d.ts +27 -4
  117. package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +2 -1
  118. package/dist/_dts/content-editor/src/hooks/useBlockAutosave.d.ts +3 -1
  119. package/dist/_dts/content-editor/src/useFooterComposerState.d.ts +3 -0
  120. package/dist/_dts/core/src/branded.d.ts +0 -8
  121. package/dist/_dts/core/src/index.d.ts +1 -0
  122. package/dist/_dts/core/src/mailing-list-setup-parser.d.ts +1 -1
  123. package/dist/_dts/core/src/mailing-list-setup.d.ts +14 -1
  124. package/dist/_dts/core/src/mailing-list-submission.d.ts +7 -27
  125. package/dist/_dts/core/src/participants.d.ts +2 -29
  126. package/dist/_dts/core/src/public-experience.d.ts +4 -0
  127. package/dist/_dts/core/src/public-profile.d.ts +27 -1
  128. package/dist/_dts/core/src/site-route-target.d.ts +9 -2
  129. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +296 -606
  130. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/MailingListGlobalSettingsSummary.d.ts +10 -0
  131. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/MailingListTargetingField.d.ts +3 -2
  132. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/context.d.ts +3 -2
  133. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/loaders.d.ts +3 -2
  134. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/targetingState.d.ts +19 -0
  135. package/dist/_dts/editor-blocks/src/widgets/site-option-picker/loaders.d.ts +27 -1
  136. package/dist/_dts/sdk/src/public-api/contracts.d.ts +14 -20
  137. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +2 -0
  138. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +2 -0
  139. package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +7 -1
  140. package/dist/_dts/sdk/src/rendering/helpers/templateContent.d.ts +1 -0
  141. package/dist/_dts/sdk/src/version.d.ts +1 -1
  142. package/dist/_dts/theme-core/src/ThemeFontLoader.d.ts +17 -1
  143. package/dist/_dts/theme-core/src/accordions/types.d.ts +3 -3
  144. package/dist/_dts/theme-core/src/buttons/affordanceSuppression.d.ts +17 -0
  145. package/dist/_dts/theme-core/src/buttons/buttonColourContract.d.ts +1 -1
  146. package/dist/_dts/theme-core/src/buttons/classNames.d.ts +16 -0
  147. package/dist/_dts/theme-core/src/buttons/generateButtonCss.d.ts +0 -6
  148. package/dist/_dts/theme-core/src/buttons/resolvedButtonCss.d.ts +4 -4
  149. package/dist/_dts/theme-core/src/cards/types.d.ts +21 -21
  150. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  151. package/dist/_dts/theme-core/src/header/interactionPalette.d.ts +8 -2
  152. package/dist/_dts/theme-core/src/header/legacyHeaderVariant.d.ts +2 -2
  153. package/dist/_dts/theme-core/src/hosted-booking-appearance.d.ts +54 -12
  154. package/dist/_dts/theme-core/src/index.d.ts +1 -1
  155. package/dist/_dts/theme-core/src/inputs/types.d.ts +2 -2
  156. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +54 -54
  157. package/dist/_dts/theme-core/src/runtime/buildThemeRuntimeFromBridge.d.ts +1 -4
  158. package/dist/_dts/theme-core/src/schema.d.ts +84 -84
  159. package/dist/_dts/theme-core/src/shared/componentStyles.d.ts +1 -1
  160. package/dist/_dts/theme-core/src/site-styles/backgroundAppearance.d.ts +2 -2
  161. package/dist/_dts/theme-core/src/surfaces/foregroundInteraction.d.ts +77 -0
  162. package/dist/_dts/theme-core/src/surfaces/index.d.ts +1 -0
  163. package/dist/_dts/theme-core/src/typography/generateTypographyCss.d.ts +2 -2
  164. package/dist/_dts/ui/src/lib/use-delayed-flag.d.ts +9 -0
  165. package/dist/_dts/ui/src/pending-button.d.ts +10 -0
  166. package/dist/client/{BookingConsentAgreement-CZvTDtsK.mjs → BookingConsentAgreement-xJeYNdnb.mjs} +4 -4
  167. package/dist/client/{DiscountCodeDisclosure-D-DsLCMU.mjs → DiscountCodeDisclosure-DdT6uzl9.mjs} +1 -1
  168. package/dist/client/{EventCombined.client-dWqgd5ZO.mjs → EventCombined.client-Cp28uYuM.mjs} +12 -16
  169. package/dist/client/{EventListing.client-BMRa9IYp.mjs → EventListing.client-CD6AJsMr.mjs} +4 -17
  170. package/dist/client/{LeafletStaticMap-D21W9kBZ.mjs → LeafletStaticMap-DBsAi9-e.mjs} +1 -1
  171. package/dist/client/{accordion-FxF_ta47.mjs → accordion-6dwbOKYR.mjs} +1 -1
  172. package/dist/client/{bookingForm-YnwW4TGw.mjs → bookingForm-CZE9_qPQ.mjs} +7 -7
  173. package/dist/client/bookings.mjs +500 -233
  174. package/dist/client/{carousel-vng7fFT5.mjs → carousel-7VHGQARz.mjs} +2 -2
  175. package/dist/client/{carousel.client-59G_WMr4.mjs → carousel.client-DQTjCVQT.mjs} +1 -1
  176. package/dist/client/{cart-DEPDsjNk.mjs → cart-Qg_mvQhh.mjs} +3 -3
  177. package/dist/client/{checkout-CZRWu9rW.mjs → checkout-D84rpgdr.mjs} +3 -3
  178. package/dist/client/{checkoutUrls-BuseL0dw.mjs → checkoutUrls-FL6lRkrt.mjs} +1 -1
  179. package/dist/client/client.mjs +2315 -1017
  180. package/dist/client/{colorStyles-CrxJrPjJ.mjs → colorStyles-3013aRAY.mjs} +3 -1
  181. package/dist/client/{context-DvU_WUmd.mjs → context-Ctp3T0Wr.mjs} +6 -19
  182. package/dist/client/{dates-wnPMiRl5.mjs → dates-DJKFcI_N.mjs} +2 -2
  183. package/dist/client/{eventCalendar-BA3Q5L15.mjs → eventCalendar-CK31z3vs.mjs} +12 -8
  184. package/dist/client/{eventCombined-51wgR-1R.mjs → eventCombined-DiXd-ewn.mjs} +3 -3
  185. package/dist/client/{eventDetails-modaetpm.mjs → eventDetails-CTRgt2DK.mjs} +4 -4
  186. package/dist/client/{eventListing-D8t2J3Kv.mjs → eventListing-Dy9vi_j_.mjs} +3 -3
  187. package/dist/client/{eventRegistration-CYqtkCE_.mjs → eventRegistration-CnalYMr2.mjs} +618 -177
  188. package/dist/client/{form-CBKXN5In.mjs → form-eUiMveTT.mjs} +3 -3
  189. package/dist/client/{headerSection-DylDqNrs.mjs → headerSection-Dy9kQpB1.mjs} +2 -2
  190. package/dist/client/hooks.mjs +692 -212
  191. package/dist/client/{locationMap-CvWrG0vZ.mjs → locationMap-DalCmWU0.mjs} +3 -3
  192. package/dist/client/{media-BOHuueS5.mjs → media-DHpfFwd3.mjs} +1 -1
  193. package/dist/client/{newsletterForm-Btwk70zw.mjs → newsletterForm-SDDPvhS0.mjs} +150 -94
  194. package/dist/client/{pricing-Uzw-GQ6Y.mjs → pricing-OcMz4SnX.mjs} +1 -1
  195. package/dist/client/{productDetail-JLcUYKnd.mjs → productDetail-BQrgHElM.mjs} +3 -3
  196. package/dist/client/{productList-FM0cbUzj.mjs → productList-OnPn_UJj.mjs} +3 -3
  197. package/dist/client/{propsDecoder-DYzafZb2.mjs → propsDecoder-zBdsnS-N.mjs} +168 -32
  198. package/dist/client/rendering/client.mjs +1355 -519
  199. package/dist/client/rendering/islands.mjs +19 -19
  200. package/dist/client/rendering.mjs +2294 -953
  201. package/dist/client/{scrollToBlock-CvXszexS.mjs → scrollToBlock-BNM4Ob2Y.mjs} +28 -11
  202. package/dist/client/{shop-BIcjvy5a.mjs → shop-Bv1fPTwQ.mjs} +6 -6
  203. package/dist/client/{shop-commerce-BZQsy7xw.mjs → shop-commerce-D4KNGaW8.mjs} +7 -7
  204. package/dist/client/{shop-commerce-store-D5V7XAb5.mjs → shop-commerce-store-2N5EV0Rc.mjs} +1 -1
  205. package/dist/client/{shopShared-DowkXevB.mjs → shopShared-DvJGdHTV.mjs} +4 -4
  206. package/dist/client/{useEventFilters-oMoTw_JE.mjs → useEventFilters-BBBvGDHQ.mjs} +19 -13
  207. package/dist/preview-next/before-render.mjs +119 -64
  208. package/dist/preview-next/client/runtime.mjs +4 -4
  209. package/dist/preview-next/editor-chrome.css +4 -8
  210. package/dist/preview-next/keepAlive.mjs +119 -64
  211. package/dist/preview-next/middleware.mjs +119 -64
  212. package/dist/{previewAuthStore-COUyAKaX.mjs → previewAuthStore-Gjb6r6vz.mjs} +119 -64
  213. package/dist/{sdk-runtime-D4k2LSGF.mjs → sdk-runtime-Defnbfzw.mjs} +2 -2
  214. package/dist/{separator-UGtpag4Z.mjs → separator-CZXO3Sb0.mjs} +1 -1
  215. package/dist/server/components.mjs +1170 -384
  216. package/dist/server/config-validation.mjs +560 -105
  217. package/dist/server/config.mjs +564 -109
  218. package/dist/server/data.mjs +688 -212
  219. package/dist/server/index.mjs +126 -66
  220. package/dist/server/next.mjs +1429 -662
  221. package/dist/server/page-converter.mjs +372 -99
  222. package/dist/server/prebuild.mjs +1 -1
  223. package/dist/server/rendering/server.mjs +1624 -817
  224. package/dist/server/rendering.mjs +1200 -391
  225. package/dist/server/routing.mjs +767 -247
  226. package/dist/server/server.mjs +715 -276
  227. package/dist/server/theme-bridge.mjs +475 -110
  228. package/dist/server/theme.mjs +9 -3
  229. package/dist/styles/index.css +265 -45
  230. package/package.json +1 -1
  231. package/dist/_dts/blocks/src/system/runtime/shared/components/BookingOptionCompactRow.d.ts +0 -29
  232. package/dist/_dts/blocks/src/system/runtime/shared/components/BookingOptionList.d.ts +0 -13
@@ -6878,8 +6878,14 @@ const headerInteractionPillPaletteValues = [
6878
6878
  "accent"
6879
6879
  ];
6880
6880
  /**
6881
- * "No pill": the nav link keeps whatever hover treatment its recipe compiled,
6882
- * and the palette step writes nothing at all (#1318 Phase 4c decision 2).
6881
+ * "No pill": a colour change on hover rather than a filled background.
6882
+ *
6883
+ * The palette step writes nothing (#1318 Phase 4c decision 2), but on a
6884
+ * foreground-adaptive style that is not the end of the story: the hover colour
6885
+ * is derived from the resolved opening foreground at render time, paired with
6886
+ * the resting colour, so `quiet` resolves to a definite colour rather than to
6887
+ * whatever brand token the recipe happened to name. See
6888
+ * `applyOpeningForeground`.
6883
6889
  *
6884
6890
  * It exists because "a colour change on hover, no filled background" was not
6885
6891
  * expressible in the vocabulary, and it is what
@@ -7861,6 +7867,28 @@ const bookingRequirementConsentFieldSchema = z.object({
7861
7867
  z.union([blockBookingConsentSchema, bookingRequirementConsentFieldSchema]);
7862
7868
  //#endregion
7863
7869
  //#region ../blocks/src/system/blocks/events/shared/schemas.ts
7870
+ const publicEventLoaderQuerySchemaShape = {
7871
+ limit: z.string().optional(),
7872
+ from: z.string().optional(),
7873
+ to: z.string().optional(),
7874
+ afterStartsAt: z.string().optional(),
7875
+ afterId: z.string().optional(),
7876
+ categoryIds: z.string().optional(),
7877
+ venueId: z.string().optional(),
7878
+ staffMemberId: z.string().optional(),
7879
+ eventSurface: z.string().optional(),
7880
+ eventPresets: z.string().optional(),
7881
+ scheduleScope: z.string().optional(),
7882
+ seriesId: z.string().optional(),
7883
+ seriesIds: z.string().optional(),
7884
+ runSeriesId: z.string().optional(),
7885
+ seriesSlug: z.string().optional(),
7886
+ includeOccurrenceId: z.string().optional(),
7887
+ readIntent: z.string().optional(),
7888
+ detailLevel: z.string().optional(),
7889
+ readProfile: z.string().optional()
7890
+ };
7891
+ z.object(publicEventLoaderQuerySchemaShape);
7864
7892
  const eventPresetSchema = z.enum([
7865
7893
  "event",
7866
7894
  "class",
@@ -8168,6 +8196,7 @@ z.object({
8168
8196
  eventSurface: z.enum(eventSurfaceScopeValues).optional(),
8169
8197
  eventPresets: z.string().optional(),
8170
8198
  scheduleScope: z.enum(eventScheduleScopeValues).optional(),
8199
+ seriesIds: z.string().optional(),
8171
8200
  categoryIds: z.string().optional(),
8172
8201
  venueId: z.string().transform(normalizeCalendarFilterId).optional(),
8173
8202
  staffMemberId: z.string().transform(normalizeCalendarFilterId).optional()
@@ -8727,6 +8756,9 @@ function isApiSuccessResponse(json) {
8727
8756
  * });
8728
8757
  * ```
8729
8758
  */
8759
+ function publicEventsQuery(params) {
8760
+ return { ...params ?? {} };
8761
+ }
8730
8762
  function createBlockApi(config) {
8731
8763
  const { baseUrl, auth, authOverrides, siteId, isPreview } = config;
8732
8764
  const dedup = createDeduplicationCache({ ttl: 100 });
@@ -8879,23 +8911,7 @@ function createBlockApi(config) {
8879
8911
  const path = buildPath(EVENTS.list.path, { siteId: sid });
8880
8912
  return request(EVENTS.list, {
8881
8913
  path,
8882
- query: {
8883
- from: params?.from,
8884
- to: params?.to,
8885
- afterStartsAt: params?.afterStartsAt,
8886
- afterId: params?.afterId,
8887
- limit: params?.limit,
8888
- stage: params?.stage,
8889
- eventSurface: params?.eventSurface,
8890
- eventPresets: params?.eventPresets,
8891
- scheduleScope: params?.scheduleScope,
8892
- categoryIds: params?.categoryIds,
8893
- venueId: params?.venueId,
8894
- staffMemberId: params?.staffMemberId,
8895
- seriesId: params?.seriesId,
8896
- includeOccurrenceId: params?.includeOccurrenceId,
8897
- detailLevel: params?.detailLevel
8898
- }
8914
+ query: publicEventsQuery(params)
8899
8915
  });
8900
8916
  },
8901
8917
  async getEventFilters(params) {
@@ -8959,7 +8975,7 @@ function createBlockApi(config) {
8959
8975
  const path = buildPath(WHOLE_SERIES.waitlistClaimResolve.path, { siteId: sid });
8960
8976
  return request(WHOLE_SERIES.waitlistClaimResolve, {
8961
8977
  path,
8962
- body: { claimToken: data.claimToken }
8978
+ body: data
8963
8979
  });
8964
8980
  },
8965
8981
  async getDiscountsAvailable(data) {
@@ -10610,10 +10626,14 @@ function buildDiscountAvailabilityRequestPlan(options) {
10610
10626
  }
10611
10627
  };
10612
10628
  }
10613
- function discountAvailabilityStateFromResponse(response) {
10614
- if (!discountAvailabilityHasDiscounts(response)) return { tag: "unavailable" };
10629
+ function discountAvailabilityStateFromResponse(requestKey, response) {
10630
+ if (!discountAvailabilityHasDiscounts(response)) return {
10631
+ tag: "unavailable",
10632
+ requestKey
10633
+ };
10615
10634
  return {
10616
10635
  tag: "available",
10636
+ requestKey,
10617
10637
  manualCodeEntryAllowed: discountAvailabilityAllowsManualEntry(response),
10618
10638
  autoAppliedDiscount: getAutoAppliedDiscountPreview(response)
10619
10639
  };
@@ -10623,10 +10643,13 @@ function discountCodeUiReducer(state, event) {
10623
10643
  case "availability-disabled": return initialDiscountCodeUiState;
10624
10644
  case "availability-loading": return {
10625
10645
  ...state,
10626
- availability: { tag: "loading" }
10646
+ availability: {
10647
+ tag: "loading",
10648
+ previous: state.availability.tag === "available" || state.availability.tag === "unavailable" ? state.availability : state.availability.tag === "loading" ? state.availability.previous : null
10649
+ }
10627
10650
  };
10628
10651
  case "availability-loaded": {
10629
- const availability = discountAvailabilityStateFromResponse(event.response);
10652
+ const availability = discountAvailabilityStateFromResponse(event.requestKey, event.response);
10630
10653
  if (availability.tag !== "available" || !availability.manualCodeEntryAllowed) return {
10631
10654
  ...state,
10632
10655
  discountUiOpen: false,
@@ -10642,7 +10665,10 @@ function discountCodeUiReducer(state, event) {
10642
10665
  ...state,
10643
10666
  discountUiOpen: false,
10644
10667
  discountCode: "",
10645
- availability: { tag: "error" }
10668
+ availability: {
10669
+ tag: "error",
10670
+ requestKey: event.requestKey
10671
+ }
10646
10672
  };
10647
10673
  case "discount-code-changed": return {
10648
10674
  ...state,
@@ -10678,11 +10704,15 @@ function useDiscountCodeUi(options) {
10678
10704
  if (cancelled) return;
10679
10705
  dispatch({
10680
10706
  type: "availability-loaded",
10707
+ requestKey: requestPlan.key,
10681
10708
  response: res
10682
10709
  });
10683
10710
  } catch {
10684
10711
  if (cancelled) return;
10685
- dispatch({ type: "availability-failed" });
10712
+ dispatch({
10713
+ type: "availability-failed",
10714
+ requestKey: requestPlan.key
10715
+ });
10686
10716
  }
10687
10717
  }
10688
10718
  checkDiscountAvailability();
@@ -10691,8 +10721,9 @@ function useDiscountCodeUi(options) {
10691
10721
  };
10692
10722
  }, [options.api, requestPlan]);
10693
10723
  const availability = state.availability;
10694
- const isAvailable = availability.tag === "available";
10695
- const manualCodeEntryAllowed = isAvailable ? availability.manualCodeEntryAllowed : false;
10724
+ const settledAvailability = availability.tag === "loading" ? availability.previous : availability.tag === "available" || availability.tag === "unavailable" ? availability : null;
10725
+ const isAvailable = settledAvailability?.tag === "available";
10726
+ const manualCodeEntryAllowed = isAvailable ? settledAvailability.manualCodeEntryAllowed : false;
10696
10727
  return {
10697
10728
  discountUiOpen: state.discountUiOpen,
10698
10729
  setDiscountUiOpen: (isOpen) => dispatch({
@@ -10706,8 +10737,10 @@ function useDiscountCodeUi(options) {
10706
10737
  }),
10707
10738
  discountsAvailable: isAvailable,
10708
10739
  manualCodeEntryAllowed,
10709
- autoAppliedDiscount: isAvailable ? availability.autoAppliedDiscount : null,
10710
- discountsAvailableLoading: availability.tag === "loading"
10740
+ autoAppliedDiscount: isAvailable ? settledAvailability.autoAppliedDiscount : null,
10741
+ discountsAvailableLoading: availability.tag === "loading",
10742
+ discountAvailabilityRequestKey: requestPlan.key,
10743
+ settledDiscountAvailabilityRequestKey: availability.tag === "error" ? availability.requestKey : settledAvailability?.requestKey ?? null
10711
10744
  };
10712
10745
  }
10713
10746
  //#endregion
@@ -14867,61 +14900,6 @@ const BookingFormClient$1 = ({ siteId: siteIdProp, render }) => {
14867
14900
  });
14868
14901
  };
14869
14902
  //#endregion
14870
- //#region ../blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.ts
14871
- function resolveRegistrationRecoveryAction(step, action) {
14872
- if (step === "payment-failed") return "payment-options";
14873
- if (step === "verifying-payment" || step === "verifying-timeout" || step === "redirecting") return "payment-status";
14874
- return action;
14875
- }
14876
- function canRecoverToWaitlist(eligibility) {
14877
- return Boolean(eligibility?.isFull && eligibility.canJoinWaitlist);
14878
- }
14879
- function shouldRefreshAfterRegistrationError(step, action, enabled) {
14880
- return enabled || step === "error" && action === "places";
14881
- }
14882
- function resetRegistrationAfterExpiry(input) {
14883
- input.dispatchFlow({
14884
- type: "reset",
14885
- hasPreSelectedContext: input.hasPreSelectedContext
14886
- });
14887
- input.setSelectedTicketLines([]);
14888
- input.setSelectedSlidingAmountInput("");
14889
- const mode = input.preSelectedEvent?.deliveryMode;
14890
- input.setSelectedAttendanceMode(mode === "online" || mode === "in_person" ? mode : null);
14891
- input.setErrorMessage("");
14892
- input.setPendingRegistrationReference(null);
14893
- }
14894
- /** Recovery never starts another payment. Unknown payment outcomes go to the portal. */
14895
- function recoverRegistrationError(action, handlers) {
14896
- switch (action) {
14897
- case "none": return;
14898
- case "portal":
14899
- case "payment-status":
14900
- window.location.assign("/portal");
14901
- return;
14902
- case "event":
14903
- window.location.assign(window.location.pathname);
14904
- return;
14905
- case "retry":
14906
- window.location.reload();
14907
- return;
14908
- case "details":
14909
- handlers.clearError();
14910
- handlers.setStep("enter-details");
14911
- return;
14912
- case "payment-options":
14913
- case "places":
14914
- handlers.refreshOptions();
14915
- handlers.clearError();
14916
- handlers.setStep(action === "places" ? handlers.canJoinWaitlist ? "enter-details" : "select-tickets" : "select-payment");
14917
- return;
14918
- case "start":
14919
- handlers.refreshOptions();
14920
- handlers.reset();
14921
- return;
14922
- }
14923
- }
14924
- //#endregion
14925
14903
  //#region ../blocks/src/system/runtime/nodes/events/domain/capacity.ts
14926
14904
  /**
14927
14905
  * Compute remaining spots for an event from `availableSpots` with a fallback
@@ -14991,6 +14969,166 @@ function resolveRuntimeEventDestination(event) {
14991
14969
  };
14992
14970
  }
14993
14971
  //#endregion
14972
+ //#region ../blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.ts
14973
+ /** Recovery may select held places; checkout still owns admission and payment validation. */
14974
+ function checkoutRecoveryOptionAvailability(availability) {
14975
+ if (availability.kind === "available" || availability.reason === "sold_out" || availability.reason === "overallCapacityUnavailable") return {
14976
+ kind: "available",
14977
+ remainingPlaces: null
14978
+ };
14979
+ return availability;
14980
+ }
14981
+ /**
14982
+ * A form-only projection for the explicit existing-checkout path. It permits
14983
+ * collecting the original selection without claiming a new place is available.
14984
+ * The public checkout service identifies the customer and remains the admission
14985
+ * authority; no reservation/customer data is exposed through this projection.
14986
+ */
14987
+ function getCheckoutRecoveryFormEligibility(eligibility) {
14988
+ 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;
14989
+ const amountCents = eligibility.price ?? 0;
14990
+ if (amountCents <= 0 || !eligibility.currency || eligibility.availability.kind === "unavailable" && eligibility.availability.reason === "selectionRequired") return eligibility.registration.kind === "pending_payment" ? {
14991
+ ...eligibility,
14992
+ registration: { kind: "none" },
14993
+ ticketTypes: eligibility.ticketTypes.map((option) => ({
14994
+ ...option,
14995
+ availability: checkoutRecoveryOptionAvailability(option.availability)
14996
+ }))
14997
+ } : eligibility;
14998
+ const currency = eligibility.currency;
14999
+ const paymentOptions = eligibility.paymentTerms.allowedOptions.map((option) => {
15000
+ switch (option.kind) {
15001
+ case "upfront": return {
15002
+ kind: "payInFull",
15003
+ amountCents,
15004
+ currency
15005
+ };
15006
+ case "deferred_manual": return {
15007
+ kind: "deferredManual",
15008
+ amountCents,
15009
+ currency
15010
+ };
15011
+ case "instalment_plan": return {
15012
+ kind: "instalmentPlan",
15013
+ amountCents,
15014
+ currency
15015
+ };
15016
+ case "flexible_balance": return {
15017
+ kind: "flexibleBalance",
15018
+ amountCents,
15019
+ currency
15020
+ };
15021
+ }
15022
+ });
15023
+ return {
15024
+ ...eligibility,
15025
+ registration: { kind: "none" },
15026
+ availability: {
15027
+ kind: "available",
15028
+ remainingPlaces: null,
15029
+ waitlistEnabled: eligibility.waitlistEnabled
15030
+ },
15031
+ eligible: paymentOptions.length > 0,
15032
+ isFull: false,
15033
+ canJoinWaitlist: false,
15034
+ isFree: false,
15035
+ requiresPayment: true,
15036
+ canPayDirectly: paymentOptions.length > 0,
15037
+ paymentOptions,
15038
+ eligiblePasses: [],
15039
+ eligibleMemberships: [],
15040
+ ticketTypes: eligibility.ticketTypes.map((option) => ({
15041
+ ...option,
15042
+ availability: checkoutRecoveryOptionAvailability(option.availability)
15043
+ }))
15044
+ };
15045
+ }
15046
+ function canJoinWaitlistOutsideRecovery(event, attendanceMode, checkoutRecovery) {
15047
+ return !checkoutRecovery && event !== null && canJoinEventWaitlist(event, { attendanceMode });
15048
+ }
15049
+ //#endregion
15050
+ //#region ../blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.ts
15051
+ /** Recovery belongs to the selected booking subject; changing events resets its scope. */
15052
+ function useCheckoutRecovery(event, setStep) {
15053
+ const [recoveryEventId, setRecoveryEventId] = useState(null);
15054
+ return {
15055
+ checkoutRecovery: event !== null && recoveryEventId === event.selectionId,
15056
+ startCheckoutRecovery: useCallback(() => {
15057
+ if (!event) return;
15058
+ setRecoveryEventId(event.selectionId);
15059
+ setStep("select-tickets");
15060
+ }, [event, setStep])
15061
+ };
15062
+ }
15063
+ /** Authenticated pending bookings enter the same form-only recovery path as guests. */
15064
+ function useCheckoutRecoveryEligibility(eligibility, step, checkoutRecovery, startCheckoutRecovery) {
15065
+ const registrationKind = eligibility?.registration.kind;
15066
+ useEffect(() => {
15067
+ if ((step === "select-event" || step === "select-tickets" || step === "enter-details" || step === "select-payment") && registrationKind === "pending_payment" && !checkoutRecovery) startCheckoutRecovery();
15068
+ }, [
15069
+ registrationKind,
15070
+ step,
15071
+ checkoutRecovery,
15072
+ startCheckoutRecovery
15073
+ ]);
15074
+ return useMemo(() => checkoutRecovery ? getCheckoutRecoveryFormEligibility(eligibility) : eligibility, [checkoutRecovery, eligibility]);
15075
+ }
15076
+ //#endregion
15077
+ //#region ../blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.ts
15078
+ function resolveRegistrationRecoveryAction(step, action) {
15079
+ if (step === "payment-failed") return "payment-options";
15080
+ if (step === "verifying-payment" || step === "verifying-timeout" || step === "redirecting") return "payment-status";
15081
+ return action;
15082
+ }
15083
+ function canRecoverToWaitlist(eligibility) {
15084
+ return Boolean(eligibility?.isFull && eligibility.canJoinWaitlist);
15085
+ }
15086
+ function shouldRefreshAfterRegistrationError(step, action, enabled) {
15087
+ return enabled || step === "error" && action === "places";
15088
+ }
15089
+ function resetRegistrationAfterExpiry(input) {
15090
+ input.dispatchFlow({
15091
+ type: "reset",
15092
+ hasPreSelectedContext: input.hasPreSelectedContext
15093
+ });
15094
+ input.setSelectedTicketLines([]);
15095
+ input.setSelectedSlidingAmountInput("");
15096
+ const mode = input.preSelectedEvent?.deliveryMode;
15097
+ input.setSelectedAttendanceMode(mode === "online" || mode === "in_person" ? mode : null);
15098
+ input.setErrorMessage("");
15099
+ input.setPendingRegistrationReference(null);
15100
+ }
15101
+ /** Recovery never starts another payment. Unknown payment outcomes go to the portal. */
15102
+ function recoverRegistrationError(action, handlers) {
15103
+ switch (action) {
15104
+ case "none": return;
15105
+ case "portal":
15106
+ case "payment-status":
15107
+ window.location.assign("/portal");
15108
+ return;
15109
+ case "event":
15110
+ window.location.assign(window.location.pathname);
15111
+ return;
15112
+ case "retry":
15113
+ window.location.reload();
15114
+ return;
15115
+ case "details":
15116
+ handlers.clearError();
15117
+ handlers.setStep("enter-details");
15118
+ return;
15119
+ case "payment-options":
15120
+ case "places":
15121
+ handlers.refreshOptions();
15122
+ handlers.clearError();
15123
+ handlers.setStep(action === "places" ? handlers.canJoinWaitlist ? "enter-details" : "select-tickets" : "select-payment");
15124
+ return;
15125
+ case "start":
15126
+ handlers.refreshOptions();
15127
+ handlers.reset();
15128
+ return;
15129
+ }
15130
+ }
15131
+ //#endregion
14994
15132
  //#region ../blocks/src/system/runtime/nodes/event-registration/validation.ts
14995
15133
  function createInitialRegistrationFormData() {
14996
15134
  return {
@@ -15129,6 +15267,7 @@ function hasValidPricingOptionSelection(input) {
15129
15267
  const initialEligibilityLookupState = {
15130
15268
  tag: "idle",
15131
15269
  eligibility: null,
15270
+ settledRequestKey: null,
15132
15271
  error: null
15133
15272
  };
15134
15273
  function eligibilityLookupReducer(state, action) {
@@ -15137,16 +15276,19 @@ function eligibilityLookupReducer(state, action) {
15137
15276
  case "loading-started": return {
15138
15277
  tag: "loading",
15139
15278
  eligibility: state.eligibility,
15279
+ settledRequestKey: state.settledRequestKey,
15140
15280
  error: null
15141
15281
  };
15142
15282
  case "resolved": return {
15143
15283
  tag: "resolved",
15144
15284
  eligibility: action.eligibility,
15285
+ settledRequestKey: action.requestKey,
15145
15286
  error: null
15146
15287
  };
15147
15288
  case "failed": return {
15148
15289
  tag: "failed",
15149
15290
  eligibility: null,
15291
+ settledRequestKey: null,
15150
15292
  error: action.message
15151
15293
  };
15152
15294
  default: return assertNever(action);
@@ -15252,9 +15394,23 @@ function toRegistrationOptionsSubject(subject, attendanceMode) {
15252
15394
  function useEligibility(params) {
15253
15395
  return useEligibilityWithDeps(params, eventRegistrationHooksDeps);
15254
15396
  }
15397
+ function eligibilityRequestKey(params) {
15398
+ return JSON.stringify({
15399
+ enabled: params.enabled,
15400
+ refreshKey: params.refreshKey ?? 0,
15401
+ subject: params.subject,
15402
+ attendanceMode: params.attendanceMode ?? null,
15403
+ ticketSelections: params.ticketSelectionsKey,
15404
+ selectedSlidingAmount: params.selectedSlidingAmount ?? null
15405
+ });
15406
+ }
15255
15407
  function useEligibilityWithDeps(params, deps) {
15256
15408
  const api = deps.useBlockApi();
15257
15409
  const ticketSelectionsKey = JSON.stringify(normalizeTicketSelectionLines(params.ticketSelections));
15410
+ const requestKey = eligibilityRequestKey({
15411
+ ...params,
15412
+ ticketSelectionsKey
15413
+ });
15258
15414
  const [state, dispatch] = useReducer(eligibilityLookupReducer, initialEligibilityLookupState);
15259
15415
  const requestIdRef = useRef(0);
15260
15416
  useEffect(() => {
@@ -15287,7 +15443,8 @@ function useEligibilityWithDeps(params, deps) {
15287
15443
  if (cancelled || requestIdRef.current !== requestId) return;
15288
15444
  dispatch({
15289
15445
  type: "resolved",
15290
- eligibility: transformRegistrationOptionsResponse(result)
15446
+ eligibility: transformRegistrationOptionsResponse(result),
15447
+ requestKey
15291
15448
  });
15292
15449
  } catch {
15293
15450
  if (cancelled || requestIdRef.current !== requestId) return;
@@ -15316,6 +15473,8 @@ function useEligibilityWithDeps(params, deps) {
15316
15473
  return {
15317
15474
  state,
15318
15475
  eligibility: state.eligibility,
15476
+ settledRequestKey: state.settledRequestKey,
15477
+ requestKey,
15319
15478
  isLoading: state.tag === "loading",
15320
15479
  error: state.error,
15321
15480
  creditState
@@ -15514,6 +15673,10 @@ const eventRegistrationErrors = {
15514
15673
  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.",
15515
15674
  action: "payment-status"
15516
15675
  },
15676
+ paymentProviderUnavailable: {
15677
+ message: "We couldn’t reach the payment provider. Please try again in a minute.",
15678
+ action: "retry"
15679
+ },
15517
15680
  paymentPageUnavailable: {
15518
15681
  message: "We couldn’t open the payment page. Please refresh this page and try again. If this keeps happening, contact the organiser for help.",
15519
15682
  action: "retry"
@@ -15636,11 +15799,6 @@ function ensureWaitlistClaimLocationTracking() {
15636
15799
  } catch {}
15637
15800
  window.addEventListener("popstate", emitWaitlistClaimLocationChange);
15638
15801
  }
15639
- function getWaitlistClaimTokenFromUrl() {
15640
- if (typeof window === "undefined") return null;
15641
- const token = new URLSearchParams(window.location.search).get("waitlist_claim")?.trim() ?? "";
15642
- return token.length > 0 ? token : null;
15643
- }
15644
15802
  const useWaitlistClaimDeps = { useBlockApi };
15645
15803
  function subscribeToWaitlistClaimToken(callback) {
15646
15804
  if (typeof window === "undefined") return () => {};
@@ -15650,28 +15808,42 @@ function subscribeToWaitlistClaimToken(callback) {
15650
15808
  window.removeEventListener(WAITLIST_CLAIM_LOCATION_EVENT, callback);
15651
15809
  };
15652
15810
  }
15653
- function getWaitlistClaimTokenSnapshot() {
15654
- return getWaitlistClaimTokenFromUrl();
15811
+ function getWaitlistClaimLocationSnapshot() {
15812
+ return typeof window === "undefined" ? "" : window.location.search;
15813
+ }
15814
+ function parseWaitlistClaimCredential(search) {
15815
+ const params = new URLSearchParams(search);
15816
+ const token = params.get("waitlist_claim")?.trim();
15817
+ if (token) return {
15818
+ kind: "emailedToken",
15819
+ token
15820
+ };
15821
+ const entryId = params.get("waitlistEntry")?.trim();
15822
+ return entryId ? {
15823
+ kind: "portalOwnedEntry",
15824
+ entryId
15825
+ } : null;
15655
15826
  }
15656
15827
  function useWaitlistClaim() {
15657
15828
  return useWaitlistClaimWithDeps(useWaitlistClaimDeps);
15658
15829
  }
15659
15830
  function useWaitlistClaimWithDeps(deps) {
15660
- return useResolvedWaitlistClaim(deps, useSyncExternalStore(subscribeToWaitlistClaimToken, getWaitlistClaimTokenSnapshot, () => null));
15831
+ const locationSearch = useSyncExternalStore(subscribeToWaitlistClaimToken, getWaitlistClaimLocationSnapshot, () => "");
15832
+ return useResolvedWaitlistClaim(deps, useMemo(() => parseWaitlistClaimCredential(locationSearch), [locationSearch]));
15661
15833
  }
15662
- function useResolvedWaitlistClaim(deps, token) {
15834
+ function useResolvedWaitlistClaim(deps, credential) {
15663
15835
  const api = deps.useBlockApi();
15664
- const [state, dispatch] = useReducer(waitlistClaimReducer, Boolean(token), createInitialWaitlistClaimState);
15836
+ const [state, dispatch] = useReducer(waitlistClaimReducer, Boolean(credential), createInitialWaitlistClaimState);
15665
15837
  useEffect(() => {
15666
15838
  let cancelled = false;
15667
15839
  async function resolveClaim() {
15668
- if (!token) {
15840
+ if (!credential) {
15669
15841
  dispatch({ type: "cleared" });
15670
15842
  return;
15671
15843
  }
15672
15844
  dispatch({ type: "started" });
15673
15845
  try {
15674
- const result = await api.resolveWaitlistClaim({ claimToken: token });
15846
+ const result = credential.kind === "portalOwnedEntry" ? await api.resolveWaitlistClaim({ waitlistEntryId: credential.entryId }) : await api.resolveWaitlistClaim({ claimToken: credential.token });
15675
15847
  if (cancelled) return;
15676
15848
  dispatch({
15677
15849
  type: "resolved",
@@ -15689,9 +15861,10 @@ function useResolvedWaitlistClaim(deps, token) {
15689
15861
  return () => {
15690
15862
  cancelled = true;
15691
15863
  };
15692
- }, [api, token]);
15864
+ }, [api, credential]);
15693
15865
  return {
15694
- token,
15866
+ token: credential?.kind === "emailedToken" ? credential.token : null,
15867
+ entryId: credential?.kind === "portalOwnedEntry" ? credential.entryId : null,
15695
15868
  claim: getWaitlistClaim(state),
15696
15869
  error: getWaitlistClaimError(state),
15697
15870
  loginMessage: getWaitlistClaimLoginMessage(state),
@@ -16173,15 +16346,12 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
16173
16346
  * landed — a success, or a hand-off to checkout — because until then nobody
16174
16347
  * knows whether the first one committed.
16175
16348
  *
16176
- * Reusing it after a failure is safe even if the customer edits their
16177
- * details. The server consults the command record before it re-checks
16178
- * anything, so a submission that already booked is answered with the booking
16179
- * that exists — not refused for spending a credit or a claim that this very
16180
- * command already spent, and not treated as a second booking because a name
16181
- * or a note changed in between.
16349
+ * Identical retries retain the command after a lost response. Changed form
16350
+ * details get a new command so the server applies the new booking intent.
16182
16351
  */
16183
- const commandIdRef = useRef(null);
16184
- return async (method, passId, membershipId, selection, submitOptions) => {
16352
+ const commandRef = useRef(null);
16353
+ const inFlightRef = useRef(null);
16354
+ const submit = async (method, passId, membershipId, selection, submitOptions) => {
16185
16355
  const target = options.registrationTarget;
16186
16356
  if (!target) return {
16187
16357
  ok: false,
@@ -16189,44 +16359,34 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
16189
16359
  message: "Select an event to continue."
16190
16360
  };
16191
16361
  options.setStep("submitting");
16192
- const registrationCommandId = commandIdRef.current ?? deps.createClientCommandId();
16193
- commandIdRef.current = registrationCommandId;
16362
+ const registrationCommandId = commandRef.current?.id ?? deps.createClientCommandId();
16194
16363
  try {
16195
- const prepared = prepareSubmitContext(options, registrationCommandId, target, method, passId, membershipId, selection);
16364
+ let prepared = prepareSubmitContext(options, registrationCommandId, target, method, passId, membershipId, selection);
16196
16365
  if (prepared.subject.kind === "wholeSeries" && method === "stripe") {
16197
- commandIdRef.current = null;
16366
+ commandRef.current = null;
16198
16367
  return await submitWholeSeriesCheckout(options, deps, {
16199
16368
  ...prepared,
16200
16369
  subject: prepared.subject
16201
16370
  }, submitOptions);
16202
16371
  }
16372
+ const request = buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId);
16373
+ const intentKey = registrationRequestIntentKey(request);
16374
+ if (commandRef.current !== null && commandRef.current.intentKey !== intentKey) prepared = {
16375
+ ...prepared,
16376
+ registrationCommandId: deps.createClientCommandId()
16377
+ };
16378
+ commandRef.current = {
16379
+ id: prepared.registrationCommandId,
16380
+ intentKey
16381
+ };
16203
16382
  const result = await options.api.registerForEvent({
16204
- registrationCommandId: prepared.registrationCommandId,
16205
- subject: prepared.subject,
16206
- ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
16207
- selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
16208
- email: options.formData.email.trim().toLowerCase(),
16209
- name: options.formData.name.trim(),
16210
- phone: options.formData.phone.trim() || void 0,
16211
- notes: options.formData.notes.trim() || void 0,
16212
- consentAccepted: options.formData.consentAccepted,
16213
- altchaSolution: options.altchaSolution,
16214
- paymentMethod: method,
16215
- customerPassId: method === "pass" ? passId : void 0,
16216
- customerMembershipId: method === "membership" ? membershipId : void 0,
16217
- bundleProductId: prepared.bundleProductId,
16218
- claimToken: options.claimToken ?? void 0,
16219
- guests: prepared.guestsPayload
16383
+ ...request,
16384
+ registrationCommandId: prepared.registrationCommandId
16220
16385
  });
16221
- commandIdRef.current = null;
16222
- if (needsOccurrenceCheckout(result, method)) return await submitOccurrenceCheckout(options, deps, prepared, result, method, submitOptions);
16223
- options.setRegistrationResult(toRegistrationResult(result));
16224
- options.setStep("success");
16225
- return {
16226
- ok: true,
16227
- outcome: { kind: "completed" }
16228
- };
16386
+ commandRef.current = null;
16387
+ return await completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions);
16229
16388
  } catch (error) {
16389
+ if (error instanceof BlockApiError && error.tag === "registrationPreparationChanged") commandRef.current = null;
16230
16390
  const { message, action } = registrationErrorPresentation(error);
16231
16391
  options.setErrorAction?.(action);
16232
16392
  options.setErrorMessage(message);
@@ -16238,6 +16398,24 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
16238
16398
  };
16239
16399
  }
16240
16400
  };
16401
+ return (...args) => {
16402
+ if (inFlightRef.current) return inFlightRef.current;
16403
+ const pending = Promise.resolve().then(() => submit(...args));
16404
+ inFlightRef.current = pending;
16405
+ pending.finally(() => {
16406
+ if (inFlightRef.current === pending) inFlightRef.current = null;
16407
+ });
16408
+ return pending;
16409
+ };
16410
+ }
16411
+ async function completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions) {
16412
+ if (needsOccurrenceCheckout(result, method)) return await submitOccurrenceCheckout(options, deps, prepared, result, method, submitOptions);
16413
+ options.setRegistrationResult(toRegistrationResult(result));
16414
+ options.setStep("success");
16415
+ return {
16416
+ ok: true,
16417
+ outcome: { kind: "completed" }
16418
+ };
16241
16419
  }
16242
16420
  function toTicketSelectionRequests(lines) {
16243
16421
  return lines.map((line) => ({
@@ -16312,6 +16490,7 @@ async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions)
16312
16490
  altchaSolution: options.altchaSolution,
16313
16491
  guests: prepared.guestsPayload,
16314
16492
  claimToken: options.claimToken ?? void 0,
16493
+ waitlistEntryId: options.waitlistEntryId ?? void 0,
16315
16494
  discountCode: options.discountCode.trim() || void 0,
16316
16495
  collectionOptionKind: prepared.selectionSnapshot.collectionOptionKind,
16317
16496
  checkoutAttemptId,
@@ -16333,14 +16512,14 @@ async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions)
16333
16512
  }
16334
16513
  if (result.bypassed) return completeBypassedCheckout(options);
16335
16514
  if (!result.checkoutUrl) throw new Error("Checkout URL missing");
16336
- savePendingCheckout(options, deps, prepared, checkoutAttemptId, {
16515
+ savePendingCheckout(options, deps, prepared, result.checkoutAttemptId, {
16337
16516
  scope: "wholeSeries",
16338
16517
  registrationId: result.registrationId
16339
16518
  });
16340
16519
  return redirectToCheckout(result.checkoutUrl, submitOptions);
16341
16520
  }
16342
16521
  function needsOccurrenceCheckout(result, method) {
16343
- return result.scope === "occurrence" && !result.alreadyRegistered && result.status === "confirmed" && result.pendingPayment && [
16522
+ return result.scope === "occurrence" && result.status === "confirmed" && result.pendingPayment && [
16344
16523
  "stripe",
16345
16524
  "pass_bundle",
16346
16525
  "membership_bundle"
@@ -16360,6 +16539,7 @@ async function submitOccurrenceCheckout(options, deps, prepared, registration, m
16360
16539
  kind: "occurrence",
16361
16540
  attendeeId: registration.attendeeId
16362
16541
  },
16542
+ registrationCommandId: prepared.registrationCommandId,
16363
16543
  checkoutType: method === "pass_bundle" ? "pass_bundle" : method === "membership_bundle" ? "membership_bundle" : "event",
16364
16544
  productId: prepared.bundleProductId,
16365
16545
  discountCode: options.discountCode.trim() || void 0,
@@ -16402,6 +16582,151 @@ function redirectToCheckout(checkoutUrl, submitOptions) {
16402
16582
  }
16403
16583
  };
16404
16584
  }
16585
+ function registrationRequestIntentKey(request) {
16586
+ const { registrationCommandId: _command, altchaSolution: _proof, ...intent } = request;
16587
+ return JSON.stringify(intent);
16588
+ }
16589
+ function buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId) {
16590
+ return {
16591
+ registrationCommandId: prepared.registrationCommandId,
16592
+ subject: prepared.subject,
16593
+ ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
16594
+ selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
16595
+ email: options.formData.email.trim().toLowerCase(),
16596
+ name: options.formData.name.trim(),
16597
+ phone: options.formData.phone.trim() || void 0,
16598
+ notes: options.formData.notes.trim() || void 0,
16599
+ consentAccepted: options.formData.consentAccepted,
16600
+ altchaSolution: options.altchaSolution,
16601
+ paymentMethod: method,
16602
+ customerPassId: method === "pass" ? passId : void 0,
16603
+ customerMembershipId: method === "membership" ? membershipId : void 0,
16604
+ bundleProductId: prepared.bundleProductId,
16605
+ claimToken: options.claimToken ?? void 0,
16606
+ waitlistEntryId: options.waitlistEntryId ?? void 0,
16607
+ guests: prepared.guestsPayload
16608
+ };
16609
+ }
16610
+ //#endregion
16611
+ //#region ../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts
16612
+ function eventMatchesOccurrenceId(event, occurrenceId) {
16613
+ return event.registrationSubject.kind === "occurrence" && (event.registrationSubject.occurrenceId === occurrenceId || event.selectionId === occurrenceId);
16614
+ }
16615
+ function findEventByOccurrenceId(events, occurrenceId) {
16616
+ return events.find((event) => eventMatchesOccurrenceId(event, occurrenceId)) ?? null;
16617
+ }
16618
+ function findPreSelectedEvent(input) {
16619
+ const occurrenceContext = input.occurrenceContext;
16620
+ if (!occurrenceContext) return input.scopedEvents.length === 1 ? input.scopedEvents[0] ?? null : null;
16621
+ const contextDate = getBookingLocalDateKey(toScheduledBookingDateTime({
16622
+ startsAt: occurrenceContext.startsAt,
16623
+ timeZone: occurrenceContext.timeZone
16624
+ }));
16625
+ return input.scopedEvents.find((event) => eventMatchesOccurrenceId(event, occurrenceContext.id) || getBookingLocalDateKey(toScheduledBookingDateTime({
16626
+ startsAt: event.startsAt,
16627
+ timeZone: event.timeZone
16628
+ })) === contextDate) ?? null;
16629
+ }
16630
+ function resolveRegistrationTarget(input) {
16631
+ const subject = input.occurrenceContext ? {
16632
+ kind: "occurrence",
16633
+ occurrenceId: input.occurrenceContext.id
16634
+ } : input.selectedEvent?.registrationSubject ?? null;
16635
+ if (!subject) return null;
16636
+ return {
16637
+ subject,
16638
+ selectedEventId: input.selectedEvent?.selectionId ?? null
16639
+ };
16640
+ }
16641
+ function resolveEventRequiresPayment(input) {
16642
+ if (input.eligibility) return input.eligibility.requiresPayment;
16643
+ if (input.selectedTicketType) return input.selectedTicketType.priceAmount > 0;
16644
+ if (!input.event) return false;
16645
+ return publicEventPricingType(input.event.pricing) === "paid";
16646
+ }
16647
+ function resolveDiscountContext(input) {
16648
+ const selection = input.paymentSelection.method ? input.paymentSelection : null;
16649
+ if (!input.event) return null;
16650
+ if (selection?.method === "pass_bundle" && selection.bundlePassId) return {
16651
+ type: "pass",
16652
+ passId: selection.bundlePassId
16653
+ };
16654
+ if (selection?.method === "membership_bundle" && selection.bundleMembershipId) return {
16655
+ type: "membership",
16656
+ membershipId: selection.bundleMembershipId
16657
+ };
16658
+ if (!input.eventRequiresPayment) return null;
16659
+ if (input.ticketsCount <= 0) return null;
16660
+ if (selection?.method && selection.method !== "stripe") return null;
16661
+ return {
16662
+ type: "event",
16663
+ eventSeriesId: input.event.seriesId,
16664
+ eventCategoryId: input.event.eventCategory?.id ?? null,
16665
+ ticketsCount: input.ticketsCount
16666
+ };
16667
+ }
16668
+ //#endregion
16669
+ //#region ../blocks/src/system/runtime/nodes/event-registration/useSettledCommerceView.ts
16670
+ function buildCandidate(input) {
16671
+ if (!input.eligibilityIsSettled || !input.eligibility || !input.currentEvent) return null;
16672
+ return {
16673
+ eventSelectionId: input.currentEvent.selectionId,
16674
+ discountContext: resolveDiscountContext({
16675
+ paymentSelection: input.paymentSelection,
16676
+ event: input.currentEvent,
16677
+ eventRequiresPayment: input.eventRequiresPayment,
16678
+ ticketsCount: input.ticketsCount
16679
+ }),
16680
+ subtotalCents: input.eligibility.price,
16681
+ summaryLines: input.eligibility.ticketLines.map((line) => ({
16682
+ pricingOptionId: line.pricingOptionId,
16683
+ label: line.label,
16684
+ quantity: line.quantity,
16685
+ unitPriceCents: line.unitPriceCents,
16686
+ subtotalCents: line.subtotalCents
16687
+ }))
16688
+ };
16689
+ }
16690
+ function eligibilityIsSettled(result) {
16691
+ return result.settledRequestKey === result.requestKey;
16692
+ }
16693
+ function viewIsStale(view, currentEvent, eligibilityState) {
16694
+ return view.eventSelectionId !== currentEvent?.selectionId || eligibilityState?.tag === "failed" || eligibilityState?.tag === "idle";
16695
+ }
16696
+ function requestIsSettled(discountUi) {
16697
+ return discountUi.discountAvailabilityRequestKey === "disabled" || discountUi.settledDiscountAvailabilityRequestKey === discountUi.discountAvailabilityRequestKey;
16698
+ }
16699
+ function discountRequest(view) {
16700
+ const discountContext = view?.discountContext ?? null;
16701
+ return {
16702
+ discountContext,
16703
+ subtotalCents: discountContext?.type === "event" && view?.subtotalCents !== null ? view?.subtotalCents : void 0
16704
+ };
16705
+ }
16706
+ function useSettledCommerceView(input) {
16707
+ const candidate = buildCandidate({
16708
+ eligibilityIsSettled: eligibilityIsSettled(input.eligibilityResult),
16709
+ eligibility: input.eligibility,
16710
+ currentEvent: input.currentEvent,
16711
+ paymentSelection: input.paymentSelection,
16712
+ eventRequiresPayment: input.eventRequiresPayment,
16713
+ ticketsCount: input.ticketsCount
16714
+ });
16715
+ const settledRef = useRef(candidate);
16716
+ if (settledRef.current && viewIsStale(settledRef.current, input.currentEvent, input.eligibilityResult.state)) settledRef.current = null;
16717
+ const requestView = candidate ?? settledRef.current;
16718
+ const discountUi = input.useDiscountCodeUi({
16719
+ api: input.api,
16720
+ ...discountRequest(requestView)
16721
+ });
16722
+ if (candidate && requestIsSettled(discountUi)) settledRef.current = candidate;
16723
+ return {
16724
+ discountUi,
16725
+ discountContext: settledRef.current?.discountContext ?? null,
16726
+ ticketSelectionSubtotalCents: settledRef.current?.subtotalCents ?? null,
16727
+ ticketSelectionSummaryLines: settledRef.current?.summaryLines ?? []
16728
+ };
16729
+ }
16405
16730
  //#endregion
16406
16731
  //#region ../blocks/src/system/runtime/nodes/event-registration/eventPaymentOptions.ts
16407
16732
  function getApprovedDirectPaymentCollectionOptionKinds(paymentOptions) {
@@ -17044,64 +17369,6 @@ function getStepLabel(step) {
17044
17369
  }
17045
17370
  }
17046
17371
  //#endregion
17047
- //#region ../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts
17048
- function eventMatchesOccurrenceId(event, occurrenceId) {
17049
- return event.registrationSubject.kind === "occurrence" && (event.registrationSubject.occurrenceId === occurrenceId || event.selectionId === occurrenceId);
17050
- }
17051
- function findEventByOccurrenceId(events, occurrenceId) {
17052
- return events.find((event) => eventMatchesOccurrenceId(event, occurrenceId)) ?? null;
17053
- }
17054
- function findPreSelectedEvent(input) {
17055
- const occurrenceContext = input.occurrenceContext;
17056
- if (!occurrenceContext) return input.scopedEvents.length === 1 ? input.scopedEvents[0] ?? null : null;
17057
- const contextDate = getBookingLocalDateKey(toScheduledBookingDateTime({
17058
- startsAt: occurrenceContext.startsAt,
17059
- timeZone: occurrenceContext.timeZone
17060
- }));
17061
- return input.scopedEvents.find((event) => eventMatchesOccurrenceId(event, occurrenceContext.id) || getBookingLocalDateKey(toScheduledBookingDateTime({
17062
- startsAt: event.startsAt,
17063
- timeZone: event.timeZone
17064
- })) === contextDate) ?? null;
17065
- }
17066
- function resolveRegistrationTarget(input) {
17067
- const subject = input.occurrenceContext ? {
17068
- kind: "occurrence",
17069
- occurrenceId: input.occurrenceContext.id
17070
- } : input.selectedEvent?.registrationSubject ?? null;
17071
- if (!subject) return null;
17072
- return {
17073
- subject,
17074
- selectedEventId: input.selectedEvent?.selectionId ?? null
17075
- };
17076
- }
17077
- function resolveEventRequiresPayment(input) {
17078
- if (input.eligibility) return input.eligibility.requiresPayment;
17079
- if (input.selectedTicketType) return input.selectedTicketType.priceAmount > 0;
17080
- if (!input.event) return false;
17081
- return publicEventPricingType(input.event.pricing) === "paid";
17082
- }
17083
- function resolveDiscountContext(input) {
17084
- const selection = input.paymentSelection.method ? input.paymentSelection : null;
17085
- if (!input.event) return null;
17086
- if (selection?.method === "pass_bundle" && selection.bundlePassId) return {
17087
- type: "pass",
17088
- passId: selection.bundlePassId
17089
- };
17090
- if (selection?.method === "membership_bundle" && selection.bundleMembershipId) return {
17091
- type: "membership",
17092
- membershipId: selection.bundleMembershipId
17093
- };
17094
- if (!input.eventRequiresPayment) return null;
17095
- if (input.ticketsCount <= 0) return null;
17096
- if (selection?.method && selection.method !== "stripe") return null;
17097
- return {
17098
- type: "event",
17099
- eventSeriesId: input.event.seriesId,
17100
- eventCategoryId: input.event.eventCategory?.id ?? null,
17101
- ticketsCount: input.ticketsCount
17102
- };
17103
- }
17104
- //#endregion
17105
17372
  //#region ../blocks/src/system/blocks/events/shared/runGrouping.ts
17106
17373
  function isWholeSeriesPublicEvent(event) {
17107
17374
  return event.bookingScope === "whole_series";
@@ -17340,10 +17607,6 @@ function isSoldOutWithoutWaitlist(input) {
17340
17607
  }
17341
17608
  //#endregion
17342
17609
  //#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.ts
17343
- function resolveDiscountSubtotalCents(context, subtotalCents) {
17344
- if (context?.type !== "event" || subtotalCents === null) return void 0;
17345
- return subtotalCents;
17346
- }
17347
17610
  function usesTieredPricing(event) {
17348
17611
  return event !== null && event !== void 0 ? publicEventPricingStrategy(event.pricing) === "tiered" : false;
17349
17612
  }
@@ -17424,14 +17687,28 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17424
17687
  }), [options.occurrenceContext, selectedEvent]);
17425
17688
  const registrationOccurrenceId = getRegistrationOccurrenceId(registrationTarget);
17426
17689
  const currentEvent = selectedEvent ?? preSelectedEvent;
17690
+ const setStep = useCallback((nextStep) => {
17691
+ dispatchFlow({
17692
+ type: "set-step",
17693
+ step: nextStep
17694
+ });
17695
+ }, []);
17696
+ const { checkoutRecovery, startCheckoutRecovery } = useCheckoutRecovery(currentEvent, setStep);
17427
17697
  const currentEventUsesTicketTypes = usesTieredPricing(currentEvent);
17428
- const currentCanJoinWaitlist = currentEvent ? canJoinEventWaitlist(currentEvent, { attendanceMode: selectedAttendanceMode }) : false;
17698
+ const currentCanJoinWaitlist = canJoinWaitlistOutsideRecovery(currentEvent, selectedAttendanceMode, checkoutRecovery);
17429
17699
  const usesTicketTypeSelections = currentEventUsesTicketTypes && !currentCanJoinWaitlist;
17430
17700
  const eventTicketTypesForSelection = useMemo(() => getVisibleTicketTypes({
17431
17701
  event: currentEvent,
17432
17702
  eligibility: null,
17433
17703
  selectedAttendanceMode
17434
- }), [currentEvent, selectedAttendanceMode]);
17704
+ }).map((option) => checkoutRecovery ? {
17705
+ ...option,
17706
+ availability: checkoutRecoveryOptionAvailability(option.availability)
17707
+ } : option), [
17708
+ currentEvent,
17709
+ selectedAttendanceMode,
17710
+ checkoutRecovery
17711
+ ]);
17435
17712
  const normalizedSelectedTicketLines = useMemo(() => normalizeTicketSelectionLines(selectedTicketLines), [selectedTicketLines]);
17436
17713
  const ticketTypeSelectionTotal = useMemo(() => getTicketSelectionTotal(normalizedSelectedTicketLines), [normalizedSelectedTicketLines]);
17437
17714
  const ticketsCount = usesTicketTypeSelections ? ticketTypeSelectionTotal : flowState.ticketsCount;
@@ -17469,17 +17746,11 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17469
17746
  isAuthenticated: portalAuthState === "authenticated",
17470
17747
  occurrenceId: registrationOccurrenceId
17471
17748
  });
17472
- const eligibility = eligibilityResult.eligibility;
17749
+ const eligibility = useCheckoutRecoveryEligibility(eligibilityResult.eligibility, step, checkoutRecovery, startCheckoutRecovery);
17473
17750
  const eligibilityLoading = eligibilityResult.isLoading;
17474
17751
  const eligibilityError = eligibilityResult.error;
17475
17752
  const portalCreditState = eligibilityResult.creditState;
17476
17753
  const registrationState = eligibility?.registration ?? { kind: "none" };
17477
- const setStep = useCallback((nextStep) => {
17478
- dispatchFlow({
17479
- type: "set-step",
17480
- step: nextStep
17481
- });
17482
- }, []);
17483
17754
  const setTicketsCount = useCallback((nextTicketsCount) => {
17484
17755
  dispatchFlow({
17485
17756
  type: "set-tickets-count",
@@ -17587,10 +17858,14 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17587
17858
  event: currentEvent,
17588
17859
  eligibility,
17589
17860
  selectedAttendanceMode
17590
- }), [
17861
+ }).map((option) => checkoutRecovery ? {
17862
+ ...option,
17863
+ availability: checkoutRecoveryOptionAvailability(option.availability)
17864
+ } : option), [
17591
17865
  currentEvent,
17592
17866
  selectedAttendanceMode,
17593
- eligibility
17867
+ eligibility,
17868
+ checkoutRecovery
17594
17869
  ]);
17595
17870
  const singleSelectedPricingOptionId = getSingleSelectedPricingOptionId(normalizedSelectedTicketLines);
17596
17871
  const selectedTicketType = useMemo(() => findSelectedTicketType({
@@ -17614,8 +17889,12 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17614
17889
  const event = currentEvent;
17615
17890
  if (!usesTieredPricing(event)) return false;
17616
17891
  if ((event.deliveryMode ?? "in_person") === "hybrid" && !selectedAttendanceMode) return false;
17617
- return !canJoinEventWaitlist(event, { attendanceMode: selectedAttendanceMode });
17618
- }, [currentEvent, selectedAttendanceMode]);
17892
+ return checkoutRecovery || !canJoinEventWaitlist(event, { attendanceMode: selectedAttendanceMode });
17893
+ }, [
17894
+ currentEvent,
17895
+ selectedAttendanceMode,
17896
+ checkoutRecovery
17897
+ ]);
17619
17898
  const hasValidTicketSelection = hasValidPricingOptionSelection({
17620
17899
  selectionRequired: ticketTypeSelectionRequired,
17621
17900
  lines: normalizedSelectedTicketLines,
@@ -17779,30 +18058,15 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17779
18058
  }
17780
18059
  setStep("select-tickets");
17781
18060
  };
17782
- const discountContext = useMemo(() => resolveDiscountContext({
17783
- paymentSelection,
17784
- event: currentEvent,
17785
- eventRequiresPayment,
17786
- ticketsCount
17787
- }), [
18061
+ const { discountUi, discountContext, ticketSelectionSubtotalCents, ticketSelectionSummaryLines } = useSettledCommerceView({
18062
+ api,
18063
+ useDiscountCodeUi: deps.useDiscountCodeUi,
18064
+ eligibilityResult,
18065
+ eligibility,
17788
18066
  currentEvent,
17789
18067
  eventRequiresPayment,
17790
18068
  paymentSelection,
17791
18069
  ticketsCount
17792
- ]);
17793
- const ticketSelectionSubtotalCents = eligibility?.price ?? null;
17794
- const ticketSelectionSummaryLines = useMemo(() => eligibility?.ticketLines.map((line) => ({
17795
- pricingOptionId: line.pricingOptionId,
17796
- label: line.label,
17797
- quantity: line.quantity,
17798
- unitPriceCents: line.unitPriceCents,
17799
- subtotalCents: line.subtotalCents
17800
- })) ?? [], [eligibility]);
17801
- const discountSubtotalCents = resolveDiscountSubtotalCents(discountContext, ticketSelectionSubtotalCents);
17802
- const discountUi = deps.useDiscountCodeUi({
17803
- api,
17804
- discountContext,
17805
- subtotalCents: discountSubtotalCents
17806
18070
  });
17807
18071
  const selectionMethod = paymentSelection.method;
17808
18072
  const shouldShowDiscountToggle = discountContext !== null && discountUi.manualCodeEntryAllowed && (selectionMethod === "stripe" || selectionMethod === "pass_bundle" || selectionMethod === "membership_bundle");
@@ -17819,6 +18083,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17819
18083
  guests,
17820
18084
  discountCode: discountUi.discountCode,
17821
18085
  claimToken: waitlistClaim.token,
18086
+ waitlistEntryId: waitlistClaim.entryId,
17822
18087
  setPendingRegistrationReference,
17823
18088
  setStep,
17824
18089
  setRegistrationResult: (result) => setRegistrationResult(result),
@@ -17881,6 +18146,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17881
18146
  scopedEvents,
17882
18147
  preSelectedEvent,
17883
18148
  hasPreSelectedContext,
18149
+ checkoutRecovery,
18150
+ startCheckoutRecovery,
17884
18151
  step,
17885
18152
  setStep,
17886
18153
  selectedEvent,