@riverbankcms/sdk 0.85.0 → 0.89.1

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 (166) hide show
  1. package/dist/{PreviewEditorSidebar-4PH35ZIE.mjs → PreviewEditorSidebar-JDR64FEC.mjs} +3 -3
  2. package/dist/{PreviewEditorUI-WHMCRJGM.mjs → PreviewEditorUI-67TMJMAF.mjs} +3 -3
  3. package/dist/SdkPreviewModeRuntime-ZBEMRV7N.mjs +8 -0
  4. package/dist/_dts/api/src/accessAdmin.d.ts +7 -0
  5. package/dist/_dts/api/src/endpoints.d.ts +66 -14
  6. package/dist/_dts/api/src/index.d.ts +5 -2
  7. package/dist/_dts/api/src/launchReadiness.d.ts +3 -3
  8. package/dist/_dts/api/src/mailchimpIntegration.d.ts +215 -0
  9. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +35 -15
  10. package/dist/_dts/api/src/siteInfrastructure.d.ts +0 -14
  11. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +5 -1
  12. package/dist/_dts/api/src/siteMembers.d.ts +6 -1
  13. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +1 -13
  14. package/dist/_dts/api/src/types.d.ts +7 -4
  15. package/dist/_dts/blocks/src/PageRenderer.d.ts +1 -0
  16. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +4 -0
  17. package/dist/_dts/blocks/src/index.d.ts +2 -1
  18. package/dist/_dts/blocks/src/system/blocks/appointment-booking.d.ts +288 -288
  19. package/dist/_dts/blocks/src/system/blocks/blog-listing.d.ts +288 -288
  20. package/dist/_dts/blocks/src/system/blocks/cart.d.ts +288 -288
  21. package/dist/_dts/blocks/src/system/blocks/checkout.d.ts +288 -288
  22. package/dist/_dts/blocks/src/system/blocks/collection.d.ts +288 -288
  23. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +42 -0
  24. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +4 -0
  25. package/dist/_dts/blocks/src/system/blocks/faq.d.ts +288 -288
  26. package/dist/_dts/blocks/src/system/blocks/gifting.d.ts +288 -288
  27. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +1 -1
  28. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +42 -42
  29. package/dist/_dts/blocks/src/system/blocks/newsletter-signup-destination.d.ts +300 -0
  30. package/dist/_dts/blocks/src/system/blocks/newsletter-signup.d.ts +63 -3
  31. package/dist/_dts/blocks/src/system/blocks/product-detail.d.ts +288 -288
  32. package/dist/_dts/blocks/src/system/blocks/product-list.d.ts +288 -288
  33. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +288 -288
  34. package/dist/_dts/blocks/src/system/fragments/library/newsletterForm.d.ts +53 -1
  35. package/dist/_dts/blocks/src/system/icons/cta.d.ts +3 -3
  36. package/dist/_dts/blocks/src/system/icons/index.d.ts +1 -0
  37. package/dist/_dts/blocks/src/system/icons/registry.d.ts +2 -2
  38. package/dist/_dts/blocks/src/system/icons/semantic.d.ts +3 -3
  39. package/dist/_dts/blocks/src/system/icons/svg.d.ts +72 -0
  40. package/dist/_dts/blocks/src/system/manifest/richTextSchema.d.ts +27 -0
  41. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +23 -23
  42. package/dist/_dts/blocks/src/system/runtime/api/types.d.ts +11 -2
  43. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +24 -0
  44. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +12 -0
  45. package/dist/_dts/blocks/src/system/runtime/hooks/loadStateError.d.ts +1 -0
  46. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableDates.d.ts +1 -1
  47. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableDates.state.d.ts +55 -0
  48. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableSlots.state.d.ts +39 -0
  49. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingFormConfig.d.ts +4 -27
  50. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingFormConfig.state.d.ts +40 -0
  51. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +20 -0
  52. package/dist/_dts/blocks/src/system/runtime/hooks/useEventFilters.state.d.ts +31 -0
  53. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.d.ts +3 -3
  54. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.state.d.ts +39 -0
  55. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +1 -0
  56. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +4 -0
  57. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.server.d.ts +1 -1
  58. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventPaginatedListView.client.d.ts +1 -1
  59. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/utils.d.ts +11 -1
  60. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.client.state.d.ts +24 -2
  61. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +15 -0
  62. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.server.d.ts +1 -1
  63. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.submission.d.ts +32 -0
  64. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +5 -1
  65. package/dist/_dts/blocks/src/system/runtime/nodes/shared/MagicLinkForm.state.d.ts +24 -0
  66. package/dist/_dts/blocks/src/system/runtime/shared/components/ModalShell.d.ts +5 -1
  67. package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.state.d.ts +35 -0
  68. package/dist/_dts/blocks/src/system/runtime/shared/utils/formatting.d.ts +1 -1
  69. package/dist/_dts/content-model/src/entry-slots/types.d.ts +54 -0
  70. package/dist/_dts/content-model/src/referenceFields.d.ts +1 -1
  71. package/dist/_dts/core/src/branded.d.ts +7 -0
  72. package/dist/_dts/core/src/currency-format.d.ts +37 -2
  73. package/dist/_dts/core/src/event-pricing.d.ts +24 -0
  74. package/dist/_dts/core/src/index.d.ts +1 -0
  75. package/dist/_dts/core/src/site-route-target.d.ts +40 -0
  76. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +705 -17
  77. package/dist/_dts/editor-blocks/src/widgets/reference/loaders.d.ts +3 -1
  78. package/dist/_dts/media-core/src/fileDomain.d.ts +4 -0
  79. package/dist/_dts/sdk/src/client/runtimeCachePolicy.d.ts +160 -0
  80. package/dist/_dts/sdk/src/client/types.d.ts +35 -1
  81. package/dist/_dts/sdk/src/config/validation.d.ts +3 -0
  82. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +3 -0
  83. package/dist/_dts/sdk/src/data/prefetchBlockData.d.ts +3 -9
  84. package/dist/_dts/sdk/src/index.d.ts +3 -1
  85. package/dist/_dts/sdk/src/manifest/passes/pass1-fields.d.ts +1 -1
  86. package/dist/_dts/sdk/src/manifest/three-pass-converter.d.ts +7 -18
  87. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +2 -0
  88. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +3 -1
  89. package/dist/_dts/sdk/src/rendering/helpers/loadContent.d.ts +7 -3
  90. package/dist/_dts/sdk/src/rendering/helpers/loadPage.d.ts +4 -24
  91. package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +45 -0
  92. package/dist/_dts/sdk/src/version.d.ts +1 -1
  93. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  94. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +9 -9
  95. package/dist/_dts/theme-core/src/schema.d.ts +11 -11
  96. package/dist/{chunk-PYDHOMEO.mjs → chunk-7N46MZHI.mjs} +1 -1
  97. package/dist/{chunk-ZR2GQK2A.mjs → chunk-7YUAXONX.mjs} +1880 -588
  98. package/dist/{chunk-4QNLOTES.mjs → chunk-F645A5UV.mjs} +76 -14
  99. package/dist/{chunk-OCGTXHSO.mjs → chunk-HKJQERFR.mjs} +7 -7
  100. package/dist/{chunk-NFWGLRZZ.mjs → chunk-TGBJWKMP.mjs} +37 -3
  101. package/dist/{chunk-WFPYN7KA.mjs → chunk-ZQRBLCW5.mjs} +2 -2
  102. package/dist/cli/index.mjs +1075 -126
  103. package/dist/client/{accordion-2UZPBMYM.mjs → accordion-MUCVNGQ7.mjs} +2 -2
  104. package/dist/client/{bookingForm-36CWQUMV.mjs → bookingForm-PKD6EFIE.mjs} +193 -77
  105. package/dist/client/bookings.mjs +487 -197
  106. package/dist/client/{carousel-QH77HR6X.mjs → carousel-3TKQSNJC.mjs} +4 -3
  107. package/dist/client/cart-6XHSZK23.mjs +19 -0
  108. package/dist/client/checkout-FVSPM6FI.mjs +19 -0
  109. package/dist/client/{chunk-ZE5G642V.mjs → chunk-25W2EQUN.mjs} +75 -1
  110. package/dist/client/chunk-6N7YRNYU.mjs +183 -0
  111. package/dist/client/{chunk-4OXKTA3D.mjs → chunk-7DH35FGA.mjs} +2 -2
  112. package/dist/client/{chunk-3C2VTPWI.mjs → chunk-CQKKFEQD.mjs} +363 -66
  113. package/dist/client/{chunk-7UCLJ5SP.mjs → chunk-EY42X22F.mjs} +4 -7
  114. package/dist/client/{chunk-SYIJ5JO2.mjs → chunk-FHU6PFPM.mjs} +1 -1
  115. package/dist/client/{chunk-ZKUO52W3.mjs → chunk-LQFDYWPJ.mjs} +1 -1
  116. package/dist/client/chunk-RSQWWUAD.mjs +390 -0
  117. package/dist/client/{chunk-UDNSI5PY.mjs → chunk-STJ2NCQM.mjs} +2 -3
  118. package/dist/client/{chunk-VGDBVNOO.mjs → chunk-UQFY4AHX.mjs} +511 -406
  119. package/dist/client/{chunk-F5VRX5Y6.mjs → chunk-VGLXACVK.mjs} +1 -1
  120. package/dist/client/{chunk-DVNUDUVT.mjs → chunk-WBQG7VJA.mjs} +4 -1
  121. package/dist/client/{chunk-52CGCQ7B.mjs → chunk-ZJZZA5EP.mjs} +10 -80
  122. package/dist/client/{chunk-XSV6KW4D.mjs → chunk-ZT5XE7FK.mjs} +1 -1
  123. package/dist/client/client.mjs +5820 -4782
  124. package/dist/client/{courseRegistration-TMKU6ABO.mjs → courseRegistration-ATZSYDHM.mjs} +7 -7
  125. package/dist/client/{eventCalendar-G6TI32X6.mjs → eventCalendar-6T2UGKKP.mjs} +11 -11
  126. package/dist/client/{eventCombined-SCKEMNAR.mjs → eventCombined-Q4VANXVF.mjs} +11 -11
  127. package/dist/client/{eventDetails-XPIFXXPK.mjs → eventDetails-DW37E7VW.mjs} +11 -11
  128. package/dist/client/{eventListing-7QFMEMGT.mjs → eventListing-XURTSAUW.mjs} +11 -11
  129. package/dist/client/{eventRegistration-TOODSZUI.mjs → eventRegistration-MRKEVAXW.mjs} +11 -11
  130. package/dist/client/{form-MTCMVCZT.mjs → form-WZZFFGMU.mjs} +3 -3
  131. package/dist/client/{headerSection-Y5TMR3TW.mjs → headerSection-EQYVQBLM.mjs} +4 -4
  132. package/dist/client/hooks.mjs +1700 -1412
  133. package/dist/client/{locationMap-RH2LG7FZ.mjs → locationMap-MFF5VAZR.mjs} +3 -4
  134. package/dist/client/{newsletterForm-PCAIPFMA.mjs → newsletterForm-JQ77UYIE.mjs} +127 -43
  135. package/dist/client/{productDetail-OIGDR4YE.mjs → productDetail-25LMT3IZ.mjs} +9 -9
  136. package/dist/client/{productList-4MA5S2CX.mjs → productList-5ABEMKUG.mjs} +9 -9
  137. package/dist/client/rendering/client.mjs +3884 -3722
  138. package/dist/client/rendering/islands.mjs +19 -19
  139. package/dist/client/rendering.mjs +6774 -6331
  140. package/dist/client/shop-OMMQZ6YO.mjs +21 -0
  141. package/dist/preview-next/before-render.mjs +76 -14
  142. package/dist/preview-next/client/runtime.mjs +5 -5
  143. package/dist/preview-next/editor-chrome.css +56 -9
  144. package/dist/preview-next/middleware.mjs +76 -14
  145. package/dist/{sdk-runtime-QLOCYKVU.mjs → sdk-runtime-WNLBZ3ZH.mjs} +6 -6
  146. package/dist/server/components.mjs +2579 -2548
  147. package/dist/server/config-validation.mjs +1737 -1461
  148. package/dist/server/config.mjs +1737 -1461
  149. package/dist/server/data.mjs +1701 -1413
  150. package/dist/server/index.mjs +1048 -400
  151. package/dist/server/next.mjs +3602 -2858
  152. package/dist/server/page-converter.mjs +2193 -1169
  153. package/dist/server/prebuild.mjs +1 -1
  154. package/dist/server/rendering/server.mjs +2770 -2742
  155. package/dist/server/rendering.mjs +2961 -2886
  156. package/dist/server/routing.mjs +2186 -1508
  157. package/dist/server/server.mjs +2237 -1287
  158. package/dist/server/theme-bridge.mjs +260 -0
  159. package/dist/styles/index.css +258 -0
  160. package/package.json +2 -1
  161. package/dist/SdkPreviewModeRuntime-4FGSVUYI.mjs +0 -8
  162. package/dist/client/cart-X4YK4FTW.mjs +0 -19
  163. package/dist/client/checkout-OM2BEPWD.mjs +0 -19
  164. package/dist/client/chunk-3DTWLTXM.mjs +0 -204
  165. package/dist/client/chunk-I2MMZO53.mjs +0 -6
  166. package/dist/client/shop-WXSYV5QO.mjs +0 -21
