@riverbankcms/sdk 0.88.0 → 0.90.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 (198) hide show
  1. package/README.md +27 -4
  2. package/dist/{PreviewEditorSidebar-EVRS3C7T.mjs → PreviewEditorSidebar-KVXNF3VW.mjs} +3 -3
  3. package/dist/{PreviewEditorUI-54WD4IGE.mjs → PreviewEditorUI-J3JN5Z7T.mjs} +3 -3
  4. package/dist/SdkPreviewModeRuntime-UBL6MSNP.mjs +8 -0
  5. package/dist/_dts/ai/src/contracts/proposals.d.ts +216 -0
  6. package/dist/_dts/altcha/src/AltchaWidget.d.ts +1 -1
  7. package/dist/_dts/api/src/accessAdmin.d.ts +7 -0
  8. package/dist/_dts/api/src/bookingOperations.d.ts +2 -0
  9. package/dist/_dts/api/src/bookingRecords.d.ts +4 -2
  10. package/dist/_dts/api/src/bookings.d.ts +3 -1
  11. package/dist/_dts/api/src/endpoints.d.ts +8 -0
  12. package/dist/_dts/api/src/index.d.ts +7 -6
  13. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +15 -5
  14. package/dist/_dts/api/src/request.d.ts +21 -0
  15. package/dist/_dts/api/src/sdk-event-upsert.d.ts +3 -1
  16. package/dist/_dts/api/src/sdkContracts.d.ts +2 -0
  17. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +5 -1
  18. package/dist/_dts/api/src/siteMembers.d.ts +6 -1
  19. package/dist/_dts/api/src/types.d.ts +4 -2
  20. package/dist/_dts/api/src/url.d.ts +6 -3
  21. package/dist/_dts/block-form/src/utils/visibleWhen.d.ts +1 -0
  22. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterThumbnailCard.d.ts +5 -1
  23. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterThumbnailGrid.d.ts +9 -1
  24. package/dist/_dts/block-form/src/widgets/RepeaterField/components/index.d.ts +1 -0
  25. package/dist/_dts/blocks/src/contracts/non-block-islands.d.ts +7 -11
  26. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +6 -0
  27. package/dist/_dts/blocks/src/index.d.ts +2 -1
  28. package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +14 -6
  29. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +4 -4
  30. package/dist/_dts/blocks/src/system/blocks/hero.d.ts +0 -2
  31. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +3 -3
  32. package/dist/_dts/blocks/src/system/blocks/shop.shared.d.ts +8 -0
  33. package/dist/_dts/blocks/src/system/constants/events.d.ts +4 -1
  34. package/dist/_dts/blocks/src/system/icons/cta.d.ts +3 -3
  35. package/dist/_dts/blocks/src/system/icons/index.d.ts +1 -0
  36. package/dist/_dts/blocks/src/system/icons/registry.d.ts +2 -2
  37. package/dist/_dts/blocks/src/system/icons/semantic.d.ts +3 -3
  38. package/dist/_dts/blocks/src/system/icons/svg.d.ts +72 -0
  39. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +3 -1
  40. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -0
  41. package/dist/_dts/blocks/src/system/runtime/api/types.d.ts +18 -5
  42. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +51 -6
  43. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +24 -0
  44. package/dist/_dts/blocks/src/system/runtime/hooks/loadStateError.d.ts +1 -0
  45. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableDates.d.ts +1 -1
  46. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableDates.state.d.ts +55 -0
  47. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableSlots.state.d.ts +39 -0
  48. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingFormConfig.d.ts +4 -27
  49. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingFormConfig.state.d.ts +40 -0
  50. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +20 -0
  51. package/dist/_dts/blocks/src/system/runtime/hooks/useEventFilters.state.d.ts +31 -0
  52. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.d.ts +3 -3
  53. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.state.d.ts +39 -0
  54. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.d.ts +2 -2
  55. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/logic.d.ts +1 -17
  56. package/dist/_dts/blocks/src/system/runtime/nodes/event-details.client.d.ts +5 -9
  57. package/dist/_dts/blocks/src/system/runtime/nodes/event-details.server.d.ts +5 -9
  58. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +2 -1
  59. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventPaymentOptions.d.ts +24 -0
  60. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +5 -0
  61. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.d.ts +4 -4
  62. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.state.d.ts +50 -0
  63. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +2 -2
  64. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +21 -0
  65. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.server.d.ts +1 -1
  66. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +11 -1
  67. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +2 -1
  68. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +11 -1
  69. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventPaginatedListView.client.d.ts +1 -1
  70. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/calendarViewOptions.d.ts +10 -0
  71. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventProductEligibility.d.ts +24 -0
  72. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.client.state.d.ts +24 -2
  73. package/dist/_dts/blocks/src/system/runtime/nodes/shared/MagicLinkForm.state.d.ts +24 -0
  74. package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +5 -2
  75. package/dist/_dts/blocks/src/system/runtime/nodes/shop-checkout-form.d.ts +2 -2
  76. package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.state.d.ts +35 -0
  77. package/dist/_dts/content-model/src/entry-slots/index.d.ts +1 -0
  78. package/dist/_dts/content-model/src/entry-slots/sdkBlocks.d.ts +21 -0
  79. package/dist/_dts/content-model/src/entry-slots/types.d.ts +61 -0
  80. package/dist/_dts/core/src/branded.d.ts +7 -0
  81. package/dist/_dts/core/src/index.d.ts +1 -0
  82. package/dist/_dts/core/src/money-input.d.ts +18 -0
  83. package/dist/_dts/core/src/site-route-target.d.ts +40 -0
  84. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +209 -2
  85. package/dist/_dts/media-core/src/fileDomain.d.ts +4 -0
  86. package/dist/_dts/media-editor/src/MediaEditor.d.ts +2 -1
  87. package/dist/_dts/media-editor/src/fieldUi.d.ts +6 -0
  88. package/dist/_dts/media-editor/src/index.d.ts +1 -1
  89. package/dist/_dts/preview-next/src/client/index.d.ts +1 -0
  90. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +3 -2
  91. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +3 -2
  92. package/dist/_dts/preview-next/src/client/preview/PreviewThemedSiteDocument.d.ts +3 -2
  93. package/dist/_dts/preview-next/src/client/preview/SiteChromeEditableSurface.d.ts +2 -2
  94. package/dist/_dts/preview-next/src/client/preview/themeRuntime.d.ts +6 -0
  95. package/dist/_dts/preview-next/src/client/sdk/SdkPreviewMode.d.ts +2 -1
  96. package/dist/_dts/sdk/src/cli/commands/pull-dated-offering-scope.d.ts +10 -0
  97. package/dist/_dts/sdk/src/cli/content/reader.d.ts +12 -5
  98. package/dist/_dts/sdk/src/client/management/types.d.ts +6 -55
  99. package/dist/_dts/sdk/src/client/runtimeCachePolicy.d.ts +160 -0
  100. package/dist/_dts/sdk/src/client/types.d.ts +26 -1
  101. package/dist/_dts/sdk/src/components.d.ts +1 -0
  102. package/dist/_dts/sdk/src/config/field-definitions.d.ts +3 -1
  103. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +3 -1
  104. package/dist/_dts/sdk/src/index.d.ts +3 -1
  105. package/dist/_dts/sdk/src/next/types.d.ts +8 -11
  106. package/dist/_dts/sdk/src/preview-next/client/index.d.ts +1 -1
  107. package/dist/_dts/sdk/src/rendering/blocks-theme-scope.d.ts +2 -1
  108. package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +8 -7
  109. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +5 -6
  110. package/dist/_dts/sdk/src/rendering/index.d.ts +1 -0
  111. package/dist/_dts/sdk/src/rendering/server.d.ts +1 -0
  112. package/dist/_dts/sdk/src/rendering/themeRuntime.d.ts +26 -0
  113. package/dist/_dts/sdk/src/version.d.ts +1 -1
  114. package/dist/_dts/site-commands/src/commands.d.ts +18 -0
  115. package/dist/_dts/theme-core/src/ResponsiveScope.d.ts +12 -0
  116. package/dist/_dts/theme-core/src/accordions/types.d.ts +1 -1
  117. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +2 -2
  118. package/dist/_dts/theme-core/src/buttons/types.d.ts +5 -5
  119. package/dist/_dts/theme-core/src/cards/types.d.ts +2 -2
  120. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  121. package/dist/_dts/theme-core/src/index.d.ts +2 -0
  122. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +21 -21
  123. package/dist/_dts/theme-core/src/schema.d.ts +18 -18
  124. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +2 -2
  125. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +2 -2
  126. package/dist/_dts/theme-core/src/site-styles/logoBranding.d.ts +4 -4
  127. package/dist/_dts/theme-core/src/themeRuntime.d.ts +11 -0
  128. package/dist/{chunk-ER4UIW4X.mjs → chunk-AEOYWPE4.mjs} +91 -55
  129. package/dist/{chunk-O4LVYUVH.mjs → chunk-BOQXMCSP.mjs} +147 -101
  130. package/dist/{chunk-HVOBXA3Y.mjs → chunk-GSPFFUVB.mjs} +2 -2
  131. package/dist/{chunk-7KOO7RPP.mjs → chunk-PMBB6MQ7.mjs} +2273 -1113
  132. package/dist/{chunk-K3JWH6HE.mjs → chunk-RQ3XZ4SJ.mjs} +9 -1
  133. package/dist/{chunk-YDMBIIS5.mjs → chunk-UG7I7S7W.mjs} +1 -1
  134. package/dist/cli/index.mjs +1564 -546
  135. package/dist/cli/init-docs/content/cli-reference.md +6 -1
  136. package/dist/cli/init-docs/content/content-management.md +27 -0
  137. package/dist/client/{accordion-PT5CGW5N.mjs → accordion-GXQNWQ6O.mjs} +2 -2
  138. package/dist/client/{bookingForm-2HLRTEYS.mjs → bookingForm-STLUJ36H.mjs} +206 -335
  139. package/dist/client/bookings.mjs +821 -413
  140. package/dist/client/{carousel-Z2LKYSWA.mjs → carousel-CVRN6EPP.mjs} +4 -3
  141. package/dist/client/{cart-ND5IK4A6.mjs → cart-IYIBA5CL.mjs} +8 -8
  142. package/dist/client/{checkout-EYUSGAY7.mjs → checkout-O3BGM4GS.mjs} +8 -8
  143. package/dist/client/chunk-4RTFGHZN.mjs +433 -0
  144. package/dist/client/{chunk-DIRW2LNG.mjs → chunk-6DPXDOIL.mjs} +336 -225
  145. package/dist/client/chunk-6N7YRNYU.mjs +183 -0
  146. package/dist/client/{chunk-O5JNI3E4.mjs → chunk-7DH35FGA.mjs} +2 -2
  147. package/dist/client/{chunk-S4G65LGR.mjs → chunk-D3ETC2SU.mjs} +1 -1
  148. package/dist/client/{chunk-BAWHZ5GM.mjs → chunk-DAS5CIER.mjs} +460 -157
  149. package/dist/client/{chunk-6DVPO44G.mjs → chunk-FHU6PFPM.mjs} +1 -1
  150. package/dist/client/{chunk-SDIYSQAY.mjs → chunk-HIHOQGIP.mjs} +2 -3
  151. package/dist/client/{chunk-BL66UWGD.mjs → chunk-MFPKS6QS.mjs} +13 -16
  152. package/dist/client/{chunk-X7GVFB7Y.mjs → chunk-NBFRJ5NB.mjs} +157 -5
  153. package/dist/client/{chunk-WCVK4MBJ.mjs → chunk-VFHZLZAC.mjs} +1 -1
  154. package/dist/client/{chunk-GOFO7HRH.mjs → chunk-WHZQDPBZ.mjs} +19 -1
  155. package/dist/client/{chunk-MHBEWDT7.mjs → chunk-Z62JYS5O.mjs} +122 -50
  156. package/dist/client/client.mjs +5979 -5198
  157. package/dist/client/{courseRegistration-H3AZBUEG.mjs → courseRegistration-2D3ACMJR.mjs} +20 -58
  158. package/dist/client/{eventCalendar-FPKJGLGS.mjs → eventCalendar-QY4UZUFF.mjs} +11 -11
  159. package/dist/client/{eventCombined-QCGIZBUY.mjs → eventCombined-RRCDKJC2.mjs} +11 -11
  160. package/dist/client/{eventDetails-HIT3BJWU.mjs → eventDetails-YO335BUT.mjs} +11 -11
  161. package/dist/client/{eventListing-R4HNWJDN.mjs → eventListing-PXA6GFQ3.mjs} +11 -11
  162. package/dist/client/{eventRegistration-Q7BYY5HF.mjs → eventRegistration-2ZHEDDXO.mjs} +11 -11
  163. package/dist/client/{form-NI6YOG6S.mjs → form-ZS6KX4U2.mjs} +7 -7
  164. package/dist/client/{headerSection-SDYGII36.mjs → headerSection-QK5SLIIB.mjs} +3 -3
  165. package/dist/client/hooks.mjs +1102 -1029
  166. package/dist/client/{locationMap-BDETEUQD.mjs → locationMap-GFNIUD2X.mjs} +3 -3
  167. package/dist/client/{newsletterForm-EKYIU67X.mjs → newsletterForm-PGLTTCUG.mjs} +61 -25
  168. package/dist/client/{productDetail-5UTGNN76.mjs → productDetail-OPBE5ZPI.mjs} +8 -8
  169. package/dist/client/{productList-7YA5KXZQ.mjs → productList-NI72Q62Z.mjs} +8 -8
  170. package/dist/client/rendering/client.mjs +4390 -4245
  171. package/dist/client/rendering/islands.mjs +19 -19
  172. package/dist/client/rendering.mjs +3327 -3181
  173. package/dist/client/{shop-AIMUMZYC.mjs → shop-3ZQPEWYI.mjs} +8 -8
  174. package/dist/client/spam-protection.mjs +4 -5
  175. package/dist/preview-next/before-render.mjs +20 -2
  176. package/dist/preview-next/client/runtime.mjs +5 -5
  177. package/dist/preview-next/middleware.mjs +18 -0
  178. package/dist/{sdk-runtime-NW472WNT.mjs → sdk-runtime-FSHXCWDS.mjs} +6 -6
  179. package/dist/server/components.mjs +2580 -2783
  180. package/dist/server/config-validation.mjs +1334 -1261
  181. package/dist/server/config.mjs +1334 -1261
  182. package/dist/server/data.mjs +1102 -1029
  183. package/dist/server/index.mjs +1097 -476
  184. package/dist/server/navigation.mjs +20 -30
  185. package/dist/server/next.mjs +3282 -2847
  186. package/dist/server/page-converter.mjs +1009 -946
  187. package/dist/server/prebuild.mjs +1 -1
  188. package/dist/server/rendering/server.mjs +2580 -2783
  189. package/dist/server/rendering.mjs +2586 -2789
  190. package/dist/server/routing.mjs +1440 -1053
  191. package/dist/server/server.mjs +1886 -1153
  192. package/dist/server/theme-bridge.mjs +34 -5
  193. package/dist/styles/index.css +26 -0
  194. package/package.json +3 -2
  195. package/dist/SdkPreviewModeRuntime-ZALZDJEK.mjs +0 -8
  196. package/dist/client/chunk-H4MHEXYS.mjs +0 -184
  197. package/dist/client/chunk-ZFHRN6W2.mjs +0 -66
  198. /package/dist/client/{chunk-LI2C6M5O.mjs → chunk-25W2EQUN.mjs} +0 -0
