@riverbankcms/sdk 0.72.0 → 0.75.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 (146) hide show
  1. package/README.md +1 -1
  2. package/dist/{PreviewEditorSidebar-44T64SAR.mjs → PreviewEditorSidebar-U2IHCBYN.mjs} +3 -3
  3. package/dist/{PreviewEditorUI-4WKHZTXW.mjs → PreviewEditorUI-ZGH2RQNP.mjs} +3 -3
  4. package/dist/SdkPreviewModeRuntime-MTUGBTLQ.mjs +8 -0
  5. package/dist/_dts/ai/src/contracts/proposals.d.ts +10 -10
  6. package/dist/_dts/api/src/cache-tags.d.ts +22 -0
  7. package/dist/_dts/api/src/contentRuntime.d.ts +1 -0
  8. package/dist/_dts/api/src/endpoints.d.ts +24 -24
  9. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +2 -1
  10. package/dist/_dts/block-form/src/blockDraftSaveability.d.ts +4 -1
  11. package/dist/_dts/blocks/src/client/booking-form.d.ts +2 -0
  12. package/dist/_dts/blocks/src/client/carousel.d.ts +1 -0
  13. package/dist/_dts/blocks/src/client/course-registration.d.ts +2 -0
  14. package/dist/_dts/blocks/src/client/events.d.ts +4 -0
  15. package/dist/_dts/blocks/src/client/form.d.ts +2 -0
  16. package/dist/_dts/blocks/src/client/header.d.ts +1 -0
  17. package/dist/_dts/blocks/src/client/location-map.d.ts +1 -0
  18. package/dist/_dts/blocks/src/client/newsletter-form.d.ts +2 -0
  19. package/dist/_dts/blocks/src/client/shop.d.ts +6 -0
  20. package/dist/_dts/blocks/src/lib/video.d.ts +2 -0
  21. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +21 -1
  22. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +6 -6
  23. package/dist/_dts/blocks/src/system/node/fragments/backgroundLayer.d.ts +15 -1
  24. package/dist/_dts/blocks/src/system/node/fragments/styledSection.d.ts +11 -0
  25. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +1 -0
  26. package/dist/_dts/blocks/src/system/runtime/header/enhanceHeaderSection.d.ts +13 -0
  27. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +3 -2
  28. package/dist/_dts/blocks/src/system/runtime/nodes/events/index.d.ts +3 -0
  29. package/dist/_dts/blocks/src/system/runtime/nodes/header-section.client.d.ts +1 -0
  30. package/dist/_dts/blocks/src/system/runtime/nodes/header-section.server.d.ts +1 -0
  31. package/dist/_dts/blocks/src/system/runtime/nodes/media.d.ts +6 -0
  32. package/dist/_dts/content-editor/src/hooks/validateBlocksForPublish.d.ts +5 -0
  33. package/dist/_dts/preview-next/src/client/preview/SiteChromeEditableSurface.d.ts +12 -2
  34. package/dist/_dts/sdk/src/public-api/contracts.d.ts +1 -0
  35. package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +2 -2
  36. package/dist/_dts/sdk/src/rendering/islands/deferredVideoEmbeds.d.ts +2 -0
  37. package/dist/_dts/sdk/src/rendering/islands/enhancers/accordion.d.ts +1 -0
  38. package/dist/_dts/sdk/src/rendering/islands/enhancers/bookingForm.d.ts +1 -0
  39. package/dist/_dts/sdk/src/rendering/islands/enhancers/carousel.d.ts +1 -0
  40. package/dist/_dts/sdk/src/rendering/islands/enhancers/cart.d.ts +1 -0
  41. package/dist/_dts/sdk/src/rendering/islands/enhancers/checkout.d.ts +1 -0
  42. package/dist/_dts/sdk/src/rendering/islands/enhancers/courseRegistration.d.ts +1 -0
  43. package/dist/_dts/sdk/src/rendering/islands/enhancers/eventCalendar.d.ts +1 -0
  44. package/dist/_dts/sdk/src/rendering/islands/enhancers/eventCombined.d.ts +1 -0
  45. package/dist/_dts/sdk/src/rendering/islands/enhancers/eventDetails.d.ts +1 -0
  46. package/dist/_dts/sdk/src/rendering/islands/enhancers/eventListing.d.ts +1 -0
  47. package/dist/_dts/sdk/src/rendering/islands/enhancers/eventRegistration.d.ts +1 -0
  48. package/dist/_dts/sdk/src/rendering/islands/enhancers/form.d.ts +1 -0
  49. package/dist/_dts/sdk/src/rendering/islands/enhancers/headerSection.d.ts +1 -0
  50. package/dist/_dts/sdk/src/rendering/islands/enhancers/locationMap.d.ts +1 -0
  51. package/dist/_dts/sdk/src/rendering/islands/enhancers/newsletterForm.d.ts +1 -0
  52. package/dist/_dts/sdk/src/rendering/islands/enhancers/productDetail.d.ts +1 -0
  53. package/dist/_dts/sdk/src/rendering/islands/enhancers/productList.d.ts +1 -0
  54. package/dist/_dts/sdk/src/rendering/islands/enhancers/shop.d.ts +1 -0
  55. package/dist/_dts/sdk/src/rendering/islands/hydrateBlocksIslands.d.ts +2 -2
  56. package/dist/_dts/sdk/src/rendering/islands/propsDecoder.d.ts +7 -0
  57. package/dist/_dts/sdk/src/rendering/islands/types.d.ts +9 -0
  58. package/dist/_dts/sdk/src/rendering/server.d.ts +3 -0
  59. package/dist/_dts/sdk/src/version.d.ts +1 -1
  60. package/dist/_dts/theme-core/src/accordions/types.d.ts +3 -3
  61. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +7 -7
  62. package/dist/_dts/theme-core/src/buttons/types.d.ts +20 -20
  63. package/dist/_dts/theme-core/src/cards/types.d.ts +2 -2
  64. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  65. package/dist/_dts/theme-core/src/header/navDropdownSizing.d.ts +7 -0
  66. package/dist/_dts/theme-core/src/inputs/types.d.ts +3 -3
  67. package/dist/_dts/theme-core/src/interactive/baseSchema.d.ts +1 -1
  68. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +156 -156
  69. package/dist/_dts/theme-core/src/navigation/types.d.ts +1 -1
  70. package/dist/_dts/theme-core/src/palette/variants/types.d.ts +4 -4
  71. package/dist/_dts/theme-core/src/schema.d.ts +178 -178
  72. package/dist/_dts/theme-core/src/shared/componentStyles.d.ts +2 -2
  73. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +8 -8
  74. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +5 -5
  75. package/dist/_dts/theme-core/src/tokens/themeColorTokens.d.ts +2 -2
  76. package/dist/{chunk-G4NLITC2.mjs → chunk-BGMNDF6T.mjs} +7 -7
  77. package/dist/{chunk-3YNCQG5N.mjs → chunk-GFE74WRD.mjs} +457 -98
  78. package/dist/{chunk-HV745JYE.mjs → chunk-RWXQBRQZ.mjs} +1 -1
  79. package/dist/{chunk-7RX72SK2.mjs → chunk-VX7B5VAC.mjs} +36 -25
  80. package/dist/{chunk-YRJKZEQ3.mjs → chunk-Z7JLNTJR.mjs} +1 -1
  81. package/dist/{chunk-KWQPAJYS.mjs → chunk-ZSHFGFUG.mjs} +2 -2
  82. package/dist/cli/index.mjs +3498 -3826
  83. package/dist/client/accordion-T2UD2ZTH.mjs +120 -0
  84. package/dist/client/altcha-LIGLPZS5.mjs +2755 -0
  85. package/dist/client/bookingForm-GUP75FKN.mjs +3022 -0
  86. package/dist/client/bookings.mjs +32 -10
  87. package/dist/client/carousel-2NQA6V57.mjs +47 -0
  88. package/dist/client/cart-5TFIAFDS.mjs +18 -0
  89. package/dist/client/checkout-TP4WAHZE.mjs +18 -0
  90. package/dist/client/chunk-2PHQZ666.mjs +383 -0
  91. package/dist/client/chunk-3DCJ45Z2.mjs +36 -0
  92. package/dist/client/chunk-3PEDD5KJ.mjs +146 -0
  93. package/dist/client/chunk-CY2ZTSE5.mjs +204 -0
  94. package/dist/client/chunk-F7LHOKEH.mjs +146 -0
  95. package/dist/client/chunk-FU2QRZMX.mjs +7617 -0
  96. package/dist/client/chunk-I2MMZO53.mjs +6 -0
  97. package/dist/client/chunk-II7O4XN3.mjs +2206 -0
  98. package/dist/client/chunk-M3L3KYYR.mjs +1181 -0
  99. package/dist/client/chunk-N7PBWBWQ.mjs +26 -0
  100. package/dist/client/chunk-NWOUL6JY.mjs +1378 -0
  101. package/dist/client/chunk-OJPZEZU2.mjs +31 -0
  102. package/dist/client/chunk-PMAIXMAB.mjs +1960 -0
  103. package/dist/client/chunk-RTZ3JKKX.mjs +178 -0
  104. package/dist/client/chunk-TQ5MSPDX.mjs +74 -0
  105. package/dist/client/chunk-VUAOE3AG.mjs +5592 -0
  106. package/dist/client/chunk-WJXXNDSE.mjs +245 -0
  107. package/dist/client/chunk-YLMKMCSJ.mjs +86 -0
  108. package/dist/client/chunk-ZLMS67RR.mjs +106 -0
  109. package/dist/client/client.mjs +51865 -52071
  110. package/dist/client/courseRegistration-5DPU6PDY.mjs +1737 -0
  111. package/dist/client/eventCalendar-F3GZGTEF.mjs +40 -0
  112. package/dist/client/eventCombined-BQOB6QMY.mjs +37 -0
  113. package/dist/client/eventDetails-PEM2EJWE.mjs +25 -0
  114. package/dist/client/eventListing-YMIQPVME.mjs +40 -0
  115. package/dist/client/eventRegistration-4I6ZNDUF.mjs +40 -0
  116. package/dist/client/form-ZJVAYZ6G.mjs +300 -0
  117. package/dist/client/headerSection-TOT5MGTF.mjs +729 -0
  118. package/dist/client/hooks.mjs +91 -42
  119. package/dist/client/locationMap-J66NZREU.mjs +227 -0
  120. package/dist/client/newsletterForm-ET2XUMRO.mjs +208 -0
  121. package/dist/client/productDetail-C2XIH7C5.mjs +18 -0
  122. package/dist/client/productList-T2AZLFTP.mjs +18 -0
  123. package/dist/client/rendering/client.mjs +12796 -18295
  124. package/dist/client/rendering/islands.mjs +108 -44022
  125. package/dist/client/rendering.mjs +45141 -45346
  126. package/dist/client/shop-UZ6IUZXD.mjs +20 -0
  127. package/dist/preview-next/before-render.mjs +37 -25
  128. package/dist/preview-next/client/runtime.mjs +5 -5
  129. package/dist/preview-next/middleware.mjs +37 -25
  130. package/dist/{sdk-runtime-NGDWSWOS.mjs → sdk-runtime-JCUQM63Y.mjs} +6 -6
  131. package/dist/server/components.mjs +472 -276
  132. package/dist/server/config-validation.mjs +91 -42
  133. package/dist/server/config.mjs +91 -42
  134. package/dist/server/data.mjs +91 -42
  135. package/dist/server/index.mjs +45 -33
  136. package/dist/server/next.mjs +468 -272
  137. package/dist/server/page-converter.mjs +41 -17
  138. package/dist/server/prebuild.mjs +1 -1
  139. package/dist/server/rendering/server.mjs +556 -275
  140. package/dist/server/rendering.mjs +474 -278
  141. package/dist/server/routing.mjs +99 -43
  142. package/dist/server/server.mjs +92 -43
  143. package/dist/server/theme-bridge.mjs +29 -0
  144. package/dist/styles/index.css +16 -0
  145. package/package.json +2 -1
  146. package/dist/SdkPreviewModeRuntime-FO6V7YVY.mjs +0 -8
