@burdenoff/fe-libs 2026.813.1 → 2026.813.3

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.
@@ -2,13 +2,13 @@ import { createBrowserTraceContext as e } from "./shared/events/metadata.js";
2
2
  import { DevtoolsSink as t } from "./shared/events/sinks/DevtoolsSink.js";
3
3
  import { BroadcastChannelSink as n } from "./shared/events/sinks/BroadcastChannelSink.js";
4
4
  import { BackendAuditSink as r } from "./shared/events/sinks/BackendAuditSink.js";
5
- import { RybbitSink as i } from "./shared/events/sinks/RybbitSink.js";
6
- import { OtelBrowserSink as a } from "./shared/events/sinks/OtelBrowserSink.js";
5
+ import { AnalyticsConsentBanner as i, RybbitSink as a, readAnalyticsConsent as o, setAnalyticsConsent as s } from "./shared/events/sinks/RybbitSink.js";
6
+ import { OtelBrowserSink as c } from "./shared/events/sinks/OtelBrowserSink.js";
7
7
  import "./shared/events/sinks/index.js";
8
- import { createContext as o, use as s, useCallback as c, useEffect as l, useMemo as u } from "react";
9
- import { jsx as d } from "react/jsx-runtime";
8
+ import { createContext as l, use as u, useCallback as d, useEffect as f, useMemo as p } from "react";
9
+ import { jsx as m } from "react/jsx-runtime";
10
10
  //#region src/shared/events/index.tsx