@@ -1,16 +1,15 @@
1
1
  "use client";
2
- import { usePolling } from './chunk-H4MHEXYS.mjs';
3
- import { SpinnerNode } from './chunk-6DVPO44G.mjs';
4
- import { useDiscountCodeUi } from './chunk-ZFHRN6W2.mjs';
2
+ import { buildBookingPaymentSelectionViewModel, usePolling } from './chunk-4RTFGHZN.mjs';
3
+ import { SpinnerNode } from './chunk-FHU6PFPM.mjs';
5
4
  import { buildRouteIslandApiConfig } from './chunk-L4J5Y62O.mjs';
6
- import { scrollToBlock, buildCheckoutReturnUrls, DiscountCodeDisclosure, formatPrice } from './chunk-X7GVFB7Y.mjs';
5
+ import { scrollToBlock, useDiscountCodeUi, buildCheckoutReturnUrls, DiscountCodeDisclosure } from './chunk-NBFRJ5NB.mjs';
7
6
  import { FieldValidationMessage, getFieldValidationControlProps } from './chunk-3DCJ45Z2.mjs';
8
7
  import './chunk-WBQG7VJA.mjs';
9
- import { isSpamProtectionEnabled, getChallengeUrl, AltchaWidget } from './chunk-SDIYSQAY.mjs';
10
- import { BlockApiProvider, useBlockApi, FeedbackMessage } from './chunk-GOFO7HRH.mjs';
8
+ import { isSpamProtectionEnabled, getChallengeUrl, AltchaWidget } from './chunk-HIHOQGIP.mjs';
9
+ import { BlockApiProvider, useBlockApi, FeedbackMessage } from './chunk-WHZQDPBZ.mjs';
11
10
  import { mountReactIsland } from './chunk-N7PBWBWQ.mjs';
