@riverbankcms/sdk 0.74.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 (113) hide show
  1. package/dist/{PreviewEditorSidebar-5XL7M3OM.mjs → PreviewEditorSidebar-U2IHCBYN.mjs} +3 -3
  2. package/dist/{PreviewEditorUI-ZDFRDJID.mjs → PreviewEditorUI-ZGH2RQNP.mjs} +3 -3
  3. package/dist/SdkPreviewModeRuntime-MTUGBTLQ.mjs +8 -0
  4. package/dist/_dts/api/src/cache-tags.d.ts +22 -0
  5. package/dist/_dts/api/src/contentRuntime.d.ts +1 -0
  6. package/dist/_dts/api/src/endpoints.d.ts +24 -24
  7. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +2 -1
  8. package/dist/_dts/block-form/src/blockDraftSaveability.d.ts +4 -1
  9. package/dist/_dts/blocks/src/client/booking-form.d.ts +2 -0
  10. package/dist/_dts/blocks/src/client/carousel.d.ts +1 -0
  11. package/dist/_dts/blocks/src/client/course-registration.d.ts +2 -0
  12. package/dist/_dts/blocks/src/client/events.d.ts +4 -0
  13. package/dist/_dts/blocks/src/client/form.d.ts +2 -0
  14. package/dist/_dts/blocks/src/client/header.d.ts +1 -0
  15. package/dist/_dts/blocks/src/client/location-map.d.ts +1 -0
  16. package/dist/_dts/blocks/src/client/newsletter-form.d.ts +2 -0
  17. package/dist/_dts/blocks/src/client/shop.d.ts +6 -0
  18. package/dist/_dts/blocks/src/lib/video.d.ts +2 -0
  19. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +21 -1
  20. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +1 -0
  21. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +3 -2
  22. package/dist/_dts/blocks/src/system/runtime/nodes/events/index.d.ts +3 -0
  23. package/dist/_dts/blocks/src/system/runtime/nodes/header-section.client.d.ts +1 -0
  24. package/dist/_dts/blocks/src/system/runtime/nodes/header-section.server.d.ts +1 -0
  25. package/dist/_dts/content-editor/src/hooks/validateBlocksForPublish.d.ts +5 -0
  26. package/dist/_dts/preview-next/src/client/preview/SiteChromeEditableSurface.d.ts +12 -2
  27. package/dist/_dts/sdk/src/public-api/contracts.d.ts +1 -0
  28. package/dist/_dts/sdk/src/rendering/islands/deferredVideoEmbeds.d.ts +2 -0
  29. package/dist/_dts/sdk/src/rendering/server.d.ts +3 -0
  30. package/dist/_dts/sdk/src/version.d.ts +1 -1
  31. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  32. package/dist/{chunk-YY7K3QD2.mjs → chunk-BGMNDF6T.mjs} +7 -7
  33. package/dist/{chunk-2MIWNFJM.mjs → chunk-GFE74WRD.mjs} +309 -84
  34. package/dist/{chunk-CEQBBLMJ.mjs → chunk-RWXQBRQZ.mjs} +1 -1
  35. package/dist/{chunk-7RX72SK2.mjs → chunk-VX7B5VAC.mjs} +36 -25
  36. package/dist/{chunk-YRJKZEQ3.mjs → chunk-Z7JLNTJR.mjs} +1 -1
  37. package/dist/{chunk-CBD47MTM.mjs → chunk-ZSHFGFUG.mjs} +2 -2
  38. package/dist/cli/index.mjs +3395 -3753
  39. package/dist/client/{accordion-ZZVXWV3N.mjs → accordion-T2UD2ZTH.mjs} +1 -1
  40. package/dist/client/bookingForm-GUP75FKN.mjs +3022 -0
  41. package/dist/client/bookings.mjs +19 -10
  42. package/dist/client/{carousel-25WK2H7G.mjs → carousel-2NQA6V57.mjs} +3 -2
  43. package/dist/client/cart-5TFIAFDS.mjs +18 -0
  44. package/dist/client/checkout-TP4WAHZE.mjs +18 -0
  45. package/dist/client/chunk-2PHQZ666.mjs +383 -0
  46. package/dist/client/chunk-3DCJ45Z2.mjs +36 -0
  47. package/dist/client/chunk-3PEDD5KJ.mjs +146 -0
  48. package/dist/client/chunk-CY2ZTSE5.mjs +204 -0
  49. package/dist/client/chunk-F7LHOKEH.mjs +146 -0
  50. package/dist/client/{chunk-6VGXRE34.mjs → chunk-FU2QRZMX.mjs} +6 -6
  51. package/dist/client/chunk-I2MMZO53.mjs +6 -0
  52. package/dist/client/chunk-II7O4XN3.mjs +2206 -0
  53. package/dist/client/chunk-M3L3KYYR.mjs +1181 -0
  54. package/dist/client/chunk-NWOUL6JY.mjs +1378 -0
  55. package/dist/client/chunk-OJPZEZU2.mjs +31 -0
  56. package/dist/client/chunk-RTZ3JKKX.mjs +178 -0
  57. package/dist/client/chunk-TQ5MSPDX.mjs +74 -0
  58. package/dist/client/chunk-VUAOE3AG.mjs +5592 -0
  59. package/dist/client/chunk-WJXXNDSE.mjs +245 -0
  60. package/dist/client/chunk-YLMKMCSJ.mjs +86 -0
  61. package/dist/client/chunk-ZLMS67RR.mjs +106 -0
  62. package/dist/client/client.mjs +51626 -52074
  63. package/dist/client/courseRegistration-5DPU6PDY.mjs +1737 -0
  64. package/dist/client/{eventCalendar-X6GIPYFM.mjs → eventCalendar-F3GZGTEF.mjs} +13 -2
  65. package/dist/client/{eventCombined-EZUOPM3G.mjs → eventCombined-BQOB6QMY.mjs} +13 -2
  66. package/dist/client/eventDetails-PEM2EJWE.mjs +25 -0
  67. package/dist/client/{eventListing-HEFGAETC.mjs → eventListing-YMIQPVME.mjs} +13 -2
  68. package/dist/client/{eventRegistration-3LCP2V3P.mjs → eventRegistration-4I6ZNDUF.mjs} +13 -2
  69. package/dist/client/form-ZJVAYZ6G.mjs +300 -0
  70. package/dist/client/headerSection-TOT5MGTF.mjs +729 -0
  71. package/dist/client/hooks.mjs +49 -33
  72. package/dist/client/locationMap-J66NZREU.mjs +227 -0
  73. package/dist/client/newsletterForm-ET2XUMRO.mjs +208 -0
  74. package/dist/client/productDetail-C2XIH7C5.mjs +18 -0
  75. package/dist/client/productList-T2AZLFTP.mjs +18 -0
  76. package/dist/client/rendering/client.mjs +11763 -12445
  77. package/dist/client/rendering/islands.mjs +98 -21
  78. package/dist/client/rendering.mjs +46778 -47229
  79. package/dist/client/shop-UZ6IUZXD.mjs +20 -0
  80. package/dist/preview-next/before-render.mjs +37 -25
  81. package/dist/preview-next/client/runtime.mjs +5 -5
  82. package/dist/preview-next/middleware.mjs +37 -25
  83. package/dist/{sdk-runtime-OHNONZ5U.mjs → sdk-runtime-JCUQM63Y.mjs} +6 -6
  84. package/dist/server/components.mjs +409 -266
  85. package/dist/server/config-validation.mjs +49 -33
  86. package/dist/server/config.mjs +49 -33
  87. package/dist/server/data.mjs +49 -33
  88. package/dist/server/index.mjs +45 -33
  89. package/dist/server/next.mjs +405 -262
  90. package/dist/server/page-converter.mjs +12 -8
  91. package/dist/server/prebuild.mjs +1 -1
  92. package/dist/server/rendering/server.mjs +493 -265
  93. package/dist/server/rendering.mjs +411 -268
  94. package/dist/server/routing.mjs +49 -33
  95. package/dist/server/server.mjs +50 -34
  96. package/dist/server/theme-bridge.mjs +5 -0
  97. package/dist/styles/index.css +5 -0
  98. package/package.json +2 -1
  99. package/dist/SdkPreviewModeRuntime-CRYNDSPL.mjs +0 -8
  100. package/dist/client/bookingForm-4X77HKDS.mjs +0 -34
  101. package/dist/client/cart-JWD2VRFU.mjs +0 -11
  102. package/dist/client/checkout-V7KYGWL7.mjs +0 -11
  103. package/dist/client/chunk-5IYGMTUE.mjs +0 -18614
  104. package/dist/client/chunk-RKCFVIMS.mjs +0 -26
  105. package/dist/client/courseRegistration-O6ZPK4YT.mjs +0 -29
  106. package/dist/client/eventDetails-3WODIXET.mjs +0 -14
  107. package/dist/client/form-AKXQMY6Z.mjs +0 -85
  108. package/dist/client/headerSection-5KHCMU6B.mjs +0 -12
  109. package/dist/client/locationMap-7HIADW76.mjs +0 -14
  110. package/dist/client/newsletterForm-5N4YTMU3.mjs +0 -60
  111. package/dist/client/productDetail-IZUA7ZP3.mjs +0 -11
  112. package/dist/client/productList-KWIIJE6I.mjs +0 -11
  113. package/dist/client/shop-XZQFRQWZ.mjs +0 -13
@@ -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 };