11
- var f = o({
11
+ var h = l({
12
12
  emit: () => {},
13
13
  emitCustom: () => {},
14
14
  on: () => () => {},
@@ -16,22 +16,22 @@ var f = o({
16
16
  getBuffer: () => [],
17
17
  onAny: () => () => {}
18
18
  });
19
- function p(e, t) {
20
- if (!e) return m();
19
+ function g(e, t) {
20
+ if (!e) return _();
21
21
  let n = e.getItem(t);
22
22
  if (n) return n;
23
- let r = m();
23
+ let r = _();
24
24
  return e.setItem(t, r), r;
25
25
  }
26
- function m() {
26
+ function _() {
27
27
  return typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID() : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
28
28
  }
29
- function h() {
29
+ function v() {
30
30
  if (typeof document > "u") return "light";
31
31
  let e = document.documentElement;
32
32
  return e.classList.contains("hc") || e.dataset.theme === "hc" ? "hc" : e.classList.contains("dark") || e.dataset.theme === "dark" ? "dark" : "light";
33
33
  }
34
- function g(t, n, r) {
34
+ function y(t, n, r) {
35
35
  let i = typeof window < "u" ? window.location : void 0, a = e(), o = typeof navigator < "u" ? navigator : {
36
36
  userAgent: "",
37
37
  language: "en"
@@ -41,11 +41,11 @@ function g(t, n, r) {
41
41
  pathname: i?.pathname ?? "",
42
42
  search: i?.search ?? ""
43
43
  },
44
- sessionId: p(typeof sessionStorage < "u" ? sessionStorage : void 0, "bf-event-session-id"),
45
- deviceId: p(typeof localStorage < "u" ? localStorage : void 0, "bf-event-device-id"),
44
+ sessionId: g(typeof sessionStorage < "u" ? sessionStorage : void 0, "bf-event-session-id"),
45
+ deviceId: g(typeof localStorage < "u" ? localStorage : void 0, "bf-event-device-id"),
46
46
  userAgent: o.userAgent,
47
47
  locale: o.language || "en",
48
- theme: h(),
48
+ theme: v(),
49
49
  app: {
50
50
  name: t,
51
51
  version: n,
@@ -55,8 +55,8 @@ function g(t, n, r) {
55
55
  spanId: a.spanId
56
56
  };
57
57
  }
58
- function _({ appName: e, appVersion: t = "0.0.0", appEnv: n = "dev", sourceMfe: r = e, children: i }) {
59
- let a = u(() => v({
58
+ function b({ appName: e, appVersion: t = "0.0.0", appEnv: n = "dev", sourceMfe: r = e, children: i }) {
59
+ let a = p(() => x({
60
60
  appName: e,
61
61
  appVersion: t,
62
62
  appEnv: n,
@@ -67,16 +67,16 @@ function _({ appName: e, appVersion: t = "0.0.0", appEnv: n = "dev", sourceMfe:
67
67
  t,
68
68
  r
69
69
  ]);
70
- return /* @__PURE__ */ d(f.Provider, {
70
+ return /* @__PURE__ */ m(h.Provider, {
71
71
  value: a,
72
72
  children: i
73
73
  });
74
74
  }
75
- function v({ appName: e, appVersion: t = "0.0.0", appEnv: n = "dev", sourceMfe: r = e }) {
75
+ function x({ appName: e, appVersion: t = "0.0.0", appEnv: n = "dev", sourceMfe: r = e }) {
76
76
  let i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = [];
77
77
  function s(i, a, o) {
78
78
  return {
79
- id: m(),
79
+ id: _(),
80
80
  name: i,
81
81
  version: 1,
82
82
  source: {
@@ -86,7 +86,7 @@ function v({ appName: e, appVersion: t = "0.0.0", appEnv: n = "dev", sourceMfe:
86
86
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
87
87
  monotonic: performance.now(),
88
88
  payload: a,
89
- metadata: g(e, t, n)
89
+ metadata: y(e, t, n)
90
90
  };
91
91
  }
92
92
  function c(e) {
@@ -121,24 +121,24 @@ function v({ appName: e, appVersion: t = "0.0.0", appEnv: n = "dev", sourceMfe:
121
121
  }
122
122
  };
123
123
  }
124
- function y() {
125
- return s(f);
124
+ function S() {
125
+ return u(h);
126
126
  }
127
- function b(e, t) {
128
- let n = y();
129
- l(() => n.on(e, t), [
127
+ function C(e, t) {
128
+ let n = S();
129
+ f(() => n.on(e, t), [
130
130
  n,
131
131
  t,
132
132
  e
133
133
  ]);
134
134
  }
135
- function x(e, t) {
136
- let n = y();
137
- return c((r) => n.emit(e, r, t), [
135
+ function w(e, t) {
136
+ let n = S();
137
+ return d((r) => n.emit(e, r, t), [
138
138
  n,
139
139
  e,
140
140
  t
141
141
  ]);
142
142
  }
143
143
  //#endregion
144
- export { r as BackendAuditSink, n as BroadcastChannelSink, t as DevtoolsSink, _ as EventBusProvider, a as OtelBrowserSink, i as RybbitSink, v as createEventBus, b as useEvent, y as useEventBus, x as useEventEmitter };
144
+ export { i as AnalyticsConsentBanner, r as BackendAuditSink, n as BroadcastChannelSink, t as DevtoolsSink, b as EventBusProvider, c as OtelBrowserSink, a as RybbitSink, x as createEventBus, o as readAnalyticsConsent, s as setAnalyticsConsent, C as useEvent, S as useEventBus, w as useEventEmitter };
package/dist/shared.js CHANGED
@@ -62,63 +62,63 @@ import "./shared-components.js";
62
62
  import { DevtoolsSink as Vn } from "./shared/events/sinks/DevtoolsSink.js";
63
63
  import { BroadcastChannelSink as Hn } from "./shared/events/sinks/BroadcastChannelSink.js";
64
64
  import { BackendAuditSink as Un } from "./shared/events/sinks/BackendAuditSink.js";
65
- import { RybbitSink as Wn } from "./shared/events/sinks/RybbitSink.js";
66
- import { OtelBrowserSink as Gn } from "./shared/events/sinks/OtelBrowserSink.js";
67
- import { EventBusProvider as Kn, createEventBus as qn, useEvent as Jn, useEventBus as Yn, useEventEmitter as Xn } from "./shared-events.js";
68
- import { useDebounce as Zn } from "./shared/hooks/useDebounce.js";
69
- import { useThrottle as Qn } from "./shared/hooks/useThrottle.js";
70
- import { BREAKPOINTS as $n, useBreakpoint as er, useMobileBreakpoint as tr } from "./shared/hooks/useBreakpoint.js";
71
- import { useOnClickOutside as nr, useOnClickOutsideWithRef as rr } from "./shared/hooks/useOnClickOutside.js";
72
- import { useKeyPress as ir, useKeyboardShortcut as ar } from "./shared/hooks/useKeyPress.js";
73
- import { useExclusiveMenu as or } from "./shared/hooks/useExclusiveMenu.js";
74
- import { useLocalStorage as sr } from "./shared/hooks/useLocalStorage.js";
75
- import { useSessionStorage as cr } from "./shared/hooks/useSessionStorage.js";
76
- import { usePrevious as lr, usePreviousDistinct as ur, usePreviousHistory as dr } from "./shared/hooks/usePrevious.js";
77
- import { useConditionalToggle as fr, useToggle as pr, useToggleObject as mr } from "./shared/hooks/useToggle.js";
78
- import { usePagination as hr } from "./shared/hooks/usePagination.js";
79
- import { useAsync as gr, useAsyncImmediate as _r } from "./shared/hooks/useAsync.js";
80
- import { MODIFIER_KEYS as vr, PLATFORM_TYPES as yr } from "./shared/keyboard/types.js";
81
- import { useKeyboardShortcuts as br } from "./shared/keyboard/useKeyboardShortcuts.js";
82
- import { useHotkeys as xr } from "./shared/keyboard/useHotkeys.js";
83
- import { useShortcutHelp as Sr } from "./shared/keyboard/useShortcutHelp.js";
84
- import { GLOBAL_SHORTCUT_CATEGORIES as Cr, createGlobalShortcuts as wr, getGlobalShortcutsByCategory as Tr, mergeShortcuts as Er } from "./shared/keyboard/globalShortcuts.js";
85
- import { useLogger as Dr } from "./shared/logger/useLogger.js";
86
- import { useHasAnimated as Or } from "./shared/hooks/useHasAnimated.js";
87
- import { useReferralAttribution as kr } from "./shared/hooks/useReferralAttribution.js";
88
- import { useRecordProductVisit as Ar } from "./shared/hooks/useRecordProductVisit.js";
89
- import { QUOTA_EXHAUSTED_EVENT as jr, dispatchQuotaExhausted as Mr, useQuotaErrorToast as Nr } from "./shared/hooks/useQuotaErrorToast.js";
90
- import { PLAN_USAGE_SNAPSHOT_EVENT as Pr, publishPlanUsageSnapshot as Fr, useUpgradePrompt as Ir } from "./shared/hooks/useUpgradePrompt.js";
91
- import { appendContextToPath as Lr, useCurrentContextSearchParams as Rr } from "./shared/hooks/useCurrentContextSearchParams.js";
92
- import { MicrofrontendContext as zr, useMicrofrontendContext as Br } from "./shared-hooks.js";
93
- import { detectDeviceType as Vr, getResponsiveSelector as Hr } from "./shared/tours/types.js";
94
- import { useTourPlayer as Ur } from "./shared/tours/useTourPlayer.js";
95
- import { TourSpotlight as Wr } from "./shared/tours/TourSpotlight.js";
96
- import { TourTooltip as Gr } from "./shared/tours/TourTooltip.js";
97
- import { TourPlayerProvider as Kr, useIsTourPlaying as qr, useStartTour as Jr, useStopTour as Yr, useTourPlayerContext as Xr } from "./shared/tours/TourPlayerProvider.js";
98
- import { TourPlayer as Zr, TourTriggerButton as Qr, usePlayTour as $r } from "./shared/tours/TourPlayer.js";
99
- import { getTourContextRank as ei, getTourRouteCatalog as ti, getTourRouteModules as ni, getTourRoutePages as ri, isTourVisibleForContext as ii, normalizeTourPath as ai, registerTourRouteCatalog as oi, resolveTourTargetPath as si } from "./shared/tours/routeCatalog.js";
100
- import { withTourProgressStatus as ci } from "./shared/tours/progress.js";
101
- import { ToursProvider as li, useAutoStartTour as ui, useSafeToursContext as di, useTours as fi, useToursContext as pi } from "./shared/tours/ToursContext.js";
102
- import { TourInitializer as mi } from "./shared/tours/TourInitializer.js";
103
- import { AppShellProvider as hi, resolveAppShellObservabilityConfig as gi } from "./shared/providers/AppShellProvider.js";
104
- import { MicrofrontendProvider as _i } from "./shared-providers.js";
105
- import { TourTrigger as vi } from "./shared/tours/TourTrigger.js";
65
+ import { AnalyticsConsentBanner as Wn, RybbitSink as Gn, readAnalyticsConsent as Kn, setAnalyticsConsent as qn } from "./shared/events/sinks/RybbitSink.js";
66
+ import { OtelBrowserSink as Jn } from "./shared/events/sinks/OtelBrowserSink.js";
67
+ import { EventBusProvider as Yn, createEventBus as Xn, useEvent as Zn, useEventBus as Qn, useEventEmitter as $n } from "./shared-events.js";
68
+ import { useDebounce as er } from "./shared/hooks/useDebounce.js";
69
+ import { useThrottle as tr } from "./shared/hooks/useThrottle.js";
70
+ import { BREAKPOINTS as nr, useBreakpoint as rr, useMobileBreakpoint as ir } from "./shared/hooks/useBreakpoint.js";
71
+ import { useOnClickOutside as ar, useOnClickOutsideWithRef as or } from "./shared/hooks/useOnClickOutside.js";
72
+ import { useKeyPress as sr, useKeyboardShortcut as cr } from "./shared/hooks/useKeyPress.js";
73
+ import { useExclusiveMenu as lr } from "./shared/hooks/useExclusiveMenu.js";
74
+ import { useLocalStorage as ur } from "./shared/hooks/useLocalStorage.js";
75
+ import { useSessionStorage as dr } from "./shared/hooks/useSessionStorage.js";
76
+ import { usePrevious as fr, usePreviousDistinct as pr, usePreviousHistory as mr } from "./shared/hooks/usePrevious.js";
77
+ import { useConditionalToggle as hr, useToggle as gr, useToggleObject as _r } from "./shared/hooks/useToggle.js";
78
+ import { usePagination as vr } from "./shared/hooks/usePagination.js";
79
+ import { useAsync as yr, useAsyncImmediate as br } from "./shared/hooks/useAsync.js";
80
+ import { MODIFIER_KEYS as xr, PLATFORM_TYPES as Sr } from "./shared/keyboard/types.js";
81
+ import { useKeyboardShortcuts as Cr } from "./shared/keyboard/useKeyboardShortcuts.js";
82
+ import { useHotkeys as wr } from "./shared/keyboard/useHotkeys.js";
83
+ import { useShortcutHelp as Tr } from "./shared/keyboard/useShortcutHelp.js";
84
+ import { GLOBAL_SHORTCUT_CATEGORIES as Er, createGlobalShortcuts as Dr, getGlobalShortcutsByCategory as Or, mergeShortcuts as kr } from "./shared/keyboard/globalShortcuts.js";
85
+ import { useLogger as Ar } from "./shared/logger/useLogger.js";
86
+ import { useHasAnimated as jr } from "./shared/hooks/useHasAnimated.js";
87
+ import { useReferralAttribution as Mr } from "./shared/hooks/useReferralAttribution.js";
88
+ import { useRecordProductVisit as Nr } from "./shared/hooks/useRecordProductVisit.js";
89
+ import { QUOTA_EXHAUSTED_EVENT as Pr, dispatchQuotaExhausted as Fr, useQuotaErrorToast as Ir } from "./shared/hooks/useQuotaErrorToast.js";
90
+ import { PLAN_USAGE_SNAPSHOT_EVENT as Lr, publishPlanUsageSnapshot as Rr, useUpgradePrompt as zr } from "./shared/hooks/useUpgradePrompt.js";
91
+ import { appendContextToPath as Br, useCurrentContextSearchParams as Vr } from "./shared/hooks/useCurrentContextSearchParams.js";
92
+ import { MicrofrontendContext as Hr, useMicrofrontendContext as Ur } from "./shared-hooks.js";
93
+ import { detectDeviceType as Wr, getResponsiveSelector as Gr } from "./shared/tours/types.js";
94
+ import { useTourPlayer as Kr } from "./shared/tours/useTourPlayer.js";
95
+ import { TourSpotlight as qr } from "./shared/tours/TourSpotlight.js";
96
+ import { TourTooltip as Jr } from "./shared/tours/TourTooltip.js";
97
+ import { TourPlayerProvider as Yr, useIsTourPlaying as Xr, useStartTour as Zr, useStopTour as Qr, useTourPlayerContext as $r } from "./shared/tours/TourPlayerProvider.js";
98
+ import { TourPlayer as ei, TourTriggerButton as ti, usePlayTour as ni } from "./shared/tours/TourPlayer.js";
99
+ import { getTourContextRank as ri, getTourRouteCatalog as ii, getTourRouteModules as ai, getTourRoutePages as oi, isTourVisibleForContext as si, normalizeTourPath as ci, registerTourRouteCatalog as li, resolveTourTargetPath as ui } from "./shared/tours/routeCatalog.js";
100
+ import { withTourProgressStatus as di } from "./shared/tours/progress.js";
101
+ import { ToursProvider as fi, useAutoStartTour as pi, useSafeToursContext as mi, useTours as hi, useToursContext as gi } from "./shared/tours/ToursContext.js";
102
+ import { TourInitializer as _i } from "./shared/tours/TourInitializer.js";
103
+ import { AppShellProvider as vi, resolveAppShellObservabilityConfig as yi } from "./shared/providers/AppShellProvider.js";
104
+ import { MicrofrontendProvider as bi } from "./shared-providers.js";
105
+ import { TourTrigger as xi } from "./shared/tours/TourTrigger.js";
106
106
  import "./shared-tours.js";
107
- import { getNativeBridge as yi } from "./shared/native/bridge.js";
108
- import { getPlatform as bi, isAndroid as xi, isElectron as Si, isIOS as Ci, isInstalledApp as wi, isNative as Ti, isStandalonePWA as Ei, isWeb as Di, isWebBrowser as Oi } from "./shared/native/platform.js";
109
- import { nativeConfirm as ki, nativeCopyText as Ai, nativeImpact as ji, nativeNotify as Mi, nativeOpenUrl as Ni, nativeShare as Pi, nativeToast as Fi } from "./shared/native/consumers.js";
110
- import { SafeAreaView as Ii } from "./shared/native/SafeAreaView.js";
111
- import { useNativePlatform as Li } from "./shared/native/hooks/useNativePlatform.js";
112
- import { useSafeArea as Ri } from "./shared/native/hooks/useSafeArea.js";
113
- import { useNativeKeyboard as zi } from "./shared/native/hooks/useNativeKeyboard.js";
114
- import { useAppState as Bi } from "./shared/native/hooks/useAppState.js";
115
- import { useDeviceInfo as Vi } from "./shared/native/hooks/useDeviceInfo.js";
116
- import { useHaptics as Hi } from "./shared/native/hooks/useHaptics.js";
117
- import { useStatusBar as Ui } from "./shared/native/hooks/useStatusBar.js";
118
- import { acknowledgeNativePurchase as Wi, getNativeProducts as Gi, getNativePurchases as Ki, installNativeIAP as qi, isNativeIAPAvailable as Ji, purchaseNativeProduct as Yi, restoreNativePurchases as Xi } from "./shared/native/purchases.js";
107
+ import { getNativeBridge as Si } from "./shared/native/bridge.js";
108
+ import { getPlatform as Ci, isAndroid as wi, isElectron as Ti, isIOS as Ei, isInstalledApp as Di, isNative as Oi, isStandalonePWA as ki, isWeb as Ai, isWebBrowser as ji } from "./shared/native/platform.js";
109
+ import { nativeConfirm as Mi, nativeCopyText as Ni, nativeImpact as Pi, nativeNotify as Fi, nativeOpenUrl as Ii, nativeShare as Li, nativeToast as Ri } from "./shared/native/consumers.js";
110
+ import { SafeAreaView as zi } from "./shared/native/SafeAreaView.js";
111
+ import { useNativePlatform as Bi } from "./shared/native/hooks/useNativePlatform.js";
112
+ import { useSafeArea as Vi } from "./shared/native/hooks/useSafeArea.js";
113
+ import { useNativeKeyboard as Hi } from "./shared/native/hooks/useNativeKeyboard.js";
114
+ import { useAppState as Ui } from "./shared/native/hooks/useAppState.js";
115
+ import { useDeviceInfo as Wi } from "./shared/native/hooks/useDeviceInfo.js";
116
+ import { useHaptics as Gi } from "./shared/native/hooks/useHaptics.js";
117
+ import { useStatusBar as Ki } from "./shared/native/hooks/useStatusBar.js";
118
+ import { acknowledgeNativePurchase as qi, getNativeProducts as Ji, getNativePurchases as Yi, installNativeIAP as Xi, isNativeIAPAvailable as Zi, purchaseNativeProduct as Qi, restoreNativePurchases as $i } from "./shared/native/purchases.js";
119
119
  import "./shared-native.js";
120
120
  import "./shared/actors/index.js";
121
121
  //#region src/shared/index.ts
122
- var Zi = "1.0.0";
122
+ var ea = "1.0.0";
123
123
  //#endregion
124
- export { Rn as ASSISTANT_WIDGET_TOGGLE_EVENT, $t as AccessDenied, Wt as ActorIdentity, Fe as ApolloClient, Ie as ApolloProvider, un as AppErrorBoundary, xt as AppInitializer, hi as AppShellProvider, zn as AssistantWidget, ie as BACKEND_ERROR_EVENT, $n as BREAKPOINTS, Un as BackendAuditSink, Hn as BroadcastChannelSink, G as COMMON_SHELL_LESS_ROUTES, ae as CONNECTION_STATUS_EVENT, sn as ConditionalShell, Ot as ConsoleTransport, _n as ContextConversationWidget, Z as DEFAULT_PAGE_SIZE, K as DEFAULT_SHELL_CONFIG, Vn as DevtoolsSink, qt as ErrorBoundary, tn as ErrorFallback, Kn as EventBusProvider, Zi as FE_SHARED_VERSION, dn as FeatureFlagProvider, gn as FeatureGate, Q as GATEWAYS, Cr as GLOBAL_SHORTCUT_CATEGORIES, Oe as GatewayProvider, Le as InMemoryCache, jn as KeyboardHelpDialogWrapper, nn as LoadingFallback, wt as LogLevel, Et as LogManager, Tt as Logger, vr as MODIFIER_KEYS, Bn as Markdown, zr as MicrofrontendContext, on as MicrofrontendErrorBoundary, _i as MicrofrontendProvider, Gn as OtelBrowserSink, Pr as PLAN_USAGE_SNAPSHOT_EVENT, yr as PLATFORM_TYPES, V as PRODUCTS, H as PRODUCT_URLS, ln as PWAInstallBanner, rn as PageLoadingFallback, Xt as PermissionButton, en as PermissionDenied, Zt as PermissionGate, Qt as PermissionLink, Pt as QUOTA_EXHAUSTED_CODE, jr as QUOTA_EXHAUSTED_EVENT, Mn as QuotaMeter, Ft as RESOURCE_CAP_EXCEEDED_CODE, Jt as RequireAuth, Yt as RequireGuest, Wn as RybbitSink, Se as SSELink, it as SSORedirectSpinner, lt as SSO_DEPOSITED_PARAM, It as STORAGE_QUOTA_EXCEEDED_CODE, Ii as SafeAreaView, an as SectionLoadingFallback, mi as TourInitializer, Zr as TourPlayer, Kr as TourPlayerProvider, Wr as TourSpotlight, Gr as TourTooltip, vi as TourTrigger, Qr as TourTriggerButton, li as ToursProvider, Lt as UPGRADE_ERROR_CODES, Nn as UPGRADE_PROMPT_EVENT, In as UpgradeInlineBanner, Pn as UpgradePromptModal, Pe as WsLink, Wi as acknowledgeNativePurchase, r as alertTokens, Lr as appendContextToPath, We as attemptTokenRefresh, ut as beginSsoNavigation, Gt as buildActorFallback, Rt as buildQuotaExhaustedMessage, dt as buildSsoDepositUrl, m as capitalizeFirst, h as capitalizeWords, i as categoryTokens, at as checkRemoteSLO, ot as checkSLO, Ge as clearAuthSessionStorage, pe as clearGraphqlFetchResponseCache, st as clearLocalAuthState, Xe as clearSSoCookie, Ze as clearShellSsoCookies, ft as clearSsoDepositState, pt as clearSsoNavigation, kt as clearUserContext, Ut as cn, mt as consumeSsoDepositMarker, n as createApolloClient, qn as createEventBus, wr as createGlobalShortcuts, Ce as createGraphQLClient, Mt as createProfileScopedStorage, Vr as detectDeviceType, vn as detectPlatform, oe as dispatchBackendErrorEvent, Mr as dispatchQuotaExhausted, Fn as dispatchUpgradePrompt, se as extractBackendError, zt as extractQuotaExhaustedExtensions, Bt as extractUpgradeErrorExtensions, g as formatBytes, _ as formatCompactNumber, v as formatCurrency, y as formatCurrencyCompact, b as formatDate, x as formatDateTime, S as formatDuration, yn as formatKeyCombo, C as formatList, w as formatNumber, T as formatOrdinal, E as formatPercentage, D as formatRelativeTime, O as formatTime, a as getAlertTokens, o as getCategoryTokens, bn as getDisplayKeysForPlatform, $ as getGatewayConfig, ee as getGatewayUrl, we as getGlobalClient, Tr as getGlobalShortcutsByCategory, te as getGraphQLEndpoint, yi as getNativeBridge, Gi as getNativeProducts, Ki as getNativePurchases, bi as getPlatform, U as getProductUrl, W as getProductsWithUrls, Nt as getProfileScopedKey, s as getProgressTokens, Hr as getResponsiveSelector, ct as getSSORedirectUrl, Qe as getSSoCookie, q as getShellConfig, xn as getShortcutLabel, c as getStatusBadgeTokens, l as getStatusTokens, me as getStoredAuthToken, he as getStoredLocale, ge as getStoredOrganizationId, _e as getStoredProjectId, ve as getStoredWorkspaceId, ye as getStoredWorkspaceToken, ei as getTourContextRank, ti as getTourRouteCatalog, ni as getTourRouteModules, ri as getTourRoutePages, u as getTrendTokens, Te as getWorkspaceClient, ne as getWorkspaceTokenPayload, Re as gql, be as graphqlFetch, Ke as hasAuthGraphQLErrors, Ee as initializeAppClients, At as initializeLogger, L as installGatewayFetchRewrite, qi as installNativeIAP, ce as isAbortError, xi as isAndroid, qe as isAuthGraphQLError, Je as isAuthNetworkError, le as isBackendErrorDisplay, P as isChunkLoadError, Si as isElectron, Ci as isIOS, wi as isInstalledApp, Sn as isMac, Cn as isMobileDevice, Ti as isNative, Ji as isNativeIAPAvailable, Vt as isQuotaExhaustedError, $e as isSharedSsoCookieDomain, J as isShellLessRoute, ht as isSsoNavigationPending, Ei as isStandalonePWA, wn as isTabletDevice, ii as isTourVisibleForContext, ue as isTransportError, et as isTrustedSsoOrigin, Ht as isUpgradeError, Di as isWeb, Oi as isWebBrowser, re as isWorkspaceTokenValidForContext, F as lazyWithRetry, Dt as logManager, de as markConnectionHealthy, gt as markSsoDepositDone, _t as markSsoDepositPending, Tn as matchesKeyCombo, Er as mergeShortcuts, vt as mintSsoSessionTokens, ki as nativeConfirm, Ai as nativeCopyText, ji as nativeImpact, Mi as nativeNotify, Ni as nativeOpenUrl, Pi as nativeShare, Fi as nativeToast, En as normalizeKey, Dn as normalizePlatformCombo, ai as normalizeTourPath, On as parseKeyCombo, k as pluralize, d as progressTokens, Fr as publishPlanUsageSnapshot, Yi as purchaseNativeProduct, tt as readShellSsoCookie, yt as readSsoDepositState, Ye as redirectToLogin, oi as registerTourRouteCatalog, De as resetAppClients, gi as resolveAppShellObservabilityConfig, B as resolveAuthBridgeConfig, R as resolveGatewayBases, xe as resolveGatewayUrl, I as resolveGatewayUrls, si as resolveTourTargetPath, Xi as restoreNativePurchases, nt as setSSoCookie, rt as setShellSsoCookies, jt as setUserContext, bt as shouldAttemptSsoDeposit, kn as shouldEnableKeyboardShortcuts, An as shouldIgnoreShortcut, Y as shouldShowBreadcrumb, X as shouldShowSidebar, fe as shouldToastBackendError, A as slugify, f as statusTokens, z as suppressConsole, j as toCamelCase, M as toPascalCase, p as trendTokens, N as truncateText, Kt as useActorProfiles, ze as useApolloClient, Bi as useAppState, gr as useAsync, _r as useAsyncImmediate, ui as useAutoStartTour, er as useBreakpoint, fr as useConditionalToggle, e as useCopyToClipboard, Rr as useCurrentContextSearchParams, Zn as useDebounce, Vi as useDeviceInfo, Jn as useEvent, Yn as useEventBus, Xn as useEventEmitter, or as useExclusiveMenu, pn as useFeatureFlag, mn as useFeatureFlagDetails, hn as useFeatureFlagValue, fn as useFeatureFlags, ke as useGateway, Ae as useGatewayClient, Hi as useHaptics, Or as useHasAnimated, Ne as useHasAuthToken, xr as useHotkeys, qr as useIsTourPlaying, ir as useKeyPress, ar as useKeyboardShortcut, br as useKeyboardShortcuts, Be as useLazyQuery, sr as useLocalStorage, Dr as useLogger, t as useMediaQuery, Br as useMicrofrontendContext, tr as useMobileBreakpoint, Ve as useMutation, zi as useNativeKeyboard, Li as useNativePlatform, nr as useOnClickOutside, rr as useOnClickOutsideWithRef, cn as usePWA, hr as usePagination, $r as usePlayTour, lr as usePrevious, ur as usePreviousDistinct, dr as usePreviousHistory, He as useQuery, Nr as useQuotaErrorToast, Ar as useRecordProductVisit, kr as useReferralAttribution, St as useRegistryHelpers, Ri as useSafeArea, je as useSafeGateway, Me as useSafeGatewayClient, di as useSafeToursContext, cr as useSessionStorage, Ct as useShellNavigate, Sr as useShortcutHelp, Jr as useStartTour, Ui as useStatusBar, Yr as useStopTour, Ue as useSubscription, Qn as useThrottle, pr as useToggle, mr as useToggleObject, Ur as useTourPlayer, Xr as useTourPlayerContext, fi as useTours, pi as useToursContext, Ir as useUpgradePrompt, Ln as useVoiceInput, ci as withTourProgressStatus };
124
+ export { Rn as ASSISTANT_WIDGET_TOGGLE_EVENT, $t as AccessDenied, Wt as ActorIdentity, Wn as AnalyticsConsentBanner, Fe as ApolloClient, Ie as ApolloProvider, un as AppErrorBoundary, xt as AppInitializer, vi as AppShellProvider, zn as AssistantWidget, ie as BACKEND_ERROR_EVENT, nr as BREAKPOINTS, Un as BackendAuditSink, Hn as BroadcastChannelSink, G as COMMON_SHELL_LESS_ROUTES, ae as CONNECTION_STATUS_EVENT, sn as ConditionalShell, Ot as ConsoleTransport, _n as ContextConversationWidget, Z as DEFAULT_PAGE_SIZE, K as DEFAULT_SHELL_CONFIG, Vn as DevtoolsSink, qt as ErrorBoundary, tn as ErrorFallback, Yn as EventBusProvider, ea as FE_SHARED_VERSION, dn as FeatureFlagProvider, gn as FeatureGate, Q as GATEWAYS, Er as GLOBAL_SHORTCUT_CATEGORIES, Oe as GatewayProvider, Le as InMemoryCache, jn as KeyboardHelpDialogWrapper, nn as LoadingFallback, wt as LogLevel, Et as LogManager, Tt as Logger, xr as MODIFIER_KEYS, Bn as Markdown, Hr as MicrofrontendContext, on as MicrofrontendErrorBoundary, bi as MicrofrontendProvider, Jn as OtelBrowserSink, Lr as PLAN_USAGE_SNAPSHOT_EVENT, Sr as PLATFORM_TYPES, V as PRODUCTS, H as PRODUCT_URLS, ln as PWAInstallBanner, rn as PageLoadingFallback, Xt as PermissionButton, en as PermissionDenied, Zt as PermissionGate, Qt as PermissionLink, Pt as QUOTA_EXHAUSTED_CODE, Pr as QUOTA_EXHAUSTED_EVENT, Mn as QuotaMeter, Ft as RESOURCE_CAP_EXCEEDED_CODE, Jt as RequireAuth, Yt as RequireGuest, Gn as RybbitSink, Se as SSELink, it as SSORedirectSpinner, lt as SSO_DEPOSITED_PARAM, It as STORAGE_QUOTA_EXCEEDED_CODE, zi as SafeAreaView, an as SectionLoadingFallback, _i as TourInitializer, ei as TourPlayer, Yr as TourPlayerProvider, qr as TourSpotlight, Jr as TourTooltip, xi as TourTrigger, ti as TourTriggerButton, fi as ToursProvider, Lt as UPGRADE_ERROR_CODES, Nn as UPGRADE_PROMPT_EVENT, In as UpgradeInlineBanner, Pn as UpgradePromptModal, Pe as WsLink, qi as acknowledgeNativePurchase, r as alertTokens, Br as appendContextToPath, We as attemptTokenRefresh, ut as beginSsoNavigation, Gt as buildActorFallback, Rt as buildQuotaExhaustedMessage, dt as buildSsoDepositUrl, m as capitalizeFirst, h as capitalizeWords, i as categoryTokens, at as checkRemoteSLO, ot as checkSLO, Ge as clearAuthSessionStorage, pe as clearGraphqlFetchResponseCache, st as clearLocalAuthState, Xe as clearSSoCookie, Ze as clearShellSsoCookies, ft as clearSsoDepositState, pt as clearSsoNavigation, kt as clearUserContext, Ut as cn, mt as consumeSsoDepositMarker, n as createApolloClient, Xn as createEventBus, Dr as createGlobalShortcuts, Ce as createGraphQLClient, Mt as createProfileScopedStorage, Wr as detectDeviceType, vn as detectPlatform, oe as dispatchBackendErrorEvent, Fr as dispatchQuotaExhausted, Fn as dispatchUpgradePrompt, se as extractBackendError, zt as extractQuotaExhaustedExtensions, Bt as extractUpgradeErrorExtensions, g as formatBytes, _ as formatCompactNumber, v as formatCurrency, y as formatCurrencyCompact, b as formatDate, x as formatDateTime, S as formatDuration, yn as formatKeyCombo, C as formatList, w as formatNumber, T as formatOrdinal, E as formatPercentage, D as formatRelativeTime, O as formatTime, a as getAlertTokens, o as getCategoryTokens, bn as getDisplayKeysForPlatform, $ as getGatewayConfig, ee as getGatewayUrl, we as getGlobalClient, Or as getGlobalShortcutsByCategory, te as getGraphQLEndpoint, Si as getNativeBridge, Ji as getNativeProducts, Yi as getNativePurchases, Ci as getPlatform, U as getProductUrl, W as getProductsWithUrls, Nt as getProfileScopedKey, s as getProgressTokens, Gr as getResponsiveSelector, ct as getSSORedirectUrl, Qe as getSSoCookie, q as getShellConfig, xn as getShortcutLabel, c as getStatusBadgeTokens, l as getStatusTokens, me as getStoredAuthToken, he as getStoredLocale, ge as getStoredOrganizationId, _e as getStoredProjectId, ve as getStoredWorkspaceId, ye as getStoredWorkspaceToken, ri as getTourContextRank, ii as getTourRouteCatalog, ai as getTourRouteModules, oi as getTourRoutePages, u as getTrendTokens, Te as getWorkspaceClient, ne as getWorkspaceTokenPayload, Re as gql, be as graphqlFetch, Ke as hasAuthGraphQLErrors, Ee as initializeAppClients, At as initializeLogger, L as installGatewayFetchRewrite, Xi as installNativeIAP, ce as isAbortError, wi as isAndroid, qe as isAuthGraphQLError, Je as isAuthNetworkError, le as isBackendErrorDisplay, P as isChunkLoadError, Ti as isElectron, Ei as isIOS, Di as isInstalledApp, Sn as isMac, Cn as isMobileDevice, Oi as isNative, Zi as isNativeIAPAvailable, Vt as isQuotaExhaustedError, $e as isSharedSsoCookieDomain, J as isShellLessRoute, ht as isSsoNavigationPending, ki as isStandalonePWA, wn as isTabletDevice, si as isTourVisibleForContext, ue as isTransportError, et as isTrustedSsoOrigin, Ht as isUpgradeError, Ai as isWeb, ji as isWebBrowser, re as isWorkspaceTokenValidForContext, F as lazyWithRetry, Dt as logManager, de as markConnectionHealthy, gt as markSsoDepositDone, _t as markSsoDepositPending, Tn as matchesKeyCombo, kr as mergeShortcuts, vt as mintSsoSessionTokens, Mi as nativeConfirm, Ni as nativeCopyText, Pi as nativeImpact, Fi as nativeNotify, Ii as nativeOpenUrl, Li as nativeShare, Ri as nativeToast, En as normalizeKey, Dn as normalizePlatformCombo, ci as normalizeTourPath, On as parseKeyCombo, k as pluralize, d as progressTokens, Rr as publishPlanUsageSnapshot, Qi as purchaseNativeProduct, Kn as readAnalyticsConsent, tt as readShellSsoCookie, yt as readSsoDepositState, Ye as redirectToLogin, li as registerTourRouteCatalog, De as resetAppClients, yi as resolveAppShellObservabilityConfig, B as resolveAuthBridgeConfig, R as resolveGatewayBases, xe as resolveGatewayUrl, I as resolveGatewayUrls, ui as resolveTourTargetPath, $i as restoreNativePurchases, qn as setAnalyticsConsent, nt as setSSoCookie, rt as setShellSsoCookies, jt as setUserContext, bt as shouldAttemptSsoDeposit, kn as shouldEnableKeyboardShortcuts, An as shouldIgnoreShortcut, Y as shouldShowBreadcrumb, X as shouldShowSidebar, fe as shouldToastBackendError, A as slugify, f as statusTokens, z as suppressConsole, j as toCamelCase, M as toPascalCase, p as trendTokens, N as truncateText, Kt as useActorProfiles, ze as useApolloClient, Ui as useAppState, yr as useAsync, br as useAsyncImmediate, pi as useAutoStartTour, rr as useBreakpoint, hr as useConditionalToggle, e as useCopyToClipboard, Vr as useCurrentContextSearchParams, er as useDebounce, Wi as useDeviceInfo, Zn as useEvent, Qn as useEventBus, $n as useEventEmitter, lr as useExclusiveMenu, pn as useFeatureFlag, mn as useFeatureFlagDetails, hn as useFeatureFlagValue, fn as useFeatureFlags, ke as useGateway, Ae as useGatewayClient, Gi as useHaptics, jr as useHasAnimated, Ne as useHasAuthToken, wr as useHotkeys, Xr as useIsTourPlaying, sr as useKeyPress, cr as useKeyboardShortcut, Cr as useKeyboardShortcuts, Be as useLazyQuery, ur as useLocalStorage, Ar as useLogger, t as useMediaQuery, Ur as useMicrofrontendContext, ir as useMobileBreakpoint, Ve as useMutation, Hi as useNativeKeyboard, Bi as useNativePlatform, ar as useOnClickOutside, or as useOnClickOutsideWithRef, cn as usePWA, vr as usePagination, ni as usePlayTour, fr as usePrevious, pr as usePreviousDistinct, mr as usePreviousHistory, He as useQuery, Ir as useQuotaErrorToast, Nr as useRecordProductVisit, Mr as useReferralAttribution, St as useRegistryHelpers, Vi as useSafeArea, je as useSafeGateway, Me as useSafeGatewayClient, mi as useSafeToursContext, dr as useSessionStorage, Ct as useShellNavigate, Tr as useShortcutHelp, Zr as useStartTour, Ki as useStatusBar, Qr as useStopTour, Ue as useSubscription, tr as useThrottle, gr as useToggle, _r as useToggleObject, Kr as useTourPlayer, $r as useTourPlayerContext, hi as useTours, gi as useToursContext, zr as useUpgradePrompt, Ln as useVoiceInput, di as withTourProgressStatus };
@@ -1 +1 @@
1
- {"version":3,"file":"SaveToFilesDialog.d.ts","sourceRoot":"","sources":["../../src/storage/SaveToFilesDialog.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElE,UAAU,KAAK;IACb,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,iBAAiB,EACjB,QAAQ,EACR,OAAO,GACR,EAAE,KAAK,2CAwFP"}
1
+ {"version":3,"file":"SaveToFilesDialog.d.ts","sourceRoot":"","sources":["../../src/storage/SaveToFilesDialog.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElE,UAAU,KAAK;IACb,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,iBAAiB,EACjB,QAAQ,EACR,OAAO,GACR,EAAE,KAAK,2CA6GP"}
@@ -8,7 +8,7 @@ import { useEffect as d, useState as f } from "react";
8
8
  import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
9
9
  //#region src/storage/SaveToFilesDialog.tsx
10
10
  function g({ open: g, onOpenChange: _, source: v, defaultFolderPath: y, filename: b, onSaved: x }) {
11
- let [S, C] = f(y ?? "/Saved"), { save: w, isPending: T, error: E, progress: D } = u();
11
+ let [S, C] = f(y ?? "/Saved"), { save: w, isPending: T, error: E, progress: D, retry: O } = u();
12
12
  return d(() => {
13
13
  g && C(y ?? "/Saved");
14
14
  }, [g, y]), /* @__PURE__ */ m(e, {
@@ -55,6 +55,21 @@ function g({ open: g, onOpenChange: _, source: v, defaultFolderPath: y, filename
55
55
  style: { width: `${D}%` }
56
56
  })
57
57
  }),
58
+ T && O && /* @__PURE__ */ h("p", {
59
+ className: "text-xs text-muted-foreground",
60
+ role: "status",
61
+ "aria-live": "polite",
62
+ "data-testid": "save-to-files-retry",
63
+ children: [
64
+ O.kind === "cold-start" ? "The file service is starting up — retrying" : "Hit a hiccup — retrying",
65
+ " ",
66
+ "(attempt ",
67
+ O.attempt,
68
+ " of ",
69
+ O.maxAttempts,
70
+ ")…"
71
+ ]
72
+ }),
58
73
  E && /* @__PURE__ */ m("p", {
59
74
  className: "text-xs text-destructive",
60
75
  "data-testid": "save-to-files-error",
@@ -6,5 +6,8 @@ export { SaveToFilesDialog } from './SaveToFilesDialog';
6
6
  export { useSaveToFiles } from './useSaveToFiles';
7
7
  export type { SavedFile, UseSaveToFilesResult } from './useSaveToFiles';
8
8
  export { uploadBlobToFiles, FILES_AFTER_SAVE_REFETCH } from './uploadBlob';
9
- export type { UploadBlobParams, UploadedFile } from './uploadBlob';
9
+ export type { UploadBlobParams, UploadedFile, SaveToFilesStep, SaveToFilesRetryNotice, } from './uploadBlob';
10
+ export { classifyFilesError, decideFilesRetry, runWithFilesRetry, COLD_START_MAX_ATTEMPTS, COLD_START_RETRY_DELAYS_MS, COLD_START_RETRY_BUDGET_MS, } from './retryPolicy';
11
+ export type { FilesRetryKind, FilesRetryDecision, FilesRetryNotice, FilesRetryContext, } from './retryPolicy';
12
+ export { warmFilesService, useFilesServiceWarmup, FILES_WARMUP_COOLDOWN_MS, } from './warmFilesService';
10
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAC3E,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAC3E,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC"}
@@ -1,6 +1,8 @@
1
1
  import { StorageFolderPicker as e } from "./StorageFolderPicker.js";
2
- import { FILES_AFTER_SAVE_REFETCH as t, uploadBlobToFiles as n } from "./uploadBlob.js";
3
- import { useSaveToFiles as r } from "./useSaveToFiles.js";
4
- import { SaveToFilesDialog as i } from "./SaveToFilesDialog.js";
5
- import { SaveToFilesButton as a } from "./SaveToFilesButton.js";
6
- export { t as FILES_AFTER_SAVE_REFETCH, a as SaveToFilesButton, i as SaveToFilesDialog, e as StorageFolderPicker, n as uploadBlobToFiles, r as useSaveToFiles };
2
+ import { COLD_START_MAX_ATTEMPTS as t, COLD_START_RETRY_BUDGET_MS as n, COLD_START_RETRY_DELAYS_MS as r, classifyFilesError as i, decideFilesRetry as a, runWithFilesRetry as o } from "./retryPolicy.js";
3
+ import { FILES_AFTER_SAVE_REFETCH as s, uploadBlobToFiles as c } from "./uploadBlob.js";
4
+ import { useSaveToFiles as l } from "./useSaveToFiles.js";
5
+ import { SaveToFilesDialog as u } from "./SaveToFilesDialog.js";
6
+ import { SaveToFilesButton as d } from "./SaveToFilesButton.js";
7
+ import { FILES_WARMUP_COOLDOWN_MS as f, useFilesServiceWarmup as p, warmFilesService as m } from "./warmFilesService.js";
8
+ export { t as COLD_START_MAX_ATTEMPTS, n as COLD_START_RETRY_BUDGET_MS, r as COLD_START_RETRY_DELAYS_MS, s as FILES_AFTER_SAVE_REFETCH, f as FILES_WARMUP_COOLDOWN_MS, d as SaveToFilesButton, u as SaveToFilesDialog, e as StorageFolderPicker, i as classifyFilesError, a as decideFilesRetry, o as runWithFilesRetry, c as uploadBlobToFiles, p as useFilesServiceWarmup, l as useSaveToFiles, m as warmFilesService };
@@ -0,0 +1,179 @@
1
+ /**
2
+ * retryPolicy — when a wspace-files-svc call through the workspace gateway is
3
+ * worth trying again, and how long to wait before doing so.
4
+ *
5
+ * ## Why this exists: a scale-to-zero cold start, measured in production
6
+ *
7
+ * `wspace-files-svc` runs at `minReplicas: 0`, 0.25 vCPU / 0.5 GiB, so after an
8
+ * idle period its revision sits at `replicas: 0, state: "ScaledToZero"`. Timed on
9
+ * the deployed image at that exact resource envelope:
10
+ *
11
+ * bunx prisma migrate deploy 26.0s
12
+ * app boot ~25.5s
13
+ * ------------------------------------
14
+ * >= 51s before the port binds
15
+ *
16
+ * The gateway's per-operation budget is `OPERATION_TIMEOUT_MS = 15_000`. The first
17
+ * request after a quiet period therefore CANNOT succeed: it wakes the container and
18
+ * is then abandoned ~36s before that container can answer.
19
+ *
20
+ * Seven-attempt production reproduction, same 1,305-byte file, idle gaps
21
+ * 0/5/40/5/40/90/5s:
22
+ *
23
+ * #1 16.2s FAIL "Operation timeout" {"code":"OPERATION_TIMEOUT","timeoutMs":15000}
24
+ * #2 16.2s OK #3 6.1s OK #4 6.1s OK #5 6.1s OK #6 2.1s OK #7 2.1s OK
25
+ *
26
+ * Only the first attempt fails; everything after it is warm and gets faster. With a
27
+ * 300s Azure Container Apps cooldown, a real user's first attachment after any quiet
28
+ * period lands on exactly this. The proper fix is `minReplicas: 1` — that needs Azure
29
+ * access, so this module is the client-side half that makes the cold start survivable
30
+ * meanwhile. Several services in this fleet are scale-to-zero, so it is not a
31
+ * one-off workaround.
32
+ *
33
+ * ## Two retry classes, deliberately different
34
+ *
35
+ * - `cold-start` — the gateway gave up waiting (`OPERATION_TIMEOUT` and friends).
36
+ * The container is probably still booting, so the delays are sized
37
+ * in TENS of seconds. A single immediate retry is useless here.
38
+ * - `transient-blip` — a masked `INTERNAL_SERVER_ERROR` or a bare network error, the
39
+ * pre-existing `completeUpload` case (a brief Azure Managed Redis
40
+ * slowdown). Sub-second delays, unchanged from before this module.
41
+ *
42
+ * ## What is NEVER retried
43
+ *
44
+ * Classification is an ALLOWLIST: an unrecognised code is not retried. On top of
45
+ * that, `NEVER_RETRY_CODES` is a hard stop — if a quota rejection, an auth failure
46
+ * or any other 4xx-class business error appears anywhere in the error, the whole
47
+ * error is unretryable even if a timeout also appears. Retrying those is pure harm:
48
+ * the answer will not change and the user waits a minute to be told the same thing.
49
+ */
50
+ /** How an error should be retried, or `null` for "do not retry this". */
51
+ export type FilesRetryKind = 'cold-start' | 'transient-blip';
52
+ /**
53
+ * Attempt ceiling for a cold start. Three attempts, and the third one starts at
54
+ * roughly t+61s:
55
+ *
56
+ * attempt 1 t=0 -> gateway gives up at ~16s
57
+ * wait 10s
58
+ * attempt 2 t=26 -> gateway gives up at ~41s
59
+ * wait 20s
60
+ * attempt 3 t=61 -> container bound its port at ~51s, so this is the one that lands
61
+ *
62
+ * The container's boot clock starts when attempt 1 reaches the ACA ingress, which is
63
+ * why the ladder is measured from the FIRST attempt and not from each failure. The
64
+ * numbers above come from the measurement at the top of this file: >=51s to port
65
+ * bind, 15s gateway budget. Change them if that measurement changes, not before.
66
+ */
67
+ export declare const COLD_START_MAX_ATTEMPTS = 3;
68
+ /** Delay before cold-start attempt 2, then before attempt 3. See the ladder above. */
69
+ export declare const COLD_START_RETRY_DELAYS_MS: readonly number[];
70
+ /**
71
+ * Hard wall-clock ceiling for one operation's cold-start retries, measured from the
72
+ * first attempt. The ladder above tops out at ~76s of real time; this stops a
73
+ * pathologically slow gateway from stretching that indefinitely. Past this, we give
74
+ * up honestly and show the user the real error.
75
+ */
76
+ export declare const COLD_START_RETRY_BUDGET_MS = 75000;
77
+ /** Attempt ceiling for a transient blip — unchanged from the pre-existing behaviour. */
78
+ export declare const BLIP_MAX_ATTEMPTS = 3;
79
+ /** Delays before blip attempts 2 and 3 — unchanged from the pre-existing behaviour. */
80
+ export declare const BLIP_RETRY_DELAYS_MS: readonly number[];
81
+ /**
82
+ * Best-effort message extraction, preferring the first GraphQL error's message
83
+ * (Apollo v4 `CombinedGraphQLErrors.errors`, or v3 `.graphQLErrors`) so callers can
84
+ * surface the real reason instead of a generic envelope.
85
+ *
86
+ * Lives here rather than in `uploadBlob` because both the upload path and the folder
87
+ * path need it and both now sit on top of this module. `uploadBlob` re-exports it, so
88
+ * its public name is unchanged.
89
+ */
90
+ export declare function extractErrorMessage(err: unknown): string | undefined;
91
+ /**
92
+ * Decide what KIND of failure this is, or `null` if it must not be retried.
93
+ *
94
+ * Pure. This is the whole safety argument in one function, so it is unit-tested
95
+ * directly rather than only through the upload path.
96
+ */
97
+ export declare function classifyFilesError(err: unknown): FilesRetryKind | null;
98
+ export interface FilesRetryContext {
99
+ /** 1-based index of the attempt that just failed. */
100
+ attempt: number;
101
+ /** Milliseconds since the FIRST attempt started (the container's boot clock). */
102
+ elapsedMs: number;
103
+ /** Which classes this call site permits. Defaults to cold-start only. */
104
+ allow?: readonly FilesRetryKind[];
105
+ }
106
+ export type FilesRetryDecision = {
107
+ retry: true;
108
+ kind: FilesRetryKind;
109
+ /** How long to wait before the next attempt. */
110
+ delayMs: number;
111
+ /** 1-based number of the attempt that is about to run. */
112
+ nextAttempt: number;
113
+ maxAttempts: number;
114
+ } | {
115
+ retry: false;
116
+ reason: 'not-retryable' | 'kind-not-allowed' | 'attempts-exhausted' | 'budget-exhausted';
117
+ };
118
+ /**
119
+ * The retry policy as a pure function: given the error and where we are, should we go
120
+ * again and after how long?
121
+ *
122
+ * Separated from any I/O so the safety properties can be asserted directly — retries
123
+ * on a gateway timeout, does NOT retry a quota/auth/4xx rejection, respects the
124
+ * attempt ceiling and the wall-clock budget, and reports honestly why it stopped.
125
+ */
126
+ export declare function decideFilesRetry(err: unknown, ctx: FilesRetryContext): FilesRetryDecision;
127
+ /** What one attempt reports back to the runner. */
128
+ export type FilesAttemptResult<T> = {
129
+ ok: true;
130
+ value: T;
131
+ } | {
132
+ ok: false;
133
+ error: unknown;
134
+ };
135
+ /** Handed to `onRetry` just before the runner sleeps. Enough to render honest UI. */
136
+ export interface FilesRetryNotice {
137
+ kind: FilesRetryKind;
138
+ /** 1-based number of the attempt about to run (2 means "second try"). */
139
+ attempt: number;
140
+ maxAttempts: number;
141
+ /** How long the runner is about to wait. */
142
+ delayMs: number;
143
+ /** The failure that triggered the retry, for logging — never for the user. */
144
+ error: unknown;
145
+ }
146
+ export interface RunWithFilesRetryOptions {
147
+ /** Which classes this call site permits. Defaults to cold-start only. */
148
+ allow?: readonly FilesRetryKind[];
149
+ /** Fired before each wait, so the UI can say what it is waiting for. */
150
+ onRetry?: (notice: FilesRetryNotice) => void;
151
+ /** Injected by tests. */
152
+ now?: () => number;
153
+ /** Injected by tests. */
154
+ sleep?: (ms: number) => Promise<void>;
155
+ }
156
+ export interface FilesRetryOutcome<T> {
157
+ /** Present only on success. */
158
+ value?: T;
159
+ /** The last in-band error, when `value` is absent. */
160
+ error?: unknown;
161
+ /** How many attempts were actually made. */
162
+ attempts: number;
163
+ /** Why we stopped, when `value` is absent. */
164
+ gaveUpBecause?: 'not-retryable' | 'kind-not-allowed' | 'attempts-exhausted' | 'budget-exhausted';
165
+ }
166
+ /**
167
+ * Run `attempt` until it succeeds, the policy says stop, or the budget runs out.
168
+ *
169
+ * Two failure channels, on purpose:
170
+ *
171
+ * - A THROWN error is classified and, if unretryable, rethrown **as-is**. Identity
172
+ * and stack are preserved, so callers that let network errors through untouched
173
+ * keep doing exactly that.
174
+ * - An IN-BAND error (`{ ok: false, error }` — what `errorPolicy: 'all'` produces on
175
+ * `result.error`) is returned in the outcome. The runner never invents a message
176
+ * for it; the caller owns the wording, which is what fe-libs #132 established.
177
+ */
178
+ export declare function runWithFilesRetry<T>(attempt: (attemptNumber: number) => Promise<FilesAttemptResult<T>>, options?: RunWithFilesRetryOptions): Promise<FilesRetryOutcome<T>>;
179
+ //# sourceMappingURL=retryPolicy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retryPolicy.d.ts","sourceRoot":"","sources":["../../src/storage/retryPolicy.ts"],"names":[],"mappings":"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"}