12
- import { defineIslandPropsDecoder, resolveBookingSiteId, resolveDefaultBookingServiceId, getBookingRedirectStateFromLocation, deriveBookingFormViewState, logger, getBookingSuccessMessage, resolveAppointmentCheckoutVerificationState, themeButtonClassName, toSelectedCollectionOptionKind, assertNever11, prepareBookingSubmission, formatBookingSubmissionPreparationError, resolveBookingPaymentStep, BOOKING_FORM_DATA_RESERVED_KEYS, clearWorkflowFeedback, reportWorkflowError, reportWorkflowSuccess, okWith2, err2 } from './chunk-DIRW2LNG.mjs';
13
- import { resolveBookingTimeZoneId, DEFAULT_BOOKING_TIME_ZONE, unsafeAsFormId, unsafeAsAppointmentResourceId, unsafeAsCustomerPassId, unsafeAsAppointmentServiceId, formatLocalScheduleDate, addLocalScheduleDays, parseBookingLocalDate, resolveFlexibleBalanceInitialPaymentCents, resolveFlexibleBalanceDueAt, getBookingInstalmentDepositRefundability, unsafeAsPassId, splitAmountWithRemainderInFirst, addIntervalPreservingMonthAnchor, clampConfiguredAmount, getBookingInstalmentPlanIntervalCount, omitZeroAmountFutureRows, formatBookingInstant } from './chunk-LI2C6M5O.mjs';
11
+ import { defineIslandPropsDecoder, resolveBookingSiteId, resolveDefaultBookingServiceId, getBookingRedirectStateFromLocation, deriveBookingFormViewState, logger, getBookingSuccessMessage, resolveAppointmentCheckoutVerificationState, themeButtonClassName, toSelectedCollectionOptionKind, assertNever, prepareBookingSubmission, formatBookingSubmissionPreparationError, resolveBookingPaymentStep, BOOKING_FORM_DATA_RESERVED_KEYS, clearWorkflowFeedback, reportWorkflowError, reportWorkflowSuccess, okWith, err } from './chunk-6DPXDOIL.mjs';
12
+ import { resolveBookingTimeZoneId, DEFAULT_BOOKING_TIME_ZONE, unsafeAsFormId, unsafeAsAppointmentResourceId, unsafeAsCustomerPassId, unsafeAsAppointmentServiceId, formatLocalScheduleDate, addLocalScheduleDays, parseBookingLocalDate, unsafeAsPassId, formatBookingInstant } from './chunk-25W2EQUN.mjs';
14
13
  import React2, { useRef, useState, useMemo, useReducer, useEffect, useCallback, useLayoutEffect } from 'react';