@@ -0,0 +1,245 @@
1
+ "use client";
2
+ import { assertNever } from './chunk-FU2QRZMX.mjs';
3
+ import { useState, useEffect, useReducer, useRef, useCallback } from 'react';
4
+
5
+ function useDiscountCodeUi(options) {
6
+ const [discountUiOpen, setDiscountUiOpen] = useState(false);
7
+ const [discountCode, setDiscountCode] = useState("");
8
+ const [discountsAvailable, setDiscountsAvailable] = useState(false);
9
+ const [manualCodeEntryAllowed, setManualCodeEntryAllowed] = useState(false);
10
+ const [autoAppliedDiscount, setAutoAppliedDiscount] = useState(null);
11
+ const [discountsAvailableLoading, setDiscountsAvailableLoading] = useState(false);
12
+ useEffect(() => {
13
+ let cancelled = false;
14
+ async function checkDiscountAvailability() {
15
+ if (!options.discountContext) {
16
+ setDiscountsAvailable(false);
17
+ setManualCodeEntryAllowed(false);
18
+ setAutoAppliedDiscount(null);
19
+ setDiscountsAvailableLoading(false);
20
+ setDiscountUiOpen(false);
21
+ setDiscountCode("");
22
+ return;
23
+ }
24
+ setDiscountsAvailableLoading(true);
25
+ try {
26
+ const res = await options.api.getDiscountsAvailable({
27
+ context: options.discountContext,
28
+ subtotalCents: options.subtotalCents
29
+ });
30
+ if (cancelled) return;
31
+ setDiscountsAvailable(res.hasDiscounts);
32
+ setManualCodeEntryAllowed(res.manualCodeEntryAllowed);
33
+ setAutoAppliedDiscount(res.autoAppliedDiscount);
34
+ if (!res.hasDiscounts || !res.manualCodeEntryAllowed) {
35
+ setDiscountUiOpen(false);
36
+ setDiscountCode("");
37
+ }
38
+ } catch {
39
+ if (cancelled) return;
40
+ setDiscountsAvailable(false);
41
+ setManualCodeEntryAllowed(false);
42
+ setAutoAppliedDiscount(null);
43
+ setDiscountUiOpen(false);
44
+ setDiscountCode("");
45
+ } finally {
46
+ if (!cancelled) setDiscountsAvailableLoading(false);
47
+ }
48
+ }
49
+ checkDiscountAvailability();
50
+ return () => {
51
+ cancelled = true;
52
+ };
53
+ }, [options.api, options.discountContext, options.subtotalCents]);
54
+ return {
55
+ discountUiOpen,
56
+ setDiscountUiOpen,
57
+ discountCode,
58
+ setDiscountCode,
59
+ discountsAvailable,
60
+ manualCodeEntryAllowed,
61
+ autoAppliedDiscount,
62
+ discountsAvailableLoading
63
+ };
64
+ }
65
+
66
+ // ../blocks/src/system/runtime/hooks/usePolling.state.ts
67
+ function createInitialPollingState() {
68
+ return {
69
+ tag: "idle",
70
+ result: null,
71
+ error: null
72
+ };
73
+ }
74
+ function pollingReducer(state, action) {
75
+ switch (action.type) {
76
+ case "polling-went-idle":
77
+ return createInitialPollingState();
78
+ case "polling-reset":
79
+ return {
80
+ tag: "polling",
81
+ result: null,
82
+ error: null
83
+ };
84
+ case "polling-progressed":
85
+ return {
86
+ tag: "polling",
87
+ result: action.result,
88
+ error: null
89
+ };
90
+ case "polling-completed":
91
+ return {
92
+ tag: "completed",
93
+ result: action.result,
94
+ error: null
95
+ };
96
+ case "polling-failed":
97
+ return {
98
+ tag: "failed",
99
+ result: action.result,
100
+ error: null
101
+ };
102
+ case "polling-request-failed":
103
+ switch (state.tag) {
104
+ case "idle":
105
+ return {
106
+ tag: "polling",
107
+ result: null,
108
+ error: action.error
109
+ };
110
+ case "polling":
111
+ return {
112
+ tag: "polling",
113
+ result: state.result,
114
+ error: action.error
115
+ };
116
+ case "completed":
117
+ case "failed":
118
+ case "timeout":
119
+ return state;
120
+ default:
121
+ return assertNever(state);
122
+ }
123
+ case "polling-timed-out":
124
+ return {
125
+ tag: "timeout",
126
+ result: state.result,
127
+ error: new Error("Polling timed out")
128
+ };
129
+ default:
130
+ return assertNever(action);
131
+ }
132
+ }
133
+
134
+ // ../blocks/src/system/runtime/hooks/usePolling.ts
135
+ var DEFAULT_MAX_ATTEMPTS = 10;
136
+ var DEFAULT_POLL_INTERVAL = 1e3;
137
+ function usePolling(config) {
138
+ const [state, dispatch] = useReducer(
139
+ pollingReducer,
140
+ void 0,
141
+ createInitialPollingState
142
+ );
143
+ const attemptsRef = useRef(0);
144
+ const timeoutRef = useRef(null);
145
+ const isPollingRef = useRef(false);
146
+ const isActiveRef = useRef(false);
147
+ const generationRef = useRef(0);
148
+ const configRef = useRef(config);
149
+ configRef.current = config;
150
+ const cleanup = useCallback(() => {
151
+ isActiveRef.current = false;
152
+ generationRef.current += 1;
153
+ if (timeoutRef.current) {
154
+ clearTimeout(timeoutRef.current);
155
+ timeoutRef.current = null;
156
+ }
157
+ isPollingRef.current = false;
158
+ }, []);
159
+ const resetState = useCallback(() => {
160
+ dispatch({ type: "polling-reset" });
161
+ attemptsRef.current = 0;
162
+ }, []);
163
+ const poll = useCallback(async () => {
164
+ const cfg = configRef.current;
165
+ if (!cfg) return true;
166
+ if (isPollingRef.current) return false;
167
+ const maxAttempts = cfg.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
168
+ if (attemptsRef.current >= maxAttempts) {
169
+ dispatch({ type: "polling-timed-out" });
170
+ cleanup();
171
+ return true;
172
+ }
173
+ isPollingRef.current = true;
174
+ attemptsRef.current += 1;
175
+ const generation = generationRef.current;
176
+ try {
177
+ const data = await cfg.pollFn();
178
+ if (generation !== generationRef.current || !isActiveRef.current) {
179
+ isPollingRef.current = false;
180
+ return true;
181
+ }
182
+ if (cfg.isFailed?.(data)) {
183
+ dispatch({ type: "polling-failed", result: data });
184
+ cleanup();
185
+ return true;
186
+ }
187
+ if (cfg.isComplete(data)) {
188
+ dispatch({ type: "polling-completed", result: data });
189
+ cleanup();
190
+ return true;
191
+ }
192
+ dispatch({ type: "polling-progressed", result: data });
193
+ isPollingRef.current = false;
194
+ return false;
195
+ } catch (err) {
196
+ if (generation !== generationRef.current || !isActiveRef.current) {
197
+ isPollingRef.current = false;
198
+ return true;
199
+ }
200
+ if (err instanceof Error) {
201
+ dispatch({ type: "polling-request-failed", error: err });
202
+ }
203
+ isPollingRef.current = false;
204
+ return false;
205
+ }
206
+ }, [cleanup]);
207
+ const schedulePoll = useCallback(() => {
208
+ if (!isActiveRef.current) return;
209
+ const cfg = configRef.current;
210
+ const pollInterval = cfg?.interval ?? DEFAULT_POLL_INTERVAL;
211
+ const doPoll = async () => {
212
+ const shouldStop = await poll();
213
+ if (!shouldStop && isActiveRef.current) {
214
+ timeoutRef.current = setTimeout(doPoll, pollInterval);
215
+ }
216
+ };
217
+ doPoll();
218
+ }, [poll]);
219
+ useEffect(() => {
220
+ if (!config) {
221
+ cleanup();
222
+ dispatch({ type: "polling-went-idle" });
223
+ return;
224
+ }
225
+ resetState();
226
+ isActiveRef.current = true;
227
+ schedulePoll();
228
+ return cleanup;
229
+ }, [config, cleanup, resetState, schedulePoll]);
230
+ const retry = useCallback(() => {
231
+ if (!configRef.current) return;
232
+ cleanup();
233
+ resetState();
234
+ isActiveRef.current = true;
235
+ schedulePoll();
236
+ }, [cleanup, resetState, schedulePoll]);
237
+ return {
238
+ status: config ? state.tag : "idle",
239
+ result: config ? state.result : null,
240
+ error: config ? state.error : null,
241
+ retry
242
+ };
243
+ }
244
+
245
+ export { useDiscountCodeUi, usePolling };
@@ -0,0 +1,86 @@
1
+ "use client";
2
+ import { useRef, useState, useEffect } from 'react';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ // ../altcha/src/AltchaWidget.tsx
6
+ function AltchaWidget({
7
+ challengeUrl,
8
+ onSolutionChange,
9
+ auto = true,
10
+ hidelogo = false,
11
+ className
12
+ }) {
13
+ const containerRef = useRef(null);
14
+ const [isLoaded, setIsLoaded] = useState(false);
15
+ useEffect(() => {
16
+ if (typeof window === "undefined") return;
17
+ let widget = null;
18
+ import('./altcha-LIGLPZS5.mjs').then(() => {
19
+ if (!containerRef.current) return;
20
+ widget = document.createElement("altcha-widget");
21
+ widget.setAttribute("challengeurl", challengeUrl);
22
+ if (auto) {
23
+ widget.setAttribute("auto", "onload");
24
+ }
25
+ if (hidelogo) {
26
+ widget.setAttribute("hidelogo", "true");
27
+ }
28
+ widget.setAttribute("hidefooter", "true");
29
+ if (className) {
30
+ widget.className = className;
31
+ }
32
+ widget.addEventListener("statechange", ((event) => {
33
+ const { state, payload } = event.detail;
34
+ if (state === "verified" && payload) {
35
+ onSolutionChange?.(payload);
36
+ } else if (state === "error" || state === "expired") {
37
+ onSolutionChange?.(null);
38
+ }
39
+ }));
40
+ containerRef.current.appendChild(widget);
41
+ setIsLoaded(true);
42
+ }).catch((err) => {
43
+ console.error("Failed to load ALTCHA widget:", err);
44
+ });
45
+ return () => {
46
+ if (widget && containerRef.current) {
47
+ containerRef.current.removeChild(widget);
48
+ }
49
+ };
50
+ }, [challengeUrl, auto, hidelogo, className, onSolutionChange]);
51
+ return /* @__PURE__ */ jsx("div", { ref: containerRef });
52
+ }
53
+
54
+ // ../altcha/src/client.ts
55
+ function isSpamProtectionEnabled() {
56
+ return process.env.NEXT_PUBLIC_SPAM_PROTECTION_ENABLED === "true";
57
+ }
58
+
59
+ // ../../node_modules/.pnpm/altcha-lib@1.4.1/node_modules/altcha-lib/dist/helpers.js
60
+ new TextEncoder();
61
+
62
+ // ../altcha/src/index.ts
63
+ function getCmsApiUrl() {
64
+ const env = process.env.RIVERBANK_ENV;
65
+ if (env) {
66
+ const envKey = `RIVERBANK_${env.toUpperCase()}_DASHBOARD_URL`;
67
+ const dashboardUrl2 = process.env[envKey];
68
+ if (dashboardUrl2) {
69
+ return `${dashboardUrl2.replace(/\/$/, "")}/api`;
70
+ }
71
+ }
72
+ const dashboardUrl = process.env.NEXT_PUBLIC_DASHBOARD_URL;
73
+ if (dashboardUrl) {
74
+ return `${dashboardUrl.replace(/\/$/, "")}/api`;
75
+ }
76
+ const legacyApiUrl = process.env.NEXT_PUBLIC_CMS_API_URL;
77
+ if (legacyApiUrl) {
78
+ return legacyApiUrl.replace(/\/$/, "");
79
+ }
80
+ throw new Error("Dashboard URL not configured. Set NEXT_PUBLIC_DASHBOARD_URL");
81
+ }
82
+ function getChallengeUrl() {
83
+ return `${getCmsApiUrl()}/public/challenge`;
84
+ }
85
+
86
+ export { AltchaWidget, getChallengeUrl, isSpamProtectionEnabled };
@@ -0,0 +1,106 @@
1
+ import { EMPTY_COMMERCE_CART_STATE, parseStoredCommerceCartState, reduceCommerceCart, buildPassCartItem } from './chunk-FU2QRZMX.mjs';
2
+ import * as React from 'react';
3
+
4
+ var EMPTY_STATE = EMPTY_COMMERCE_CART_STATE;
5
+ var stores = /* @__PURE__ */ new Map();
6
+ function storageKey(siteId) {
7
+ return `riverbank:shop-cart:${siteId}`;
8
+ }
9
+ var CommerceCartStore = class {
10
+ constructor(siteId) {
11
+ this.siteId = siteId;
12
+ this.listeners = /* @__PURE__ */ new Set();
13
+ this.state = typeof window === "undefined" ? EMPTY_STATE : parseStoredCommerceCartState(window.localStorage.getItem(storageKey(siteId)));
14
+ }
15
+ subscribe(listener) {
16
+ this.listeners.add(listener);
17
+ return () => {
18
+ this.listeners.delete(listener);
19
+ };
20
+ }
21
+ getSnapshot() {
22
+ return this.state;
23
+ }
24
+ addProduct(input) {
25
+ this.setState(
26
+ reduceCommerceCart(this.state, {
27
+ type: "add_product",
28
+ item: {
29
+ key: input.key,
30
+ kind: "product",
31
+ productId: input.productId,
32
+ ...input.variantId ? { variantId: input.variantId } : {},
33
+ title: input.title,
34
+ variantTitle: input.variantTitle ?? null,
35
+ quantity: input.quantity ?? 1,
36
+ unitPriceCents: input.unitPriceCents,
37
+ currency: input.currency,
38
+ imageUrl: input.imageUrl ?? null,
39
+ soldOut: input.soldOut ?? false
40
+ }
41
+ })
42
+ );
43
+ }
44
+ addPass(input) {
45
+ this.setState(
46
+ reduceCommerceCart(this.state, {
47
+ type: "add_pass",
48
+ item: buildPassCartItem(input)
49
+ })
50
+ );
51
+ }
52
+ updateQuantity(itemKey, quantity) {
53
+ this.setState(reduceCommerceCart(this.state, {
54
+ type: "update_quantity",
55
+ itemKey,
56
+ quantity
57
+ }));
58
+ }
59
+ removeItem(itemKey) {
60
+ this.setState(reduceCommerceCart(this.state, {
61
+ type: "remove_item",
62
+ itemKey
63
+ }));
64
+ }
65
+ clear() {
66
+ this.setState(reduceCommerceCart(this.state, { type: "clear" }));
67
+ }
68
+ setState(nextState) {
69
+ this.state = nextState;
70
+ if (typeof window !== "undefined") {
71
+ window.localStorage.setItem(storageKey(this.siteId), JSON.stringify(nextState));
72
+ }
73
+ for (const listener of this.listeners) {
74
+ listener();
75
+ }
76
+ }
77
+ };
78
+ function getStore(siteId) {
79
+ const existing = stores.get(siteId);
80
+ if (existing) return existing;
81
+ const next = new CommerceCartStore(siteId);
82
+ stores.set(siteId, next);
83
+ return next;
84
+ }
85
+ function addPassToCommerceCart(siteId, input) {
86
+ getStore(siteId ?? "unknown").addPass(input);
87
+ }
88
+ function useCommerceCart(siteId) {
89
+ const effectiveSiteId = siteId ?? "unknown";
90
+ const store = React.useMemo(() => getStore(effectiveSiteId), [effectiveSiteId]);
91
+ const state = React.useSyncExternalStore(
92
+ (listener) => store.subscribe(listener),
93
+ () => store.getSnapshot(),
94
+ () => EMPTY_STATE
95
+ );
96
+ return {
97
+ items: state.items,
98
+ addProduct: store.addProduct.bind(store),
99
+ addPass: store.addPass.bind(store),
100
+ updateQuantity: store.updateQuantity.bind(store),
101
+ removeItem: store.removeItem.bind(store),
102
+ clear: store.clear.bind(store)
103
+ };
104
+ }
105
+
106
+ export { addPassToCommerceCart, useCommerceCart };