@@ -773,6 +773,64 @@ var ENDPOINT_DEFINITIONS = {
773
773
  auth: "user",
774
774
  responseKind: "json"
775
775
  },
776
+ listMailchimpAudiences: {
777
+ path: "/sites/{siteId}/integrations/mailchimp/audiences",
778
+ method: "GET",
779
+ tags: [TAG_TEMPLATES.site],
780
+ auth: "user",
781
+ responseKind: "json",
782
+ errors: ["auth:forbidden", "server:internal_error"]
783
+ },
784
+ getMailchimpSignupSyncHealth: {
785
+ path: "/sites/{siteId}/integrations/mailchimp/signup-sync-health",
786
+ method: "GET",
787
+ tags: [TAG_TEMPLATES.site],
788
+ auth: "user",
789
+ responseKind: "json",
790
+ errors: ["auth:forbidden", "server:internal_error"]
791
+ },
792
+ getMailchimpConnection: {
793
+ path: "/sites/{siteId}/integrations/mailchimp/connection",
794
+ method: "GET",
795
+ tags: [TAG_TEMPLATES.site],
796
+ auth: "user",
797
+ responseKind: "json",
798
+ errors: ["auth:forbidden", "server:internal_error"]
799
+ },
800
+ startMailchimpOAuth: {
801
+ path: "/sites/{siteId}/integrations/mailchimp/oauth/start",
802
+ method: "POST",
803
+ tags: [TAG_TEMPLATES.site],
804
+ auth: "user",
805
+ responseKind: "json",
806
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
807
+ errors: ["auth:forbidden", "validation:invalid_input", "server:internal_error"]
808
+ },
809
+ refreshMailchimpAudiences: {
810
+ path: "/sites/{siteId}/integrations/mailchimp/audiences/refresh",
811
+ method: "POST",
812
+ tags: [TAG_TEMPLATES.site],
813
+ auth: "user",
814
+ responseKind: "json",
815
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
816
+ errors: ["auth:forbidden", "server:internal_error"]
817
+ },
818
+ disconnectMailchimp: {
819
+ path: "/sites/{siteId}/integrations/mailchimp/disconnect",
820
+ method: "POST",
821
+ tags: [TAG_TEMPLATES.site],
822
+ auth: "user",
823
+ responseKind: "json",
824
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
825
+ errors: ["auth:forbidden", "server:internal_error"]
826
+ },
827
+ mailchimpOAuthCallback: {
828
+ path: "/auth/mailchimp/callback",
829
+ method: "GET",
830
+ auth: "public",
831
+ responseKind: "void",
832
+ errors: []
833
+ },
776
834
  createNewsletterList: {
777
835
  path: "/sites/{siteId}/newsletter/lists",
778
836
  method: "POST",
@@ -1774,6 +1832,24 @@ var ENDPOINT_DEFINITIONS = {
1774
1832
  auth: "user",
1775
1833
  responseKind: "json"
1776
1834
  },
1835
+ resendSiteInvitation: {
1836
+ path: "/sites/{siteId}/members/invitations/{invitationId}/resend",
1837
+ method: "POST",
1838
+ errors: [
1839
+ "auth:forbidden",
1840
+ "resource:not_found",
1841
+ "validation:invalid_input",
1842
+ "external:service_error",
1843
+ "server:internal_error"
1844
+ ],
1845
+ tags: [
1846
+ "site-{siteId}",
1847
+ "site-members-{siteId}",
1848
+ "site-invite-{invitationId}"
1849
+ ],
1850
+ auth: "user",
1851
+ responseKind: "json"
1852
+ },
1777
1853
  transferSiteOwnership: {
1778
1854
  path: "/sites/{siteId}/members/transfer-ownership",
1779
1855
  method: "POST",
@@ -2997,20 +3073,6 @@ var ENDPOINT_DEFINITIONS = {
2997
3073
  auth: "user",
2998
3074
  responseKind: "json"
2999
3075
  },
3000
- instagramUploadZip: {
3001
- path: "/instagram/upload-zip",
3002
- method: "POST",
3003
- tags: ["instagram-import"],
3004
- auth: "user",
3005
- responseKind: "json"
3006
- },
3007
- createInstagramZipUploadUrl: {
3008
- path: "/instagram/upload-zip-url",
3009
- method: "POST",
3010
- tags: ["instagram-import"],
3011
- auth: "user",
3012
- responseKind: "json"
3013
- },
3014
3076
  getAnalyticsReport: {
3015
3077
  path: "/sites/{siteId}/analytics/report",
3016
3078
  method: "GET",
@@ -6965,7 +7027,7 @@ var SimpleCache = class {
6965
7027
  };
6966
7028
 
6967
7029
  // src/version.ts
6968
- var SDK_VERSION = "0.85.0";
7030
+ var SDK_VERSION = "0.89.1";
6969
7031
 
6970
7032
  // src/client/error.ts
6971
7033
  var RiverbankApiError = class _RiverbankApiError extends Error {
@@ -7128,201 +7190,775 @@ function getResilienceStatusFromError(error) {
7128
7190
  return error[resilienceStatusSymbol];
7129
7191
  }
7130
7192
 
7131
- // src/client/resilience.ts
7132
- var DEFAULT_RETRY_CONFIG = {
7133
- maxAttempts: 3,
7134
- baseDelayMs: 200,
7135
- maxDelayMs: 2e3,
7136
- jitter: "full"
7137
- };
7138
- var DEFAULT_CIRCUIT_BREAKER_CONFIG = {
7139
- failureThreshold: 5,
7140
- resetTimeoutMs: 3e4,
7141
- halfOpenMaxRequests: 2
7142
- };
7143
- var PERMANENT_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
7144
- "ECONNREFUSED",
7145
- // Server is not running / port not listening
7146
- "ENOTFOUND",
7147
- // DNS lookup failed - hostname doesn't exist
7148
- "EAI_AGAIN"
7149
- // DNS lookup timeout (usually permanent for invalid hosts)
7150
- ]);
7151
- var TRANSIENT_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
7152
- "ECONNRESET",
7153
- // Connection was reset mid-request (server dropped it)
7154
- "EPIPE",
7155
- // Broken pipe (connection closed while writing)
7156
- "ETIMEDOUT",
7157
- // Connection timed out (could be temporary congestion)
7158
- "ESOCKETTIMEDOUT"
7159
- // Socket timeout
7160
- ]);
7161
- var NODE_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
7162
- // Permanent
7163
- "ECONNREFUSED",
7164
- "ENOTFOUND",
7165
- "EAI_AGAIN",
7166
- // Transient
7167
- "ECONNRESET",
7168
- "EPIPE",
7169
- "ETIMEDOUT",
7170
- "ESOCKETTIMEDOUT"
7171
- ]);
7172
- function isNodeNetworkErrorCode(code) {
7173
- return !code.includes(":") && NODE_NETWORK_ERROR_CODES.has(code);
7174
- }
7175
- function getErrorCodeFromCause(error) {
7176
- let current = error;
7177
- while (current) {
7178
- const nodeError = current;
7179
- if (nodeError.code && typeof nodeError.code === "string") {
7180
- if (isNodeNetworkErrorCode(nodeError.code)) {
7181
- return nodeError.code;
7182
- }
7183
- }
7184
- const errorWithCause = current;
7185
- current = errorWithCause.cause;
7186
- }
7187
- return void 0;
7188
- }
7189
- function isTransientError(error) {
7190
- if (error instanceof RiverbankApiError) {
7191
- const errorCode = getErrorCodeFromCause(error);
7192
- if (errorCode && PERMANENT_NETWORK_ERROR_CODES.has(errorCode)) {
7193
- return false;
7194
- }
7195
- if (error.status === 0) return true;
7196
- if (error.status === 429) return true;
7197
- if (error.status >= 500) return true;
7198
- return false;
7199
- }
7200
- if (error instanceof TypeError) {
7201
- const errorCode = getErrorCodeFromCause(error);
7202
- if (errorCode) {
7203
- if (PERMANENT_NETWORK_ERROR_CODES.has(errorCode)) {
7204
- return false;
7205
- }
7206
- if (TRANSIENT_NETWORK_ERROR_CODES.has(errorCode)) {
7207
- return true;
7208
- }
7209
- }
7210
- return true;
7211
- }
7212
- return true;
7213
- }
7214
- function calculateBackoff(attempt, config) {
7215
- const baseDelayMs = config.baseDelayMs ?? DEFAULT_RETRY_CONFIG.baseDelayMs;
7216
- const maxDelayMs = config.maxDelayMs ?? DEFAULT_RETRY_CONFIG.maxDelayMs;
7217
- const jitter = config.jitter ?? DEFAULT_RETRY_CONFIG.jitter;
7218
- const exponential = baseDelayMs * Math.pow(2, attempt - 1);
7219
- const capped = Math.min(exponential, maxDelayMs);
7220
- if (jitter === "full") {
7221
- return Math.random() * capped;
7222
- }
7223
- return capped;
7224
- }
7225
- var CircuitBreaker = class {
7226
- constructor(config) {
7227
- this.state = "closed";
7228
- this.failureCount = 0;
7229
- this.successCount = 0;
7230
- this.openUntil = 0;
7231
- this.halfOpenRequests = 0;
7232
- this.config = {
7233
- failureThreshold: config?.failureThreshold ?? DEFAULT_CIRCUIT_BREAKER_CONFIG.failureThreshold,
7234
- resetTimeoutMs: config?.resetTimeoutMs ?? DEFAULT_CIRCUIT_BREAKER_CONFIG.resetTimeoutMs,
7235
- halfOpenMaxRequests: config?.halfOpenMaxRequests ?? DEFAULT_CIRCUIT_BREAKER_CONFIG.halfOpenMaxRequests
7236
- };
7237
- }
7238
- /**
7239
- * Check if circuit is open (requests should be blocked)
7240
- * Also handles automatic transition from open to half-open after timeout
7241
- */
7242
- isOpen() {
7243
- if (this.state === "open" && Date.now() >= this.openUntil) {
7244
- this.transitionTo("half-open");
7245
- }
7246
- return this.state === "open";
7247
- }
7248
- /**
7249
- * Check if a request can be attempted
7250
- * - closed: always yes
7251
- * - open: always no
7252
- * - half-open: limited number of probes
7253
- */
7254
- canAttempt() {
7255
- if (this.state === "closed") return true;
7256
- if (this.state === "open") return false;
7257
- return this.halfOpenRequests < this.config.halfOpenMaxRequests;
7258
- }
7259
- /**
7260
- * Increment half-open request counter (call before making request in half-open)
7261
- */
7262
- incrementHalfOpenRequests() {
7263
- if (this.state === "half-open") {
7264
- this.halfOpenRequests++;
7265
- }
7266
- }
7267
- /**
7268
- * Record a successful request
7269
- */
7270
- recordSuccess() {
7271
- if (this.state === "half-open") {
7272
- this.successCount++;
7273
- if (this.successCount >= this.config.halfOpenMaxRequests) {
7274
- this.transitionTo("closed");
7275
- }
7276
- } else {
7277
- this.failureCount = 0;
7278
- }
7279
- }
7280
- /**
7281
- * Record a failed request
7282
- * Only counts transient failures toward circuit breaker threshold
7283
- */
7284
- recordFailure(error) {
7285
- if (!isTransientError(error)) return;
7286
- this.failureCount++;
7287
- if (this.state === "half-open") {
7288
- this.transitionTo("open");
7289
- } else if (this.failureCount >= this.config.failureThreshold) {
7290
- this.transitionTo("open");
7291
- }
7292
- }
7293
- /**
7294
- * Get current circuit state
7295
- */
7296
- getState() {
7297
- return {
7298
- state: this.state,
7299
- failureCount: this.failureCount,
7300
- openUntil: this.state === "open" ? this.openUntil : void 0
7301
- };
7302
- }
7303
- /**
7304
- * Transition to a new state
7305
- */
7306
- transitionTo(newState) {
7307
- this.state = newState;
7308
- if (newState === "open") {
7309
- this.openUntil = Date.now() + this.config.resetTimeoutMs;
7310
- } else if (newState === "half-open") {
7311
- this.halfOpenRequests = 0;
7312
- this.successCount = 0;
7313
- } else if (newState === "closed") {
7314
- this.failureCount = 0;
7315
- this.successCount = 0;
7316
- this.halfOpenRequests = 0;
7317
- }
7318
- }
7319
- };
7320
- async function fetchWithTimeoutAndRetry(fetcher, config) {
7321
- const maxAttempts = config.maxAttempts ?? DEFAULT_RETRY_CONFIG.maxAttempts;
7322
- const requestTimeoutMs = config.requestTimeoutMs ?? 8e3;
7323
- let lastError;
7324
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
7325
- try {
7193
+ // src/public-api/runtime.ts
7194
+ var PUBLIC_ENDPOINT_NAMES2 = [
7195
+ "getSite",
7196
+ "getContentByPath",
7197
+ "listPublishedEntries",
7198
+ "getPublishedEntryPreview",
7199
+ "getPublicFormById",
7200
+ "listPublicForms",
7201
+ "getPublicBookingServices",
7202
+ "getPublicChallenge",
7203
+ "listPublicEvents",
7204
+ "batchBlockLoaders",
7205
+ "listPublicCourses",
7206
+ "listPublicTeamMembers",
7207
+ "listPublicProducts",
7208
+ "listPublicPasses",
7209
+ "listPublicMemberships",
7210
+ "resolveEntrySubroute",
7211
+ "resolveEventOccurrence",
7212
+ "checkRedirect",
7213
+ "getRoutableContent",
7214
+ "getPublicRoutableContent",
7215
+ "getPublicSitemapRoutes"
7216
+ ];
7217
+ var API_ENDPOINTS2 = Object.freeze({
7218
+ getSite: {
7219
+ path: "/sites",
7220
+ method: "GET",
7221
+ revalidate: 900,
7222
+ tags: ["riverbank:site", "riverbank:site:id:{id}", "riverbank:site:slug:{slug}", "riverbank:site:domain:{domain}"],
7223
+ auth: "public",
7224
+ responseKind: "json"
7225
+ },
7226
+ getContentByPath: {
7227
+ path: "/sites/{siteId}/pages",
7228
+ method: "GET",
7229
+ tags: ["riverbank:site:{siteId}:routable-content"],
7230
+ auth: "public",
7231
+ responseKind: "json"
7232
+ },
7233
+ listPublishedEntries: {
7234
+ path: "/public/content/{siteId}/{type}/entries",
7235
+ method: "GET",
7236
+ revalidate: 60,
7237
+ tags: ["content-{siteId}-{type}"],
7238
+ auth: "public",
7239
+ responseKind: "json"
7240
+ },
7241
+ getPublishedEntryPreview: {
7242
+ path: "/public/content/{siteId}/{type}/{slug}/preview",
7243
+ method: "GET",
7244
+ revalidate: 60,
7245
+ tags: ["content-{siteId}-{type}-{slug}"],
7246
+ auth: "public",
7247
+ responseKind: "json"
7248
+ },
7249
+ getPublicFormById: {
7250
+ path: "/public/forms/{formId}",
7251
+ method: "GET",
7252
+ revalidate: 60,
7253
+ tags: ["riverbank:form:{formId}"],
7254
+ auth: "public",
7255
+ responseKind: "json"
7256
+ },
7257
+ listPublicForms: {
7258
+ path: "/public/sites/{siteId}/forms",
7259
+ method: "GET",
7260
+ revalidate: 60,
7261
+ tags: ["riverbank:site:{siteId}:forms"],
7262
+ auth: "public",
7263
+ responseKind: "json"
7264
+ },
7265
+ getPublicBookingServices: {
7266
+ path: "/public/bookings/services",
7267
+ method: "GET",
7268
+ revalidate: 60,
7269
+ tags: ["site-{siteId}"],
7270
+ auth: "public",
7271
+ responseKind: "json"
7272
+ },
7273
+ getPublicChallenge: {
7274
+ path: "/public/challenge",
7275
+ method: "GET",
7276
+ auth: "public",
7277
+ responseKind: "text"
7278
+ },
7279
+ listPublicEvents: {
7280
+ path: "/public/sites/{siteId}/events",
7281
+ method: "GET",
7282
+ revalidate: 60,
7283
+ tags: ["riverbank:site:{siteId}:public-events"],
7284
+ auth: "public",
7285
+ responseKind: "json"
7286
+ },
7287
+ batchBlockLoaders: {
7288
+ path: "/public/sites/{siteId}/block-loaders/batch",
7289
+ method: "POST",
7290
+ auth: "public",
7291
+ responseKind: "json"
7292
+ },
7293
+ listPublicCourses: {
7294
+ path: "/public/sites/{siteId}/courses",
7295
+ method: "GET",
7296
+ revalidate: 60,
7297
+ tags: ["riverbank:site:{siteId}:public-courses"],
7298
+ auth: "public",
7299
+ responseKind: "json"
7300
+ },
7301
+ listPublicTeamMembers: {
7302
+ path: "/public/sites/{siteId}/team-members",
7303
+ method: "GET",
7304
+ revalidate: 60,
7305
+ tags: ["riverbank:site:{siteId}:public-team-members"],
7306
+ auth: "public",
7307
+ responseKind: "json"
7308
+ },
7309
+ listPublicProducts: {
7310
+ path: "/public/sites/{siteId}/products",
7311
+ method: "GET",
7312
+ revalidate: 300,
7313
+ tags: ["riverbank:site:{siteId}:public-products"],
7314
+ auth: "public",
7315
+ responseKind: "json"
7316
+ },
7317
+ listPublicPasses: {
7318
+ path: "/public/sites/{siteId}/bookings/products/passes",
7319
+ method: "GET",
7320
+ revalidate: 300,
7321
+ tags: ["riverbank:site:{siteId}:public-passes"],
7322
+ auth: "public",
7323
+ responseKind: "json"
7324
+ },
7325
+ listPublicMemberships: {
7326
+ path: "/public/sites/{siteId}/bookings/products/memberships",
7327
+ method: "GET",
7328
+ revalidate: 300,
7329
+ tags: ["riverbank:site:{siteId}:public-memberships"],
7330
+ auth: "public",
7331
+ responseKind: "json"
7332
+ },
7333
+ resolveEntrySubroute: {
7334
+ path: "/public/sites/{siteId}/routing/subroutes/resolve",
7335
+ method: "GET",
7336
+ revalidate: 60,
7337
+ tags: ["site-{siteId}", "entry-subroute"],
7338
+ auth: "public",
7339
+ responseKind: "json"
7340
+ },
7341
+ resolveEventOccurrence: {
7342
+ path: "/public/sites/{siteId}/events/occurrences/resolve",
7343
+ method: "GET",
7344
+ revalidate: 60,
7345
+ tags: ["riverbank:site:{siteId}:public-events", "event-occurrence"],
7346
+ auth: "public",
7347
+ responseKind: "json"
7348
+ },
7349
+ checkRedirect: {
7350
+ path: "/public/content/redirect",
7351
+ method: "GET",
7352
+ revalidate: 86400,
7353
+ tags: ["redirect"],
7354
+ auth: "public",
7355
+ responseKind: "json"
7356
+ },
7357
+ getRoutableContent: {
7358
+ path: "/sites/{siteId}/routable-content",
7359
+ method: "GET",
7360
+ revalidate: 60,
7361
+ tags: ["riverbank:site:{siteId}:routable-content"],
7362
+ auth: "user",
7363
+ responseKind: "json"
7364
+ },
7365
+ getPublicRoutableContent: {
7366
+ path: "/public/sites/{siteId}/routable-content",
7367
+ method: "GET",
7368
+ revalidate: 60,
7369
+ tags: ["riverbank:site:{siteId}:routable-content"],
7370
+ auth: "public",
7371
+ responseKind: "json"
7372
+ },
7373
+ getPublicSitemapRoutes: {
7374
+ path: "/public/sites/{siteId}/sitemap",
7375
+ method: "GET",
7376
+ revalidate: 60,
7377
+ tags: ["riverbank:site:{siteId}:routable-content", "riverbank:site:{siteId}:settings"],
7378
+ auth: "public",
7379
+ responseKind: "json"
7380
+ }
7381
+ });
7382
+ function buildEndpointURL2(baseURL, endpoint) {
7383
+ return baseURL + API_ENDPOINTS2[endpoint].path;
7384
+ }
7385
+
7386
+ // src/client/runtimeCachePolicy.ts
7387
+ var DEFAULT_PUBLISHED_RUNTIME_CACHE_PAYLOAD_SCHEMA_VERSION = 1;
7388
+ var DEFAULT_STALE_TTL_SEC = 24 * 60 * 60;
7389
+ var DEFAULT_MEMORY_TTL_SEC = 60;
7390
+ var RUNTIME_CACHE_DURABILITY_OVERRIDES = {
7391
+ getSite: {
7392
+ kind: "durable-public-stale",
7393
+ staleTtlSec: DEFAULT_STALE_TTL_SEC
7394
+ },
7395
+ getContentByPath: {
7396
+ kind: "durable-public-stale",
7397
+ staleTtlSec: DEFAULT_STALE_TTL_SEC
7398
+ },
7399
+ listPublishedEntries: {
7400
+ kind: "memory-only",
7401
+ reason: "durable_rollout_pending"
7402
+ },
7403
+ getPublishedEntryPreview: {
7404
+ kind: "memory-only",
7405
+ reason: "durable_rollout_pending"
7406
+ },
7407
+ getPublicFormById: {
7408
+ kind: "memory-only",
7409
+ reason: "durable_rollout_pending"
7410
+ },
7411
+ listPublicForms: {
7412
+ kind: "memory-only",
7413
+ reason: "durable_rollout_pending"
7414
+ },
7415
+ getPublicBookingServices: {
7416
+ kind: "live-only",
7417
+ reason: "safety_sensitive_booking"
7418
+ },
7419
+ getPublicChallenge: {
7420
+ kind: "live-only",
7421
+ reason: "challenge_endpoint"
7422
+ },
7423
+ listPublicEvents: {
7424
+ kind: "memory-only",
7425
+ reason: "durable_rollout_pending"
7426
+ },
7427
+ batchBlockLoaders: {
7428
+ kind: "live-only",
7429
+ reason: "opaque_batch_loader"
7430
+ },
7431
+ listPublicCourses: {
7432
+ kind: "memory-only",
7433
+ reason: "durable_rollout_pending"
7434
+ },
7435
+ listPublicTeamMembers: {
7436
+ kind: "memory-only",
7437
+ reason: "durable_rollout_pending"
7438
+ },
7439
+ listPublicProducts: {
7440
+ kind: "memory-only",
7441
+ reason: "durable_rollout_pending"
7442
+ },
7443
+ listPublicPasses: {
7444
+ kind: "live-only",
7445
+ reason: "safety_sensitive_booking"
7446
+ },
7447
+ listPublicMemberships: {
7448
+ kind: "live-only",
7449
+ reason: "safety_sensitive_booking"
7450
+ },
7451
+ resolveEntrySubroute: {
7452
+ kind: "memory-only",
7453
+ reason: "durable_rollout_pending"
7454
+ },
7455
+ resolveEventOccurrence: {
7456
+ kind: "memory-only",
7457
+ reason: "durable_rollout_pending"
7458
+ },
7459
+ checkRedirect: {
7460
+ kind: "memory-only",
7461
+ reason: "durable_rollout_pending"
7462
+ },
7463
+ getRoutableContent: {
7464
+ kind: "live-only",
7465
+ reason: "auth_required"
7466
+ },
7467
+ getPublicRoutableContent: {
7468
+ kind: "memory-only",
7469
+ reason: "durable_rollout_pending"
7470
+ },
7471
+ getPublicSitemapRoutes: {
7472
+ kind: "memory-only",
7473
+ reason: "durable_rollout_pending"
7474
+ }
7475
+ };
7476
+ var PUBLIC_ENDPOINT_NAME_SET = new Set(PUBLIC_ENDPOINT_NAMES2);
7477
+ function isPublicEndpointName(endpoint) {
7478
+ return PUBLIC_ENDPOINT_NAME_SET.has(endpoint);
7479
+ }
7480
+ function isTruthyParam(value) {
7481
+ return value === true || value === "true" || value === 1 || value === "1";
7482
+ }
7483
+ function isPreviewRequest(endpoint, params) {
7484
+ if (endpoint === "getContentByPath") {
7485
+ return isTruthyParam(params.preview);
7486
+ }
7487
+ if (endpoint === "listPublishedEntries" || endpoint === "resolveEntrySubroute" || endpoint === "resolveEventOccurrence") {
7488
+ return params.stage === "preview";
7489
+ }
7490
+ return false;
7491
+ }
7492
+ function getEndpointFreshTtlSec(endpoint) {
7493
+ return API_ENDPOINTS2[endpoint].revalidate ?? DEFAULT_MEMORY_TTL_SEC;
7494
+ }
7495
+ function assertNever(value) {
7496
+ throw new Error(`Unhandled runtime cache policy override: ${String(value)}`);
7497
+ }
7498
+ function resolveKnownEndpointPolicy(endpoint, params) {
7499
+ if (isPreviewRequest(endpoint, params)) {
7500
+ return { kind: "live-only", endpoint, reason: "preview_request" };
7501
+ }
7502
+ if (endpoint === "getSite" && isTruthyParam(params.force)) {
7503
+ return { kind: "live-only", endpoint, reason: "force_refresh" };
7504
+ }
7505
+ const override = RUNTIME_CACHE_DURABILITY_OVERRIDES[endpoint];
7506
+ if (override.kind === "live-only") {
7507
+ return { kind: "live-only", endpoint, reason: override.reason };
7508
+ }
7509
+ const endpointDefinition = API_ENDPOINTS2[endpoint];
7510
+ if (endpointDefinition.method !== "GET") {
7511
+ return { kind: "live-only", endpoint, reason: "non_get_request" };
7512
+ }
7513
+ if (endpointDefinition.auth === "user") {
7514
+ return { kind: "live-only", endpoint, reason: "auth_required" };
7515
+ }
7516
+ switch (override.kind) {
7517
+ case "durable-public-stale":
7518
+ return {
7519
+ kind: "durable-public-stale",
7520
+ endpoint,
7521
+ freshTtlSec: getEndpointFreshTtlSec(endpoint),
7522
+ staleTtlSec: override.staleTtlSec
7523
+ };
7524
+ case "memory-only":
7525
+ return {
7526
+ kind: "memory-only",
7527
+ endpoint,
7528
+ freshTtlSec: getEndpointFreshTtlSec(endpoint),
7529
+ reason: override.reason
7530
+ };
7531
+ default:
7532
+ return assertNever(override);
7533
+ }
7534
+ }
7535
+ function resolveRuntimeCachePolicy(input) {
7536
+ if (input.method && input.method.toUpperCase() !== "GET") {
7537
+ return {
7538
+ kind: "live-only",
7539
+ endpoint: input.endpoint,
7540
+ reason: "non_get_request"
7541
+ };
7542
+ }
7543
+ if (!isPublicEndpointName(input.endpoint)) {
7544
+ return {
7545
+ kind: "live-only",
7546
+ endpoint: input.endpoint,
7547
+ reason: "unknown_endpoint"
7548
+ };
7549
+ }
7550
+ return resolveKnownEndpointPolicy(input.endpoint, input.params ?? {});
7551
+ }
7552
+ function toNonEmptyString(value) {
7553
+ if (value === null || value === void 0) return null;
7554
+ if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") {
7555
+ return null;
7556
+ }
7557
+ const normalized = String(value).trim();
7558
+ return normalized.length > 0 ? normalized : null;
7559
+ }
7560
+ function normalizeRuntimePublicPath(value) {
7561
+ const raw = toNonEmptyString(value) ?? "/";
7562
+ const withoutQuery = raw.split(/[?#]/, 1)[0] ?? "/";
7563
+ const withLeadingSlash = withoutQuery.startsWith("/") ? withoutQuery : `/${withoutQuery}`;
7564
+ const collapsed = withLeadingSlash.replace(/\/{2,}/g, "/");
7565
+ const withoutTrailingSlash = collapsed.length > 1 ? collapsed.replace(/\/+$/g, "") : collapsed;
7566
+ return withoutTrailingSlash || "/";
7567
+ }
7568
+ function normalizeRuntimeHostname(value) {
7569
+ const trimmed = value.trim().toLowerCase();
7570
+ const url = /^[a-z][a-z0-9+.-]*:\/\//.test(trimmed) ? new URL(trimmed) : new URL(`http://${trimmed}`);
7571
+ return url.hostname.replace(/\.$/, "");
7572
+ }
7573
+ function normalizeScalar(value) {
7574
+ return value.trim().toLowerCase();
7575
+ }
7576
+ function encodeKeyPart(key, value) {
7577
+ return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
7578
+ }
7579
+ function unsafeAsPublishedRuntimeCacheKey(value) {
7580
+ return value;
7581
+ }
7582
+ function buildPublishedRuntimeCacheKey(endpoint, normalizedParams) {
7583
+ const encodedParams = Object.entries(normalizedParams).sort(([left], [right]) => left.localeCompare(right)).map(([key, value]) => encodeKeyPart(key, value)).join(":");
7584
+ return unsafeAsPublishedRuntimeCacheKey(
7585
+ `published-runtime:v1:${endpoint}:${encodedParams}`
7586
+ );
7587
+ }
7588
+ function selectSiteRuntimeIdentity(params) {
7589
+ const slug = toNonEmptyString(params.slug);
7590
+ if (slug !== null) return { slug: normalizeScalar(slug) };
7591
+ const domain = toNonEmptyString(params.domain);
7592
+ if (domain !== null) return { domain: normalizeRuntimeHostname(domain) };
7593
+ const id = toNonEmptyString(params.id);
7594
+ if (id !== null) return { id: normalizeScalar(id) };
7595
+ return null;
7596
+ }
7597
+ function deriveGetSiteKey(params) {
7598
+ const identity = selectSiteRuntimeIdentity(params);
7599
+ if (identity === null) {
7600
+ return {
7601
+ ok: false,
7602
+ error: {
7603
+ kind: "missing_site_identity",
7604
+ acceptedParams: ["slug", "domain", "id"]
7605
+ }
7606
+ };
7607
+ }
7608
+ const normalizedParams = {
7609
+ ...identity,
7610
+ currentPath: normalizeRuntimePublicPath(params.currentPath)
7611
+ };
7612
+ return {
7613
+ ok: true,
7614
+ endpoint: "getSite",
7615
+ key: buildPublishedRuntimeCacheKey("getSite", normalizedParams),
7616
+ normalizedParams
7617
+ };
7618
+ }
7619
+ function deriveGetContentByPathKey(params) {
7620
+ const siteId = toNonEmptyString(params.siteId);
7621
+ if (siteId === null) {
7622
+ return {
7623
+ ok: false,
7624
+ error: {
7625
+ kind: "missing_required_param",
7626
+ endpoint: "getContentByPath",
7627
+ param: "siteId"
7628
+ }
7629
+ };
7630
+ }
7631
+ const normalizedParams = {
7632
+ siteId: normalizeScalar(siteId),
7633
+ path: normalizeRuntimePublicPath(params.path)
7634
+ };
7635
+ return {
7636
+ ok: true,
7637
+ endpoint: "getContentByPath",
7638
+ key: buildPublishedRuntimeCacheKey("getContentByPath", normalizedParams),
7639
+ normalizedParams
7640
+ };
7641
+ }
7642
+ var DURABLE_RUNTIME_CACHE_KEY_DERIVERS = {
7643
+ getSite: deriveGetSiteKey,
7644
+ getContentByPath: deriveGetContentByPathKey
7645
+ };
7646
+ function isPublishedRuntimeCacheKeyEndpoint(value) {
7647
+ return typeof value === "string" && Object.prototype.hasOwnProperty.call(DURABLE_RUNTIME_CACHE_KEY_DERIVERS, value);
7648
+ }
7649
+ function parsePublishedRuntimeCacheKey(value) {
7650
+ const details = parsePublishedRuntimeCacheKeyDetails(value);
7651
+ if (!details.ok) {
7652
+ return details;
7653
+ }
7654
+ return {
7655
+ ok: true,
7656
+ key: details.key,
7657
+ endpoint: details.endpoint
7658
+ };
7659
+ }
7660
+ function parsePublishedRuntimeCacheKeyDetails(value) {
7661
+ if (typeof value !== "string") {
7662
+ return { ok: false, error: "not_string" };
7663
+ }
7664
+ const parts = value.split(":");
7665
+ if (parts[0] !== "published-runtime" || parts[1] !== "v1") {
7666
+ return { ok: false, error: "invalid_prefix" };
7667
+ }
7668
+ const endpoint = parts[2];
7669
+ if (!isPublishedRuntimeCacheKeyEndpoint(endpoint)) {
7670
+ return { ok: false, error: "unknown_endpoint" };
7671
+ }
7672
+ const normalizedParams = {};
7673
+ for (const part of parts.slice(3)) {
7674
+ const separatorIndex = part.indexOf("=");
7675
+ if (separatorIndex <= 0) {
7676
+ return { ok: false, error: "invalid_param_encoding" };
7677
+ }
7678
+ try {
7679
+ const key = decodeURIComponent(part.slice(0, separatorIndex));
7680
+ const paramValue = decodeURIComponent(part.slice(separatorIndex + 1));
7681
+ normalizedParams[key] = paramValue;
7682
+ } catch {
7683
+ return { ok: false, error: "invalid_param_encoding" };
7684
+ }
7685
+ }
7686
+ if (!hasExpectedPublishedRuntimeCacheKeyParams(endpoint, normalizedParams)) {
7687
+ return { ok: false, error: "invalid_param_encoding" };
7688
+ }
7689
+ return {
7690
+ ok: true,
7691
+ key: unsafeAsPublishedRuntimeCacheKey(value),
7692
+ endpoint,
7693
+ normalizedParams
7694
+ };
7695
+ }
7696
+ function hasExpectedPublishedRuntimeCacheKeyParams(endpoint, normalizedParams) {
7697
+ const keys = Object.keys(normalizedParams).sort();
7698
+ switch (endpoint) {
7699
+ case "getSite": {
7700
+ const identityKeys = ["domain", "id", "slug"].filter(
7701
+ (key) => normalizedParams[key] !== void 0
7702
+ );
7703
+ return identityKeys.length === 1 && normalizedParams.currentPath !== void 0 && keys.every(
7704
+ (key) => ["currentPath", "domain", "id", "slug"].includes(key)
7705
+ );
7706
+ }
7707
+ case "getContentByPath":
7708
+ return normalizedParams.path !== void 0 && normalizedParams.siteId !== void 0 && keys.every((key) => ["path", "siteId"].includes(key));
7709
+ }
7710
+ }
7711
+ function parsePublishedRuntimeCachePayloadSchemaVersion(value) {
7712
+ if (typeof value !== "number") {
7713
+ return { ok: false, error: "not_number" };
7714
+ }
7715
+ if (!Number.isInteger(value)) {
7716
+ return { ok: false, error: "not_integer" };
7717
+ }
7718
+ if (value <= 0) {
7719
+ return { ok: false, error: "not_positive" };
7720
+ }
7721
+ return {
7722
+ ok: true,
7723
+ value
7724
+ };
7725
+ }
7726
+ function classifyPublishedRuntimeCacheFreshness(input) {
7727
+ const freshUntilMs = Date.parse(input.freshUntil);
7728
+ const staleUntilMs = Date.parse(input.staleUntil);
7729
+ if (Number.isNaN(freshUntilMs)) {
7730
+ return { kind: "invalid_timestamp", field: "freshUntil" };
7731
+ }
7732
+ if (Number.isNaN(staleUntilMs)) {
7733
+ return { kind: "invalid_timestamp", field: "staleUntil" };
7734
+ }
7735
+ const nowMs = input.now.getTime();
7736
+ if (nowMs > staleUntilMs) {
7737
+ return { kind: "expired" };
7738
+ }
7739
+ if (nowMs <= freshUntilMs) {
7740
+ return { kind: "fresh", staleAgeSec: 0 };
7741
+ }
7742
+ return {
7743
+ kind: "stale",
7744
+ staleAgeSec: Math.floor((nowMs - freshUntilMs) / 1e3)
7745
+ };
7746
+ }
7747
+ function derivePublishedRuntimeCacheKey(input) {
7748
+ const policy = resolveRuntimeCachePolicy({
7749
+ endpoint: input.endpoint,
7750
+ method: "GET",
7751
+ params: input.params
7752
+ });
7753
+ if (policy.kind !== "durable-public-stale") {
7754
+ return {
7755
+ ok: false,
7756
+ error: { kind: "not_durable_eligible", policy }
7757
+ };
7758
+ }
7759
+ switch (input.endpoint) {
7760
+ case "getSite":
7761
+ return DURABLE_RUNTIME_CACHE_KEY_DERIVERS.getSite(input.params);
7762
+ case "getContentByPath":
7763
+ return DURABLE_RUNTIME_CACHE_KEY_DERIVERS.getContentByPath(input.params);
7764
+ }
7765
+ }
7766
+
7767
+ // src/client/resilience.ts
7768
+ var DEFAULT_RETRY_CONFIG = {
7769
+ maxAttempts: 3,
7770
+ baseDelayMs: 200,
7771
+ maxDelayMs: 2e3,
7772
+ jitter: "full"
7773
+ };
7774
+ var DEFAULT_CIRCUIT_BREAKER_CONFIG = {
7775
+ failureThreshold: 5,
7776
+ resetTimeoutMs: 3e4,
7777
+ halfOpenMaxRequests: 2
7778
+ };
7779
+ var PERMANENT_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
7780
+ "ECONNREFUSED",
7781
+ // Server is not running / port not listening
7782
+ "ENOTFOUND",
7783
+ // DNS lookup failed - hostname doesn't exist
7784
+ "EAI_AGAIN"
7785
+ // DNS lookup timeout (usually permanent for invalid hosts)
7786
+ ]);
7787
+ var TRANSIENT_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
7788
+ "ECONNRESET",
7789
+ // Connection was reset mid-request (server dropped it)
7790
+ "EPIPE",
7791
+ // Broken pipe (connection closed while writing)
7792
+ "ETIMEDOUT",
7793
+ // Connection timed out (could be temporary congestion)
7794
+ "ESOCKETTIMEDOUT"
7795
+ // Socket timeout
7796
+ ]);
7797
+ var NODE_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
7798
+ // Permanent
7799
+ "ECONNREFUSED",
7800
+ "ENOTFOUND",
7801
+ "EAI_AGAIN",
7802
+ // Transient
7803
+ "ECONNRESET",
7804
+ "EPIPE",
7805
+ "ETIMEDOUT",
7806
+ "ESOCKETTIMEDOUT"
7807
+ ]);
7808
+ function isNodeNetworkErrorCode(code) {
7809
+ return !code.includes(":") && NODE_NETWORK_ERROR_CODES.has(code);
7810
+ }
7811
+ function getErrorCodeFromCause(error) {
7812
+ let current = error;
7813
+ while (current) {
7814
+ const nodeError = current;
7815
+ if (nodeError.code && typeof nodeError.code === "string") {
7816
+ if (isNodeNetworkErrorCode(nodeError.code)) {
7817
+ return nodeError.code;
7818
+ }
7819
+ }
7820
+ const errorWithCause = current;
7821
+ current = errorWithCause.cause;
7822
+ }
7823
+ return void 0;
7824
+ }
7825
+ function isTransientError(error) {
7826
+ if (error instanceof RiverbankApiError) {
7827
+ const errorCode = getErrorCodeFromCause(error);
7828
+ if (errorCode && PERMANENT_NETWORK_ERROR_CODES.has(errorCode)) {
7829
+ return false;
7830
+ }
7831
+ if (error.status === 0) return true;
7832
+ if (error.status === 429) return true;
7833
+ if (error.status >= 500) return true;
7834
+ return false;
7835
+ }
7836
+ if (error instanceof TypeError) {
7837
+ const errorCode = getErrorCodeFromCause(error);
7838
+ if (errorCode) {
7839
+ if (PERMANENT_NETWORK_ERROR_CODES.has(errorCode)) {
7840
+ return false;
7841
+ }
7842
+ if (TRANSIENT_NETWORK_ERROR_CODES.has(errorCode)) {
7843
+ return true;
7844
+ }
7845
+ }
7846
+ return true;
7847
+ }
7848
+ return true;
7849
+ }
7850
+ function calculateBackoff(attempt, config) {
7851
+ const baseDelayMs = config.baseDelayMs ?? DEFAULT_RETRY_CONFIG.baseDelayMs;
7852
+ const maxDelayMs = config.maxDelayMs ?? DEFAULT_RETRY_CONFIG.maxDelayMs;
7853
+ const jitter = config.jitter ?? DEFAULT_RETRY_CONFIG.jitter;
7854
+ const exponential = baseDelayMs * Math.pow(2, attempt - 1);
7855
+ const capped = Math.min(exponential, maxDelayMs);
7856
+ if (jitter === "full") {
7857
+ return Math.random() * capped;
7858
+ }
7859
+ return capped;
7860
+ }
7861
+ var CircuitBreaker = class {
7862
+ constructor(config) {
7863
+ this.state = "closed";
7864
+ this.failureCount = 0;
7865
+ this.successCount = 0;
7866
+ this.openUntil = 0;
7867
+ this.halfOpenRequests = 0;
7868
+ this.config = {
7869
+ failureThreshold: config?.failureThreshold ?? DEFAULT_CIRCUIT_BREAKER_CONFIG.failureThreshold,
7870
+ resetTimeoutMs: config?.resetTimeoutMs ?? DEFAULT_CIRCUIT_BREAKER_CONFIG.resetTimeoutMs,
7871
+ halfOpenMaxRequests: config?.halfOpenMaxRequests ?? DEFAULT_CIRCUIT_BREAKER_CONFIG.halfOpenMaxRequests
7872
+ };
7873
+ }
7874
+ /**
7875
+ * Check if circuit is open (requests should be blocked)
7876
+ * Also handles automatic transition from open to half-open after timeout
7877
+ */
7878
+ isOpen() {
7879
+ if (this.state === "open" && Date.now() >= this.openUntil) {
7880
+ this.transitionTo("half-open");
7881
+ }
7882
+ return this.state === "open";
7883
+ }
7884
+ /**
7885
+ * Check if a request can be attempted
7886
+ * - closed: always yes
7887
+ * - open: always no
7888
+ * - half-open: limited number of probes
7889
+ */
7890
+ canAttempt() {
7891
+ if (this.state === "closed") return true;
7892
+ if (this.state === "open") return false;
7893
+ return this.halfOpenRequests < this.config.halfOpenMaxRequests;
7894
+ }
7895
+ /**
7896
+ * Increment half-open request counter (call before making request in half-open)
7897
+ */
7898
+ incrementHalfOpenRequests() {
7899
+ if (this.state === "half-open") {
7900
+ this.halfOpenRequests++;
7901
+ }
7902
+ }
7903
+ /**
7904
+ * Record a successful request
7905
+ */
7906
+ recordSuccess() {
7907
+ if (this.state === "half-open") {
7908
+ this.successCount++;
7909
+ if (this.successCount >= this.config.halfOpenMaxRequests) {
7910
+ this.transitionTo("closed");
7911
+ }
7912
+ } else {
7913
+ this.failureCount = 0;
7914
+ }
7915
+ }
7916
+ /**
7917
+ * Record a failed request
7918
+ * Only counts transient failures toward circuit breaker threshold
7919
+ */
7920
+ recordFailure(error) {
7921
+ if (!isTransientError(error)) return;
7922
+ this.failureCount++;
7923
+ if (this.state === "half-open") {
7924
+ this.transitionTo("open");
7925
+ } else if (this.failureCount >= this.config.failureThreshold) {
7926
+ this.transitionTo("open");
7927
+ }
7928
+ }
7929
+ /**
7930
+ * Get current circuit state
7931
+ */
7932
+ getState() {
7933
+ return {
7934
+ state: this.state,
7935
+ failureCount: this.failureCount,
7936
+ openUntil: this.state === "open" ? this.openUntil : void 0
7937
+ };
7938
+ }
7939
+ /**
7940
+ * Transition to a new state
7941
+ */
7942
+ transitionTo(newState) {
7943
+ this.state = newState;
7944
+ if (newState === "open") {
7945
+ this.openUntil = Date.now() + this.config.resetTimeoutMs;
7946
+ } else if (newState === "half-open") {
7947
+ this.halfOpenRequests = 0;
7948
+ this.successCount = 0;
7949
+ } else if (newState === "closed") {
7950
+ this.failureCount = 0;
7951
+ this.successCount = 0;
7952
+ this.halfOpenRequests = 0;
7953
+ }
7954
+ }
7955
+ };
7956
+ async function fetchWithTimeoutAndRetry(fetcher, config) {
7957
+ const maxAttempts = config.maxAttempts ?? DEFAULT_RETRY_CONFIG.maxAttempts;
7958
+ const requestTimeoutMs = config.requestTimeoutMs ?? 8e3;
7959
+ let lastError;
7960
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
7961
+ try {
7326
7962
  const controller = new AbortController();
7327
7963
  const timeoutId = setTimeout(() => controller.abort(), requestTimeoutMs);
7328
7964
  try {
@@ -7437,12 +8073,57 @@ setSdkVersion(SDK_VERSION);
7437
8073
  var DEFAULT_BROWSER_TIMEOUT_MS = 5e3;
7438
8074
  var DEFAULT_SERVER_TIMEOUT_MS = 8e3;
7439
8075
  var MAX_GET_ENTRIES_BY_IDENTIFIERS_REFS = 50;
8076
+ function isDurableRuntimeCacheTier(cacheTier) {
8077
+ return cacheTier === "durable-fresh" || cacheTier === "durable-stale";
8078
+ }
8079
+ function isDegradedResilienceStatus(source, details) {
8080
+ return source === "stale" || source === "error" || isDurableRuntimeCacheTier(details.cacheTier) && details.error !== void 0;
8081
+ }
7440
8082
  function generateRequestId2() {
7441
8083
  return `req-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
7442
8084
  }
7443
8085
  function toRecord(value) {
7444
8086
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
7445
8087
  }
8088
+ function getRuntimePayloadSiteId(value) {
8089
+ const site = toRecord(value).site;
8090
+ if (!site || typeof site !== "object" || Array.isArray(site)) {
8091
+ return null;
8092
+ }
8093
+ const id = site.id;
8094
+ return typeof id === "string" && id.trim().length > 0 ? id : null;
8095
+ }
8096
+ function getRiverbankErrorInfo(error) {
8097
+ if (error instanceof RiverbankApiError) {
8098
+ return { code: error.code, message: error.message, status: error.status };
8099
+ }
8100
+ if (error instanceof Error) {
8101
+ return { message: error.message };
8102
+ }
8103
+ return { message: String(error) };
8104
+ }
8105
+ function planPublishedRuntimeCache(input) {
8106
+ const policy = resolveRuntimeCachePolicy({
8107
+ endpoint: input.endpoint,
8108
+ method: "GET",
8109
+ params: input.params
8110
+ });
8111
+ if (policy.kind !== "durable-public-stale") {
8112
+ return null;
8113
+ }
8114
+ const keyResult = derivePublishedRuntimeCacheKey(input);
8115
+ if (!keyResult.ok) {
8116
+ return null;
8117
+ }
8118
+ return {
8119
+ cacheKey: keyResult.key,
8120
+ endpoint: keyResult.endpoint,
8121
+ normalizedParams: keyResult.normalizedParams,
8122
+ freshTtlSec: policy.freshTtlSec,
8123
+ staleTtlSec: policy.staleTtlSec,
8124
+ siteId: input.siteId ?? null
8125
+ };
8126
+ }
7446
8127
  function normalizeEntryIdentifierRefs(identifiers) {
7447
8128
  const trimmed = identifiers.map((identifier) => identifier.trim()).filter((identifier) => identifier.length > 0);
7448
8129
  if (trimmed.length === 0) {
@@ -7676,6 +8357,8 @@ function createRiverbankClient(config) {
7676
8357
  source,
7677
8358
  isPreview: details.isPreview,
7678
8359
  cacheKey: details.cacheKey,
8360
+ cacheTier: details.cacheTier,
8361
+ durableCache: details.durableCache,
7679
8362
  error: details.error,
7680
8363
  staleAgeSec: details.staleAgeSec,
7681
8364
  prebuildAgeSec: details.prebuildAgeSec,
@@ -7685,7 +8368,7 @@ function createRiverbankClient(config) {
7685
8368
  };
7686
8369
  lastStatus = status;
7687
8370
  config.resilience?.onStatusChange?.(status);
7688
- const nowDegraded = source === "stale" || source === "error";
8371
+ const nowDegraded = isDegradedResilienceStatus(source, details);
7689
8372
  if (nowDegraded !== isDegraded) {
7690
8373
  isDegraded = nowDegraded;
7691
8374
  config.resilience?.onDegradedMode?.(nowDegraded, status);
@@ -7695,6 +8378,80 @@ function createRiverbankClient(config) {
7695
8378
  resilience: status
7696
8379
  };
7697
8380
  }
8381
+ async function tryPublishedRuntimeCacheFallback(plan, statusDetails, errorInfo) {
8382
+ const reader = config.publishedRuntimeCache?.read;
8383
+ if (!plan || !reader) {
8384
+ return null;
8385
+ }
8386
+ try {
8387
+ const result = await reader({
8388
+ cacheKey: plan.cacheKey,
8389
+ endpoint: plan.endpoint,
8390
+ payloadSchemaVersion: DEFAULT_PUBLISHED_RUNTIME_CACHE_PAYLOAD_SCHEMA_VERSION
8391
+ });
8392
+ if (result.kind === "miss") {
8393
+ return {
8394
+ kind: "miss",
8395
+ diagnostic: {
8396
+ outcome: "miss",
8397
+ reason: result.reason
8398
+ }
8399
+ };
8400
+ }
8401
+ if (result.kind === "error") {
8402
+ return {
8403
+ kind: "error",
8404
+ diagnostic: {
8405
+ outcome: "error",
8406
+ error: result.error
8407
+ }
8408
+ };
8409
+ }
8410
+ return {
8411
+ kind: "hit",
8412
+ result: emitStatus(
8413
+ result.freshness === "fresh" ? "cache" : "stale",
8414
+ result.payload,
8415
+ statusDetails({
8416
+ error: errorInfo,
8417
+ staleAgeSec: result.staleAgeSec,
8418
+ cacheTier: result.freshness === "fresh" ? "durable-fresh" : "durable-stale"
8419
+ })
8420
+ )
8421
+ };
8422
+ } catch (error) {
8423
+ return {
8424
+ kind: "error",
8425
+ diagnostic: {
8426
+ outcome: "error",
8427
+ error: {
8428
+ kind: "adapter_exception",
8429
+ message: error instanceof Error ? error.message : String(error)
8430
+ }
8431
+ }
8432
+ };
8433
+ }
8434
+ }
8435
+ async function writePublishedRuntimeCache(plan, payload) {
8436
+ const writer = config.publishedRuntimeCache?.write;
8437
+ if (!plan || !writer) {
8438
+ return;
8439
+ }
8440
+ try {
8441
+ await writer({
8442
+ cacheKey: plan.cacheKey,
8443
+ endpoint: plan.endpoint,
8444
+ normalizedParams: plan.normalizedParams,
8445
+ payload,
8446
+ siteId: plan.siteId ?? getRuntimePayloadSiteId(payload),
8447
+ freshTtlSec: plan.freshTtlSec,
8448
+ staleTtlSec: plan.staleTtlSec,
8449
+ payloadSchemaVersion: DEFAULT_PUBLISHED_RUNTIME_CACHE_PAYLOAD_SCHEMA_VERSION,
8450
+ writeReason: "live_success"
8451
+ });
8452
+ } catch {
8453
+ }
8454
+ }
7698
8455
  async function resilientFetch(cacheKey, fetcher, options) {
7699
8456
  const requestId = generateRequestId2();
7700
8457
  const startTime = Date.now();
@@ -7710,7 +8467,11 @@ function createRiverbankClient(config) {
7710
8467
  if (cacheEnabled && !options.force) {
7711
8468
  const fresh = cache.getFresh(cacheKey);
7712
8469
  if (fresh !== null) {
7713
- return emitStatus("cache", fresh, statusDetails());
8470
+ return emitStatus(
8471
+ "cache",
8472
+ fresh,
8473
+ statusDetails({ cacheTier: "memory-fresh" })
8474
+ );
7714
8475
  }
7715
8476
  }
7716
8477
  if (resilienceEnabled && circuitBreaker.isOpen()) {
@@ -7722,6 +8483,7 @@ function createRiverbankClient(config) {
7722
8483
  stale.value,
7723
8484
  statusDetails({
7724
8485
  staleAgeSec: stale.staleAgeSec,
8486
+ cacheTier: "memory-stale",
7725
8487
  error: {
7726
8488
  code: "circuit_open",
7727
8489
  message: "Circuit breaker is open"
@@ -7730,6 +8492,15 @@ function createRiverbankClient(config) {
7730
8492
  );
7731
8493
  }
7732
8494
  }
8495
+ const durableFallback = allowFallbacks && !isPreview ? await tryPublishedRuntimeCacheFallback(
8496
+ options.publishedRuntimeCache,
8497
+ statusDetails,
8498
+ { code: "circuit_open", message: "Circuit breaker is open" }
8499
+ ) : null;
8500
+ const durableCache = durableFallback?.kind === "miss" || durableFallback?.kind === "error" ? durableFallback.diagnostic : void 0;
8501
+ if (durableFallback?.kind === "hit") {
8502
+ return durableFallback.result;
8503
+ }
7733
8504
  if (allowFallbacks && !isPreview && options.prebuildFallback) {
7734
8505
  const prebuildResult = options.prebuildFallback();
7735
8506
  if (prebuildResult) {
@@ -7738,6 +8509,8 @@ function createRiverbankClient(config) {
7738
8509
  prebuildResult.data,
7739
8510
  statusDetails({
7740
8511
  prebuildAgeSec: prebuildResult.prebuildAgeSec,
8512
+ cacheTier: "prebuild",
8513
+ durableCache,
7741
8514
  error: {
7742
8515
  code: "circuit_open",
7743
8516
  message: "Circuit breaker is open"
@@ -7751,6 +8524,7 @@ function createRiverbankClient(config) {
7751
8524
  "error",
7752
8525
  null,
7753
8526
  statusDetails({
8527
+ durableCache,
7754
8528
  error: { code: "circuit_open", message: "Circuit breaker is open" }
7755
8529
  })
7756
8530
  );
@@ -7791,6 +8565,9 @@ function createRiverbankClient(config) {
7791
8565
  if (cacheEnabled) {
7792
8566
  cache.set(cacheKey, data);
7793
8567
  }
8568
+ if (allowFallbacks && !isPreview) {
8569
+ await writePublishedRuntimeCache(options.publishedRuntimeCache, data);
8570
+ }
7794
8571
  return emitStatus("live", data, statusDetails());
7795
8572
  } catch (error) {
7796
8573
  if (resilienceEnabled && error instanceof Error) {
@@ -7799,44 +8576,47 @@ function createRiverbankClient(config) {
7799
8576
  if (allowFallbacks && !isPreview && staleIfError && cacheEnabled) {
7800
8577
  const stale = cache.getStale(cacheKey);
7801
8578
  if (stale) {
7802
- const errorInfo2 = error instanceof RiverbankApiError ? {
7803
- code: error.code,
7804
- message: error.message,
7805
- status: error.status
7806
- } : { message: error.message };
8579
+ const errorInfo2 = getRiverbankErrorInfo(error);
7807
8580
  return emitStatus(
7808
8581
  "stale",
7809
8582
  stale.value,
7810
8583
  statusDetails({
7811
8584
  staleAgeSec: stale.staleAgeSec,
8585
+ cacheTier: "memory-stale",
7812
8586
  error: errorInfo2
7813
8587
  })
7814
8588
  );
7815
8589
  }
7816
8590
  }
8591
+ const errorInfo = getRiverbankErrorInfo(error);
8592
+ const durableFallback = allowFallbacks && !isPreview ? await tryPublishedRuntimeCacheFallback(
8593
+ options.publishedRuntimeCache,
8594
+ statusDetails,
8595
+ errorInfo
8596
+ ) : null;
8597
+ const durableCache = durableFallback?.kind === "miss" || durableFallback?.kind === "error" ? durableFallback.diagnostic : void 0;
8598
+ if (durableFallback?.kind === "hit") {
8599
+ return durableFallback.result;
8600
+ }
7817
8601
  if (allowFallbacks && !isPreview && options.prebuildFallback) {
7818
8602
  const prebuildResult = options.prebuildFallback();
7819
8603
  if (prebuildResult) {
7820
- const errorInfo2 = error instanceof RiverbankApiError ? {
7821
- code: error.code,
7822
- message: error.message,
7823
- status: error.status
7824
- } : { message: error.message };
7825
8604
  return emitStatus(
7826
8605
  "prebuild",
7827
8606
  prebuildResult.data,
7828
8607
  statusDetails({
7829
8608
  prebuildAgeSec: prebuildResult.prebuildAgeSec,
7830
- error: errorInfo2
8609
+ cacheTier: "prebuild",
8610
+ durableCache,
8611
+ error: errorInfo
7831
8612
  })
7832
8613
  );
7833
8614
  }
7834
8615
  }
7835
- const errorInfo = error instanceof RiverbankApiError ? { code: error.code, message: error.message, status: error.status } : { message: error.message };
7836
8616
  const failure = emitStatus(
7837
8617
  "error",
7838
8618
  null,
7839
- statusDetails({ error: errorInfo })
8619
+ statusDetails({ error: errorInfo, durableCache })
7840
8620
  );
7841
8621
  throw attachResilienceStatusToError(error, failure.resilience);
7842
8622
  }
@@ -7886,8 +8666,12 @@ function createRiverbankClient(config) {
7886
8666
  );
7887
8667
  }
7888
8668
  const siteIdentifier = slug || domain || id;
7889
- const cacheKey = `site:${siteIdentifier ?? "unknown"}:${currentPath ?? ""}`;
7890
8669
  const siteId = id || slug || domain;
8670
+ const publishedRuntimeCache = planPublishedRuntimeCache({
8671
+ endpoint: "getSite",
8672
+ params: { slug, domain, id, currentPath, force }
8673
+ });
8674
+ const cacheKey = publishedRuntimeCache?.cacheKey ?? `site:${siteIdentifier ?? "unknown"}:${currentPath ?? ""}`;
7891
8675
  return resilientFetch(
7892
8676
  cacheKey,
7893
8677
  async (sig) => {
@@ -7910,13 +8694,19 @@ function createRiverbankClient(config) {
7910
8694
  {
7911
8695
  signal,
7912
8696
  force,
8697
+ publishedRuntimeCache,
7913
8698
  prebuildFallback: prebuildLoader && siteId ? () => prebuildLoader.loadSite(siteId) : void 0
7914
8699
  }
7915
8700
  );
7916
8701
  }
7917
8702
  async function getPageWithResilienceInternal(params) {
7918
8703
  const { siteId, path: path3, preview = false, signal } = params;
7919
- const cacheKey = `page:${siteId}:${path3}:${preview}`;
8704
+ const publishedRuntimeCache = planPublishedRuntimeCache({
8705
+ endpoint: "getContentByPath",
8706
+ params: { siteId, path: path3, preview },
8707
+ siteId
8708
+ });
8709
+ const cacheKey = publishedRuntimeCache?.cacheKey ?? `page:${siteId}:${path3}:${preview}`;
7920
8710
  return resilientFetch(
7921
8711
  cacheKey,
7922
8712
  async (sig) => {
@@ -7929,6 +8719,7 @@ function createRiverbankClient(config) {
7929
8719
  {
7930
8720
  preview,
7931
8721
  signal,
8722
+ publishedRuntimeCache,
7932
8723
  // Prebuild fallback only for published pages (not preview)
7933
8724
  prebuildFallback: prebuildLoader && !preview ? () => prebuildLoader.loadPage(siteId, path3) : void 0
7934
8725
  }
@@ -8125,10 +8916,16 @@ function createRiverbankClient(config) {
8125
8916
  limit,
8126
8917
  from,
8127
8918
  to,
8919
+ afterStartsAt,
8920
+ afterId,
8128
8921
  stage,
8129
8922
  categoryIds,
8130
8923
  venueId,
8924
+ staffMemberId,
8131
8925
  kind,
8926
+ eventSurface,
8927
+ eventPresets,
8928
+ scheduleScope,
8132
8929
  entryId,
8133
8930
  seriesId,
8134
8931
  includeOccurrenceId,
@@ -8137,7 +8934,7 @@ function createRiverbankClient(config) {
8137
8934
  if (!siteId) {
8138
8935
  throw new Error("listPublicEvents() requires siteId");
8139
8936
  }
8140
- const cacheKey = `public-events:${siteId}:${limit ?? ""}:${from ?? ""}:${to ?? ""}:${stage ?? ""}:${categoryIds ?? ""}:${venueId ?? ""}:${kind ?? ""}:${entryId ?? ""}:${seriesId ?? ""}:${includeOccurrenceId ?? ""}`;
8937
+ const cacheKey = `public-events:${siteId}:${limit ?? ""}:${from ?? ""}:${to ?? ""}:${afterStartsAt ?? ""}:${afterId ?? ""}:${stage ?? ""}:${categoryIds ?? ""}:${venueId ?? ""}:${staffMemberId ?? ""}:${kind ?? ""}:${eventSurface ?? ""}:${eventPresets ?? ""}:${scheduleScope ?? ""}:${entryId ?? ""}:${seriesId ?? ""}:${includeOccurrenceId ?? ""}`;
8141
8938
  return resilientFetchData(
8142
8939
  cacheKey,
8143
8940
  async (sig) => {
@@ -8146,10 +8943,16 @@ function createRiverbankClient(config) {
8146
8943
  ...typeof limit === "number" && { limit: String(limit) },
8147
8944
  ...from && { from },
8148
8945
  ...to && { to },
8946
+ ...afterStartsAt && { afterStartsAt },
8947
+ ...afterId && { afterId },
8149
8948
  ...stage && { stage },
8150
8949
  ...categoryIds && { categoryIds },
8151
8950
  ...venueId && { venueId },
8951
+ ...staffMemberId && { staffMemberId },
8152
8952
  ...kind && { kind },
8953
+ ...eventSurface && { eventSurface },
8954
+ ...eventPresets && { eventPresets },
8955
+ ...scheduleScope && { scheduleScope },
8153
8956
  ...entryId && { entryId },
8154
8957
  ...seriesId && { seriesId },
8155
8958
  ...includeOccurrenceId && { includeOccurrenceId }
@@ -8176,6 +8979,9 @@ function createRiverbankClient(config) {
8176
8979
  venueId,
8177
8980
  staffMemberId,
8178
8981
  kind,
8982
+ eventSurface,
8983
+ eventPresets,
8984
+ scheduleScope,
8179
8985
  entryId,
8180
8986
  seriesId,
8181
8987
  includeOccurrenceId,
@@ -8184,7 +8990,7 @@ function createRiverbankClient(config) {
8184
8990
  if (!siteId) {
8185
8991
  throw new Error("getPublicEventDetails() requires siteId");
8186
8992
  }
8187
- const cacheKey = `public-event-details:${siteId}:${limit ?? ""}:${from ?? ""}:${to ?? ""}:${afterStartsAt ?? ""}:${afterId ?? ""}:${stage ?? ""}:${categoryIds ?? ""}:${venueId ?? ""}:${staffMemberId ?? ""}:${kind ?? ""}:${entryId ?? ""}:${seriesId ?? ""}:${includeOccurrenceId ?? ""}`;
8993
+ const cacheKey = `public-event-details:${siteId}:${limit ?? ""}:${from ?? ""}:${to ?? ""}:${afterStartsAt ?? ""}:${afterId ?? ""}:${stage ?? ""}:${categoryIds ?? ""}:${venueId ?? ""}:${staffMemberId ?? ""}:${kind ?? ""}:${eventSurface ?? ""}:${eventPresets ?? ""}:${scheduleScope ?? ""}:${entryId ?? ""}:${seriesId ?? ""}:${includeOccurrenceId ?? ""}`;
8188
8994
  return resilientFetchData(
8189
8995
  cacheKey,
8190
8996
  async (sig) => {
@@ -8207,6 +9013,9 @@ function createRiverbankClient(config) {
8207
9013
  ...venueId && { venueId },
8208
9014
  ...staffMemberId && { staffMemberId },
8209
9015
  ...kind && { kind },
9016
+ ...eventSurface && { eventSurface },
9017
+ ...eventPresets && { eventPresets },
9018
+ ...scheduleScope && { scheduleScope },
8210
9019
  ...entryId && { entryId },
8211
9020
  ...seriesId && { seriesId },
8212
9021
  ...includeOccurrenceId && { includeOccurrenceId }
@@ -9044,176 +9853,6 @@ function createPrebuildLoader(config) {
9044
9853
  return new PrebuildLoader(config);
9045
9854
  }
9046
9855
 
9047
- // src/public-api/runtime.ts
9048
- var API_ENDPOINTS2 = Object.freeze({
9049
- getSite: {
9050
- path: "/sites",
9051
- method: "GET",
9052
- revalidate: 900,
9053
- tags: ["riverbank:site", "riverbank:site:id:{id}", "riverbank:site:slug:{slug}", "riverbank:site:domain:{domain}"],
9054
- auth: "public",
9055
- responseKind: "json"
9056
- },
9057
- getContentByPath: {
9058
- path: "/sites/{siteId}/pages",
9059
- method: "GET",
9060
- tags: ["riverbank:site:{siteId}:routable-content"],
9061
- auth: "public",
9062
- responseKind: "json"
9063
- },
9064
- listPublishedEntries: {
9065
- path: "/public/content/{siteId}/{type}/entries",
9066
- method: "GET",
9067
- revalidate: 60,
9068
- tags: ["content-{siteId}-{type}"],
9069
- auth: "public",
9070
- responseKind: "json"
9071
- },
9072
- getPublishedEntryPreview: {
9073
- path: "/public/content/{siteId}/{type}/{slug}/preview",
9074
- method: "GET",
9075
- revalidate: 60,
9076
- tags: ["content-{siteId}-{type}-{slug}"],
9077
- auth: "public",
9078
- responseKind: "json"
9079
- },
9080
- getPublicFormById: {
9081
- path: "/public/forms/{formId}",
9082
- method: "GET",
9083
- revalidate: 60,
9084
- tags: ["riverbank:form:{formId}"],
9085
- auth: "public",
9086
- responseKind: "json"
9087
- },
9088
- listPublicForms: {
9089
- path: "/public/sites/{siteId}/forms",
9090
- method: "GET",
9091
- revalidate: 60,
9092
- tags: ["riverbank:site:{siteId}:forms"],
9093
- auth: "public",
9094
- responseKind: "json"
9095
- },
9096
- getPublicBookingServices: {
9097
- path: "/public/bookings/services",
9098
- method: "GET",
9099
- revalidate: 60,
9100
- tags: ["site-{siteId}"],
9101
- auth: "public",
9102
- responseKind: "json"
9103
- },
9104
- getPublicChallenge: {
9105
- path: "/public/challenge",
9106
- method: "GET",
9107
- auth: "public",
9108
- responseKind: "text"
9109
- },
9110
- listPublicEvents: {
9111
- path: "/public/sites/{siteId}/events",
9112
- method: "GET",
9113
- revalidate: 60,
9114
- tags: ["riverbank:site:{siteId}:public-events"],
9115
- auth: "public",
9116
- responseKind: "json"
9117
- },
9118
- batchBlockLoaders: {
9119
- path: "/public/sites/{siteId}/block-loaders/batch",
9120
- method: "POST",
9121
- auth: "public",
9122
- responseKind: "json"
9123
- },
9124
- listPublicCourses: {
9125
- path: "/public/sites/{siteId}/courses",
9126
- method: "GET",
9127
- revalidate: 60,
9128
- tags: ["riverbank:site:{siteId}:public-courses"],
9129
- auth: "public",
9130
- responseKind: "json"
9131
- },
9132
- listPublicTeamMembers: {
9133
- path: "/public/sites/{siteId}/team-members",
9134
- method: "GET",
9135
- revalidate: 60,
9136
- tags: ["riverbank:site:{siteId}:public-team-members"],
9137
- auth: "public",
9138
- responseKind: "json"
9139
- },
9140
- listPublicProducts: {
9141
- path: "/public/sites/{siteId}/products",
9142
- method: "GET",
9143
- revalidate: 300,
9144
- tags: ["riverbank:site:{siteId}:public-products"],
9145
- auth: "public",
9146
- responseKind: "json"
9147
- },
9148
- listPublicPasses: {
9149
- path: "/public/sites/{siteId}/bookings/products/passes",
9150
- method: "GET",
9151
- revalidate: 300,
9152
- tags: ["riverbank:site:{siteId}:public-passes"],
9153
- auth: "public",
9154
- responseKind: "json"
9155
- },
9156
- listPublicMemberships: {
9157
- path: "/public/sites/{siteId}/bookings/products/memberships",
9158
- method: "GET",
9159
- revalidate: 300,
9160
- tags: ["riverbank:site:{siteId}:public-memberships"],
9161
- auth: "public",
9162
- responseKind: "json"
9163
- },
9164
- resolveEntrySubroute: {
9165
- path: "/public/sites/{siteId}/routing/subroutes/resolve",
9166
- method: "GET",
9167
- revalidate: 60,
9168
- tags: ["site-{siteId}", "entry-subroute"],
9169
- auth: "public",
9170
- responseKind: "json"
9171
- },
9172
- resolveEventOccurrence: {
9173
- path: "/public/sites/{siteId}/events/occurrences/resolve",
9174
- method: "GET",
9175
- revalidate: 60,
9176
- tags: ["riverbank:site:{siteId}:public-events", "event-occurrence"],
9177
- auth: "public",
9178
- responseKind: "json"
9179
- },
9180
- checkRedirect: {
9181
- path: "/public/content/redirect",
9182
- method: "GET",
9183
- revalidate: 86400,
9184
- tags: ["redirect"],
9185
- auth: "public",
9186
- responseKind: "json"
9187
- },
9188
- getRoutableContent: {
9189
- path: "/sites/{siteId}/routable-content",
9190
- method: "GET",
9191
- revalidate: 60,
9192
- tags: ["riverbank:site:{siteId}:routable-content"],
9193
- auth: "user",
9194
- responseKind: "json"
9195
- },
9196
- getPublicRoutableContent: {
9197
- path: "/public/sites/{siteId}/routable-content",
9198
- method: "GET",
9199
- revalidate: 60,
9200
- tags: ["riverbank:site:{siteId}:routable-content"],
9201
- auth: "public",
9202
- responseKind: "json"
9203
- },
9204
- getPublicSitemapRoutes: {
9205
- path: "/public/sites/{siteId}/sitemap",
9206
- method: "GET",
9207
- revalidate: 60,
9208
- tags: ["riverbank:site:{siteId}:routable-content", "riverbank:site:{siteId}:settings"],
9209
- auth: "public",
9210
- responseKind: "json"
9211
- }
9212
- });
9213
- function buildEndpointURL2(baseURL, endpoint) {
9214
- return baseURL + API_ENDPOINTS2[endpoint].path;
9215
- }
9216
-
9217
9856
  // src/types/block-kinds.ts
9218
9857
  var SYSTEM_BLOCK_KINDS = [
9219
9858
  // Layout blocks
@@ -9267,14 +9906,23 @@ var SYSTEM_BLOCK_KINDS = [
9267
9906
  ];
9268
9907
  export {
9269
9908
  API_ENDPOINTS2 as API_ENDPOINTS,
9909
+ DEFAULT_PUBLISHED_RUNTIME_CACHE_PAYLOAD_SCHEMA_VERSION,
9270
9910
  PrebuildLoader,
9271
9911
  RiverbankApiError,
9272
9912
  SDK_CORRELATION_HEADER_NAMES,
9273
9913
  SYSTEM_BLOCK_KINDS,
9274
9914
  buildEndpointURL2 as buildEndpointURL,
9275
9915
  canUsePrebuild,
9916
+ classifyPublishedRuntimeCacheFreshness,
9276
9917
  createPrebuildLoader,
9277
9918
  createRiverbankClient,
9919
+ derivePublishedRuntimeCacheKey,
9278
9920
  getResilienceStatusFromError,
9279
- prebuildCache
9921
+ isPublishedRuntimeCacheKeyEndpoint,
9922
+ normalizeRuntimePublicPath,
9923
+ parsePublishedRuntimeCacheKey,
9924
+ parsePublishedRuntimeCacheKeyDetails,
9925
+ parsePublishedRuntimeCachePayloadSchemaVersion,
9926
+ prebuildCache,
9927
+ resolveRuntimeCachePolicy
9280
9928
  };