15
14
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
16
15
 
@@ -141,6 +140,74 @@ function useVisibleTabPolling({
141
140
  }, [enabled, intervalMs, jitterMs, minVisibleRefreshIntervalMs]);
142
141
  }
143
142
 
143
+ // ../blocks/src/system/runtime/hooks/useAvailableDates.state.ts
144
+ function createEmptyAvailableDatesData() {
145
+ return {
146
+ availableDates: /* @__PURE__ */ new Set(),
147
+ hasMore: false,
148
+ loadedRange: null,
149
+ nextStartDate: null
150
+ };
151
+ }
152
+ function createInitialAvailableDatesState() {
153
+ return {
154
+ tag: "idle",
155
+ data: createEmptyAvailableDatesData()
156
+ };
157
+ }
158
+ function getAvailableDates(state) {
159
+ return state.data.availableDates;
160
+ }
161
+ function getAvailableDatesLoadedRange(state) {
162
+ return state.data.loadedRange;
163
+ }
164
+ function getAvailableDatesNextStartDate(state) {
165
+ return state.data.nextStartDate;
166
+ }
167
+ function hasMoreAvailableDates(state) {
168
+ return state.data.hasMore;
169
+ }
170
+ function isLoadingAvailableDates(state) {
171
+ return state.tag === "loading";
172
+ }
173
+ function isRefreshingAvailableDates(state) {
174
+ return state.tag === "refreshing";
175
+ }
176
+ function getAvailableDatesError(state) {
177
+ return state.tag === "error" ? state.message : null;
178
+ }
179
+ function mergeAvailableDates(previous, action) {
180
+ const availableDates = action.append ? new Set(previous.availableDates) : /* @__PURE__ */ new Set();
181
+ for (const date of action.dates) {
182
+ availableDates.add(date);
183
+ }
184
+ return {
185
+ availableDates,
186
+ hasMore: action.hasMore,
187
+ loadedRange: {
188
+ start: action.append && previous.loadedRange ? previous.loadedRange.start : action.startDate,
189
+ end: action.endDate
190
+ },
191
+ nextStartDate: action.nextStartDate
192
+ };
193
+ }
194
+ function availableDatesReducer(state, action) {
195
+ switch (action.type) {
196
+ case "query-cleared":
197
+ return { tag: "idle", data: createEmptyAvailableDatesData() };
198
+ case "load-started":
199
+ return { tag: "loading", data: state.data };
200
+ case "refresh-started":
201
+ return { tag: "refreshing", data: state.data };
202
+ case "load-succeeded":
203
+ return { tag: "loaded", data: mergeAvailableDates(state.data, action) };
204
+ case "load-failed":
205
+ return { tag: "error", data: state.data, message: action.message };
206
+ default:
207
+ return assertNever(action);
208
+ }
209
+ }
210
+
144
211
  // ../blocks/src/system/runtime/hooks/useAvailableDates.ts
145
212
  var AVAILABILITY_REFRESH_INTERVAL_MS = 3e4;
146
213
  var AVAILABILITY_REFRESH_JITTER_MS = 5e3;
@@ -153,25 +220,23 @@ function useAvailableDates({
153
220
  initialDays = 30
154
221
  }) {
155
222
  const api = useBlockApi();
156
- const [availableDates, setAvailableDates] = useState(/* @__PURE__ */ new Set());
157
- const [isLoading, setIsLoading] = useState(false);
158
- const [isRefreshing, setIsRefreshing] = useState(false);
159
- const [error, setError] = useState(null);
160
- const [hasMore, setHasMore] = useState(false);
161
- const [loadedRange, setLoadedRange] = useState(null);
162
- const nextStartDateRef = useRef(null);
223
+ const [state, dispatch] = useReducer(
224
+ availableDatesReducer,
225
+ createInitialAvailableDatesState()
226
+ );
163
227
  const requestIdRef = useRef(0);
228
+ const loadedRange = getAvailableDatesLoadedRange(state);
229
+ const isLoading = isLoadingAvailableDates(state);
230
+ const nextStartDate = getAvailableDatesNextStartDate(state);
164
231
  const fetchDates = useCallback(
165
232
  async (startDate, endDate, append = false, mode = "load") => {
166
233
  if (!serviceId) return;
167
234
  const requestId = ++requestIdRef.current;
168
235
  if (mode === "refresh") {
169
- setIsRefreshing(true);
236
+ dispatch({ type: "refresh-started" });
170
237
  } else {
171
- setIsLoading(true);
172
- setIsRefreshing(false);
238
+ dispatch({ type: "load-started" });
173
239
  }
174
- setError(null);
175
240
  try {
176
241
  const data = await api.getAvailableDates({
177
242
  serviceId,
@@ -181,38 +246,29 @@ function useAvailableDates({
181
246
  resourceId
182
247
  });
183
248
  if (requestId !== requestIdRef.current) return;
184
- setAvailableDates((prev) => {
185
- const newSet = append ? new Set(prev) : /* @__PURE__ */ new Set();
186
- data.dates.forEach((d) => newSet.add(d));
187
- return newSet;
249
+ dispatch({
250
+ type: "load-succeeded",
251
+ dates: data.dates,
252
+ hasMore: data.hasMore,
253
+ nextStartDate: data.nextStartDate || null,
254
+ startDate: data.startDate,
255
+ endDate: data.endDate,
256
+ append
188
257
  });
189
- setHasMore(data.hasMore);
190
- nextStartDateRef.current = data.nextStartDate || null;
191
- setLoadedRange((prev) => ({
192
- start: append && prev ? prev.start : data.startDate,
193
- end: data.endDate
194
- }));
195
- } catch (err) {
258
+ } catch (err2) {
196
259
  if (requestId !== requestIdRef.current) return;
197
- setError(
198
- err instanceof Error ? err.message : "Failed to load available dates"
199
- );
200
- } finally {
201
- if (mode === "refresh" && requestId === requestIdRef.current) {
202
- setIsRefreshing(false);
203
- } else if (requestId === requestIdRef.current) {
204
- setIsLoading(false);
205
- }
260
+ dispatch({
261
+ type: "load-failed",
262
+ message: err2 instanceof Error ? err2.message : "Failed to load available dates"
263
+ });
206
264
  }
207
265
  },
208
266
  [api, serviceId, resourceId, timezone]
209
267
  );
210
268
  useEffect(() => {
211
269
  if (!serviceId) {
212
- setAvailableDates(/* @__PURE__ */ new Set());
213
- setLoadedRange(null);
214
- setHasMore(false);
215
- setIsRefreshing(false);
270
+ requestIdRef.current += 1;
271
+ dispatch({ type: "query-cleared" });
216
272
  return;
217
273
  }
218
274
  const now = /* @__PURE__ */ new Date();
@@ -236,8 +292,8 @@ function useAvailableDates({
236
292
  }
237
293
  });
238
294
  const loadMore = useCallback(() => {
239
- if (!nextStartDateRef.current || isLoading) return;
240
- const start = nextStartDateRef.current;
295
+ if (!nextStartDate || isLoading) return;
296
+ const start = nextStartDate;
241
297
  const end = formatLocalScheduleDate(
242
298
  addLocalScheduleDays(
243
299
  parseBookingLocalDate(start),
@@ -245,17 +301,83 @@ function useAvailableDates({
245
301
  )
246
302
  );
247
303
  void fetchDates(start, end, true);
248
- }, [fetchDates, isLoading]);
304
+ }, [fetchDates, isLoading, nextStartDate]);
249
305
  return {
250
- availableDates,
306
+ availableDates: getAvailableDates(state),
251
307
  isLoading,
252
- isRefreshing,
253
- error,
254
- hasMore,
308
+ isRefreshing: isRefreshingAvailableDates(state),
309
+ error: getAvailableDatesError(state),
310
+ hasMore: hasMoreAvailableDates(state),
255
311
  loadMore,
256
312
  loadedRange
257
313
  };
258
314
  }
315
+
316
+ // ../blocks/src/system/runtime/hooks/useAvailableSlots.state.ts
317
+ var initialAvailableSlotsState = { tag: "idle" };
318
+ function getAvailableSlots(state) {
319
+ switch (state.tag) {
320
+ case "idle":
321
+ case "loading":
322
+ return [];
323
+ case "loaded":
324
+ case "refreshing":
325
+ case "error":
326
+ return state.slots;
327
+ default:
328
+ return assertNever(state);
329
+ }
330
+ }
331
+ function hasLoadedAvailableSlots(state) {
332
+ switch (state.tag) {
333
+ case "idle":
334
+ return false;
335
+ case "loading":
336
+ case "refreshing":
337
+ case "error":
338
+ return state.hasLoaded;
339
+ case "loaded":
340
+ return true;
341
+ default:
342
+ return assertNever(state);
343
+ }
344
+ }
345
+ function isLoadingAvailableSlots(state) {
346
+ return state.tag === "loading";
347
+ }
348
+ function isRefreshingAvailableSlots(state) {
349
+ return state.tag === "refreshing";
350
+ }
351
+ function getAvailableSlotsError(state) {
352
+ return state.tag === "error" ? state.message : null;
353
+ }
354
+ function availableSlotsReducer(state, action) {
355
+ switch (action.type) {
356
+ case "query-cleared":
357
+ return { tag: "idle" };
358
+ case "load-started":
359
+ return { tag: "loading", hasLoaded: hasLoadedAvailableSlots(state) };
360
+ case "refresh-started":
361
+ return {
362
+ tag: "refreshing",
363
+ slots: getAvailableSlots(state),
364
+ hasLoaded: hasLoadedAvailableSlots(state)
365
+ };
366
+ case "load-succeeded":
367
+ return { tag: "loaded", slots: action.slots };
368
+ case "load-failed":
369
+ return {
370
+ tag: "error",
371
+ slots: getAvailableSlots(state),
372
+ hasLoaded: hasLoadedAvailableSlots(state),
373
+ message: action.message
374
+ };
375
+ default:
376
+ return assertNever(action);
377
+ }
378
+ }
379
+
380
+ // ../blocks/src/system/runtime/hooks/useAvailableSlots.ts
259
381
  var AVAILABILITY_REFRESH_INTERVAL_MS2 = 3e4;
260
382
  var AVAILABILITY_REFRESH_JITTER_MS2 = 5e3;
261
383
  function useAvailableSlots({
@@ -267,31 +389,23 @@ function useAvailableSlots({
267
389
  timezone
268
390
  }) {
269
391
  const api = useBlockApi();
270
- const [slots, setSlots] = useState([]);
271
- const [isLoading, setIsLoading] = useState(false);
272
- const [isRefreshing, setIsRefreshing] = useState(false);
273
- const [hasLoaded, setHasLoaded] = useState(false);
274
- const [error, setError] = useState(null);
392
+ const [state, dispatch] = useReducer(
393
+ availableSlotsReducer,
394
+ initialAvailableSlotsState
395
+ );
275
396
  const requestIdRef = useRef(0);
276
397
  const fetchSlots = useCallback(
277
398
  async (mode) => {
278
399
  const requestId = ++requestIdRef.current;
279
400
  if (!selectedDate || !serviceId) {
280
- setSlots([]);
281
- setIsLoading(false);
282
- setIsRefreshing(false);
283
- setHasLoaded(false);
284
- setError(null);
401
+ dispatch({ type: "query-cleared" });
285
402
  return;
286
403
  }
287
404
  if (mode === "refresh") {
288
- setIsRefreshing(true);
405
+ dispatch({ type: "refresh-started" });
289
406
  } else {
290
- setIsLoading(true);
291
- setIsRefreshing(false);
292
- setSlots([]);
407
+ dispatch({ type: "load-started" });
293
408
  }
294
- setError(null);
295
409
  try {
296
410
  const result = await api.getAvailableSlots({
297
411
  serviceId,
@@ -301,24 +415,19 @@ function useAvailableSlots({
301
415
  resourceId
302
416
  });
303
417
  if (requestId !== requestIdRef.current) return;
304
- setSlots(
305
- result.slots.map((slot) => ({
418
+ dispatch({
419
+ type: "load-succeeded",
420
+ slots: result.slots.map((slot) => ({
306
421
  ...slot,
307
422
  resourceId: unsafeAsAppointmentResourceId(slot.resourceId)
308
423
  }))
309
- );
310
- setHasLoaded(true);
311
- } catch (err) {
424
+ });
425
+ } catch (err2) {
312
426
  if (requestId !== requestIdRef.current) return;
313
- setError(
314
- err instanceof Error ? err.message : "Failed to load available times"
315
- );
316
- } finally {
317
- if (mode === "refresh" && requestId === requestIdRef.current) {
318
- setIsRefreshing(false);
319
- } else if (requestId === requestIdRef.current) {
320
- setIsLoading(false);
321
- }
427
+ dispatch({
428
+ type: "load-failed",
429
+ message: err2 instanceof Error ? err2.message : "Failed to load available times"
430
+ });
322
431
  }
323
432
  },
324
433
  [selectedDate, serviceId, resourceId, timezone, api]
@@ -335,7 +444,13 @@ function useAvailableSlots({
335
444
  jitterMs: AVAILABILITY_REFRESH_JITTER_MS2,
336
445
  onPoll: () => fetchSlots("refresh")
337
446
  });
338
- return { slots, isLoading, isRefreshing, hasLoaded, error };
447
+ return {
448
+ slots: getAvailableSlots(state),
449
+ isLoading: isLoadingAvailableSlots(state),
450
+ isRefreshing: isRefreshingAvailableSlots(state),
451
+ hasLoaded: hasLoadedAvailableSlots(state),
452
+ error: getAvailableSlotsError(state)
453
+ };
339
454
  }
340
455
 
341
456
  // ../blocks/src/system/runtime/hooks/useBookingSubmission.state.ts
@@ -364,7 +479,7 @@ function bookingSubmissionReducer(state, action) {
364
479
  case "feedback-cleared":
365
480
  return clearWorkflowFeedback(state);
366
481
  default:
367
- return assertNever11(action);
482
+ return assertNever(action);
368
483
  }
369
484
  }
370
485
  function selectIsSubmitting(state) {
@@ -408,7 +523,7 @@ function useBookingSubmission(_siteId) {
408
523
  type: "submission-succeeded",
409
524
  message: response.type === "checkout_redirect" ? "Redirecting to secure checkout..." : "Booking submitted successfully."
410
525
  });
411
- return okWith2(response);
526
+ return okWith(response);
412
527
  } catch (error) {
413
528
  console.error("Booking submission error:", error);
414
529
  const message = error instanceof Error ? error.message : "Failed to book appointment";
@@ -416,7 +531,7 @@ function useBookingSubmission(_siteId) {
416
531
  type: "submission-failed",
417
532
  message
418
533
  });
419
- return err2(message);
534
+ return err(message);
420
535
  }
421
536
  };
422
537
  return {
@@ -428,253 +543,6 @@ function useBookingSubmission(_siteId) {
428
543
  };
429
544
  }
430
545
 
431
- // ../blocks/src/system/runtime/shared/bookingPaymentOptionCopy.ts
432
- function buildUpfrontBookingPaymentOptionCopy(formattedTotal) {
433
- return {
434
- title: "Pay in full",
435
- description: "Pay everything today and your booking is confirmed.",
436
- ctaLabel: `Pay ${formattedTotal} now`
437
- };
438
- }
439
- function buildDeferredManualBookingPaymentOptionCopy() {
440
- return {
441
- title: "Pay offline",
442
- description: "Book now and pay the business later, outside the platform.",
443
- helperText: "Nothing is due today.",
444
- ctaLabel: "Book now"
445
- };
446
- }
447
- function buildInstalmentBookingPaymentOptionCopy(input) {
448
- return {
449
- title: "Payment plan",
450
- description: describeInstalmentPlanCopy(input),
451
- helperText: "You can pay the rest early any time in your customer portal.",
452
- ctaLabel: `Pay ${input.formattedDueToday} now`
453
- };
454
- }
455
- function describeInstalmentPlanCopy(input) {
456
- if (input.depositRefundability) {
457
- return `Pay ${input.formattedDueToday} today, then continue with scheduled payments. Your deposit is ${formatDepositRefundabilityLabel(input.depositRefundability)}.`;
458
- }
459
- if (input.futurePaymentCount === 0) {
460
- return `Pay ${input.formattedDueToday} today.`;
461
- }
462
- if (input.futurePaymentCount === 1) {
463
- return `Pay ${input.formattedDueToday} today, then one more payment later.`;
464
- }
465
- const formattedFirstFuture = input.formattedFirstFuture ?? input.formattedDueToday;
466
- return `Pay ${input.formattedDueToday} today, then ${input.futurePaymentCount} more ${input.cadenceLabel} payments from ${formattedFirstFuture}.`;
467
- }
468
- function buildFlexibleBalanceBookingPaymentOptionCopy(input) {
469
- return {
470
- title: "Deposit now, pay the rest later",
471
- description: `Pay ${input.formattedDueToday} today, then pay the remaining balance any time before ${input.dueDateLabel}. Your deposit is ${formatDepositRefundabilityLabel(input.depositRefundability)}.`,
472
- helperText: "You can return in your customer portal to pay the rest before the due date.",
473
- ctaLabel: `Pay ${input.formattedDueToday} now`
474
- };
475
- }
476
- function formatDepositRefundabilityLabel(depositRefundability) {
477
- return depositRefundability === "non_refundable" ? "non-refundable" : "refundable";
478
- }
479
-
480
- // ../blocks/src/system/runtime/shared/bookingPaymentOptions.ts
481
- function buildBookingPaymentSelectionViewModel(input) {
482
- const currency = input.priceCurrency ?? "USD";
483
- const totalCents = Math.max(0, input.priceAmount ?? 0);
484
- const allowedOptions = input.paymentTerms?.allowedOptions ?? [{ kind: "upfront" }];
485
- const mode = allowedOptions.length > 1 ? "choice_required" : "single_option";
486
- return {
487
- mode,
488
- sectionTitle: mode === "choice_required" ? "Choose how you'd like to pay" : "Payment",
489
- serviceTitle: input.serviceTitle,
490
- options: allowedOptions.map((option) => buildBookingPaymentOptionViewModel({
491
- option,
492
- totalCents,
493
- currency,
494
- bookingStartAt: input.bookingStartAt,
495
- locale: input.locale
496
- }))
497
- };
498
- }
499
- function buildBookingPaymentOptionViewModel(input) {
500
- switch (input.option.kind) {
501
- case "upfront": {
502
- const formattedTotal = formatPrice(input.totalCents, input.currency, input.locale);
503
- const copy = buildUpfrontBookingPaymentOptionCopy(formattedTotal);
504
- return {
505
- kind: "upfront",
506
- title: copy.title,
507
- description: copy.description,
508
- summaryRows: [
509
- { label: "Total", value: formattedTotal },
510
- { label: "Due today", value: formattedTotal }
511
- ],
512
- ctaLabel: copy.ctaLabel
513
- };
514
- }
515
- case "deferred_manual": {
516
- const formattedTotal = formatPrice(input.totalCents, input.currency, input.locale);
517
- const copy = buildDeferredManualBookingPaymentOptionCopy();
518
- return {
519
- kind: "deferred_manual",
520
- title: copy.title,
521
- description: copy.description,
522
- summaryRows: [
523
- { label: "Total", value: formattedTotal },
524
- { label: "Due today", value: formatPrice(0, input.currency, input.locale) }
525
- ],
526
- helperText: copy.helperText,
527
- ctaLabel: copy.ctaLabel
528
- };
529
- }
530
- case "instalment_plan": {
531
- const schedulePreview = buildInstalmentSchedulePreview({
532
- totalCents: input.totalCents,
533
- option: input.option,
534
- bookingStartAt: input.bookingStartAt
535
- });
536
- const dueToday = schedulePreview[0]?.amountCents ?? input.totalCents;
537
- const futureRows = schedulePreview.slice(1);
538
- const formattedTotal = formatPrice(input.totalCents, input.currency, input.locale);
539
- const formattedDueToday = formatPrice(dueToday, input.currency, input.locale);
540
- const depositRefundability = getBookingInstalmentDepositRefundability(input.option.plan);
541
- const copy = buildInstalmentBookingPaymentOptionCopy({
542
- formattedDueToday,
543
- futurePaymentCount: futureRows.length,
544
- formattedFirstFuture: futureRows[0] ? formatPrice(futureRows[0].amountCents, input.currency, input.locale) : null,
545
- cadenceLabel: getPaymentCadenceLabel(input.option.plan),
546
- depositRefundability
547
- });
548
- return {
549
- kind: "instalment_plan",
550
- title: copy.title,
551
- description: copy.description,
552
- summaryRows: [
553
- { label: "Total", value: formattedTotal },
554
- { label: "Due today", value: formattedDueToday },
555
- ...depositRefundability ? [{
556
- label: "Deposit policy",
557
- value: depositRefundability === "non_refundable" ? "Non-refundable" : "Refundable"
558
- }] : [],
559
- ...futureRows.map((row) => ({
560
- label: formatScheduleDate(row.dueAt, input.locale),
561
- value: formatPrice(row.amountCents, input.currency, input.locale)
562
- }))
563
- ],
564
- helperText: copy.helperText,
565
- ctaLabel: copy.ctaLabel
566
- };
567
- }
568
- case "flexible_balance": {
569
- const dueToday = resolveFlexibleBalanceInitialPaymentCents({
570
- totalAmountCents: input.totalCents,
571
- config: input.option.config
572
- });
573
- const formattedTotal = formatPrice(input.totalCents, input.currency, input.locale);
574
- const formattedDueToday = formatPrice(dueToday, input.currency, input.locale);
575
- const dueAt = resolveFlexibleBalanceDueAt({
576
- bookingStartAt: input.bookingStartAt ?? (/* @__PURE__ */ new Date()).toISOString(),
577
- dueDateRule: input.option.config.dueDateRule
578
- });
579
- const copy = buildFlexibleBalanceBookingPaymentOptionCopy({
580
- formattedDueToday,
581
- dueDateLabel: formatScheduleDate(dueAt, input.locale),
582
- depositRefundability: input.option.config.depositRefundability
583
- });
584
- return {
585
- kind: "flexible_balance",
586
- title: copy.title,
587
- description: copy.description,
588
- summaryRows: [
589
- { label: "Total", value: formattedTotal },
590
- { label: "Due today", value: formattedDueToday },
591
- { label: "Balance due by", value: formatScheduleDate(dueAt, input.locale) },
592
- {
593
- label: "Deposit policy",
594
- value: input.option.config.depositRefundability === "non_refundable" ? "Non-refundable" : "Refundable"
595
- }
596
- ],
597
- helperText: copy.helperText,
598
- ctaLabel: copy.ctaLabel
599
- };
600
- }
601
- default:
602
- return assertNever11(input.option);
603
- }
604
- }
605
- function buildInstalmentSchedulePreview(input) {
606
- const startAt = input.bookingStartAt ?? (/* @__PURE__ */ new Date()).toISOString();
607
- switch (input.option.plan.kind) {
608
- case "deposit_plus_one_remainder": {
609
- const deposit = clampConfiguredAmount(input.option.plan.depositAmountCents, input.totalCents);
610
- const remainder = Math.max(0, input.totalCents - deposit);
611
- return compactSchedulePreview([
612
- { dueAt: startAt, amountCents: deposit },
613
- {
614
- dueAt: addIntervalPreservingMonthAnchor(
615
- startAt,
616
- input.option.plan.remainderDueCount,
617
- input.option.plan.intervalUnit
618
- ),
619
- amountCents: remainder
620
- }
621
- ]);
622
- }
623
- case "deposit_plus_scheduled_instalments": {
624
- const plan = input.option.plan;
625
- const deposit = clampConfiguredAmount(plan.depositAmountCents, input.totalCents);
626
- const remaining = Math.max(0, input.totalCents - deposit);
627
- const instalments = splitAmountWithRemainderInFirst(
628
- remaining,
629
- plan.instalmentCount
630
- );
631
- return compactSchedulePreview([
632
- { dueAt: startAt, amountCents: deposit },
633
- ...instalments.map((amountCents, index) => ({
634
- dueAt: addIntervalPreservingMonthAnchor(
635
- startAt,
636
- plan.intervalCount * (index + 1),
637
- plan.intervalUnit
638
- ),
639
- amountCents
640
- }))
641
- ]);
642
- }
643
- case "equal_scheduled_instalments": {
644
- const plan = input.option.plan;
645
- const instalments = splitAmountWithRemainderInFirst(
646
- input.totalCents,
647
- plan.instalmentCount
648
- );
649
- return compactSchedulePreview(instalments.map((amountCents, index) => ({
650
- dueAt: index === 0 ? startAt : addIntervalPreservingMonthAnchor(
651
- startAt,
652
- plan.intervalCount * index,
653
- plan.intervalUnit
654
- ),
655
- amountCents
656
- })));
657
- }
658
- default:
659
- return assertNever11(input.option.plan);
660
- }
661
- }
662
- function getPaymentCadenceLabel(plan) {
663
- const intervalCount = getBookingInstalmentPlanIntervalCount(plan);
664
- const unitLabel = intervalCount === 1 ? plan.intervalUnit : `${plan.intervalUnit}s`;
665
- return intervalCount === 1 ? unitLabel : `every ${intervalCount} ${unitLabel}`;
666
- }
667
- function compactSchedulePreview(schedule) {
668
- return omitZeroAmountFutureRows(schedule);
669
- }
670
- function formatScheduleDate(isoString, locale) {
671
- const date = new Date(isoString);
672
- if (!Number.isFinite(date.getTime())) {
673
- return isoString;
674
- }
675
- return new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(date);
676
- }
677
-
678
546
  // ../blocks/src/system/runtime/nodes/booking-form.headless.state.ts
679
547
  var unsafeAsBookingFieldId = (id) => id;
680
548
  function createEmptyBookingValidationErrors() {
@@ -880,7 +748,7 @@ function bookingFlowReducer(state, event) {
880
748
  case "reset":
881
749
  return event.initial;
882
750
  default:
883
- return assertNever11(event);
751
+ return assertNever(event);
884
752
  }
885
753
  }
886
754
  function clearAvailabilityFeedback(feedback) {
@@ -1009,7 +877,7 @@ function validateBookingStep(input) {
1009
877
  return Object.keys(errors).length > 0 ? { ok: false, errors: createFieldBookingValidationErrors(errors) } : { ok: true };
1010
878
  }
1011
879
  default:
1012
- return assertNever11(input.stepId);
880
+ return assertNever(input.stepId);
1013
881
  }
1014
882
  }
1015
883
  function validateBookingFields(input) {
@@ -1301,7 +1169,7 @@ function resolveAppointmentPackagesModel(input) {
1301
1169
  };
1302
1170
  }
1303
1171
  default:
1304
- return assertNever11(input.state);
1172
+ return assertNever(input.state);
1305
1173
  }
1306
1174
  }
1307
1175
  function toHeadlessEligibleAppointmentPackage(appointmentPackage) {
@@ -1625,7 +1493,10 @@ function useHeadlessBookingFlow(options) {
1625
1493
  state.selectedDate,
1626
1494
  state.selectedSlot
1627
1495
  ]);
1628
- const appointmentDiscountContext = selectedService && (selectedService.priceAmount ?? 0) > 0 ? { type: "appointment", serviceId: selectedService.id } : null;
1496
+ const appointmentDiscountContext = useMemo(
1497
+ () => selectedService && (selectedService.priceAmount ?? 0) > 0 ? { type: "appointment", serviceId: selectedService.id } : null,
1498
+ [selectedService?.id, selectedService?.priceAmount]
1499
+ );
1629
1500
  const discountUi = useDiscountCodeUi({
1630
1501
  api,
1631
1502
  discountContext: appointmentDiscountContext,
@@ -2211,7 +2082,7 @@ function DefaultBookingStepContent({
2211
2082
  case "custom-fields":
2212
2083
  return /* @__PURE__ */ jsx(DefaultDynamicFields, { fields: booking.fields.items, booking });
2213
2084
  default:
2214
- return assertNever11(stepId);
2085
+ return assertNever(stepId);
2215
2086
  }
2216
2087
  }
2217
2088
  function DefaultServiceSelectionStep({