@burdenoff/fe-libs 2026.1023.7 → 2026.1023.9

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 (39) hide show
  1. package/dist/shared/events/sinks/RybbitSink.d.ts +21 -0
  2. package/dist/shared/events/sinks/RybbitSink.js +36 -11
  3. package/dist/shared/events/sinks/index.d.ts +1 -1
  4. package/dist/shared/graphql/client.d.ts +9 -0
  5. package/dist/shared/graphql/client.js +241 -201
  6. package/dist/shared/graphql/fetch.js +135 -123
  7. package/dist/shared/graphql/index.d.ts +1 -0
  8. package/dist/shared/graphql/workspaceOperationGuard.d.ts +70 -0
  9. package/dist/shared/graphql/workspaceOperationGuard.js +62 -0
  10. package/dist/shared/providers/AppShellProvider.d.ts +16 -0
  11. package/dist/shared/providers/AppShellProvider.js +232 -226
  12. package/dist/shared/providers/shell/AuthProvider.d.ts +14 -1
  13. package/dist/shared/providers/shell/AuthProvider.js +105 -94
  14. package/dist/shared/providers/shell/MultiGatewayProvider.d.ts +8 -1
  15. package/dist/shared/providers/shell/MultiGatewayProvider.js +115 -119
  16. package/dist/shared/providers/shell/ProfileStorageManager.js +1 -1
  17. package/dist/shared/providers/shell/WorkspaceWriteRefusedToastListener.d.ts +4 -0
  18. package/dist/shared/providers/shell/WorkspaceWriteRefusedToastListener.js +23 -0
  19. package/dist/shared/providers/shell/authProvider/identityChange.d.ts +26 -0
  20. package/dist/shared/providers/shell/authProvider/identityChange.js +11 -0
  21. package/dist/shared/providers/shell/authProvider/useAuthActions.d.ts +4 -1
  22. package/dist/shared/providers/shell/authProvider/useAuthActions.js +105 -92
  23. package/dist/shared/providers/shell/authProvider/useBridgeInitialization.d.ts +27 -1
  24. package/dist/shared/providers/shell/authProvider/useBridgeInitialization.js +82 -62
  25. package/dist/shared/providers/shell/authProvider/useRemoteSLO.d.ts +4 -1
  26. package/dist/shared/providers/shell/authProvider/useRemoteSLO.js +16 -14
  27. package/dist/shared/providers/shell/authProvider/useStorageSync.d.ts +4 -1
  28. package/dist/shared/providers/shell/authProvider/useStorageSync.js +19 -14
  29. package/dist/shared/providers/shell/contextSwitchCache.d.ts +4 -0
  30. package/dist/shared/providers/shell/contextSwitchCache.js +17 -0
  31. package/dist/shared/providers/shell/identityQueryReset.d.ts +17 -0
  32. package/dist/shared/providers/shell/identityQueryReset.js +21 -0
  33. package/dist/shared/providers/shell/identityScopedQueryReset.d.ts +16 -0
  34. package/dist/shared/providers/shell/identityScopedQueryReset.js +30 -0
  35. package/dist/shared/providers/shell/index.d.ts +1 -1
  36. package/dist/shared-events.js +29 -29
  37. package/dist/shared-graphql.js +11 -10
  38. package/dist/shared.js +129 -128
  39. package/package.json +2 -2
@@ -1,7 +1,9 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { ProfileUser, AuthTokens, ProfileMeta } from './ProfileStorageManager';
3
3
  import { AuthActions } from './authProvider/useAuthActions';
4
+ import { IdentityChangeReason } from './authProvider/identityChange';
4
5
  export type { ProfileUser as User, AuthTokens, ProfileMeta };
6
+ export type { IdentityChangeReason };
5
7
  export interface Account {
6
8
  id: string;
7
9
  email: string;
@@ -57,6 +59,17 @@ export interface AuthProviderProps {
57
59
  bridgeDebug?: boolean;
58
60
  /** Called when the auth bridge has finished initializing (responded or timed out) */
59
61
  onBridgeReady?: () => void;
62
+ /**
63
+ * BOFF-9384: called synchronously BEFORE React state moves to another
64
+ * account, by every path that changes it (sign-in, sign-out, account switch,
65
+ * sign-out of every account, remote single-logout, auth-bridge sync,
66
+ * cross-tab storage sync), and only when the account really changes. The
67
+ * first four also call it before they write storage; the background three
68
+ * call it once storage already names the next account. AppShellProvider
69
+ * empties its React Query cache here so the next account never reads the
70
+ * previous account's data.
71
+ */
72
+ onBeforeIdentityChange?: (reason: IdentityChangeReason) => void;
60
73
  }
61
- export declare function AuthProvider({ children, onTokenExpired, onSessionExpiringSoon, onRefreshToken, bridgeUrl, bridgeAllowedOrigins, bridgeDebug, onBridgeReady, }: AuthProviderProps): import('react/jsx-runtime').JSX.Element;
74
+ export declare function AuthProvider({ children, onTokenExpired, onSessionExpiringSoon, onRefreshToken, bridgeUrl, bridgeAllowedOrigins, bridgeDebug, onBridgeReady, onBeforeIdentityChange, }: AuthProviderProps): import('react/jsx-runtime').JSX.Element;
62
75
  export declare function useAuth(): AuthContextValue;
@@ -1,16 +1,17 @@
1
1
  import { getActiveProfileId as e, getProfileTokens as t, getProfileUser as n, getProfileWorkspaceToken as ee, getSwitchableProfiles as r, resolveActiveProfileId as te } from "./ProfileStorageManager.js";
2
2
  import { readShellSsoCookie as i } from "../../utils/authCookie.js";
3
- import { useBridgeInitialization as a } from "./authProvider/useBridgeInitialization.js";
4
- import { useTokenExpiryTimer as o } from "./authProvider/useTokenExpiryTimer.js";
5
- import { useStorageSync as ne } from "./authProvider/useStorageSync.js";
6
- import { useRemoteSLO as s } from "./authProvider/useRemoteSLO.js";
7
- import { useAuthActions as c } from "./authProvider/useAuthActions.js";
8
- import { useSsoDepositBootGuard as l } from "./authProvider/useSsoDepositBootGuard.js";
9
- import { createContext as u, use as d, useCallback as f, useMemo as p, useRef as m, useState as h } from "react";
10
- import { jsx as g } from "react/jsx-runtime";
3
+ import { identityKeyOf as a } from "./authProvider/identityChange.js";
4
+ import { useBridgeInitialization as o } from "./authProvider/useBridgeInitialization.js";
5
+ import { useTokenExpiryTimer as ne } from "./authProvider/useTokenExpiryTimer.js";
6
+ import { useStorageSync as re } from "./authProvider/useStorageSync.js";
7
+ import { useRemoteSLO as ie } from "./authProvider/useRemoteSLO.js";
8
+ import { useAuthActions as ae } from "./authProvider/useAuthActions.js";
9
+ import { useSsoDepositBootGuard as oe } from "./authProvider/useSsoDepositBootGuard.js";
10
+ import { createContext as s, use as c, useCallback as l, useLayoutEffect as se, useMemo as u, useRef as d, useState as f } from "react";
11
+ import { jsx as ce } from "react/jsx-runtime";
11
12
  //#region src/shared/providers/shell/AuthProvider.tsx
12
- var _ = u(null);
13
- function v(e) {
13
+ var p = s(null);
14
+ function m(e) {
14
15
  return r(e).map((t) => ({
15
16
  id: t.id,
16
17
  email: t.email,
@@ -20,130 +21,140 @@ function v(e) {
20
21
  lastLogin: t.lastLogin
21
22
  }));
22
23
  }
23
- function y({ children: r, onTokenExpired: u, onSessionExpiringSoon: d, onRefreshToken: y, bridgeUrl: b, bridgeAllowedOrigins: x, bridgeDebug: S, onBridgeReady: C }) {
24
- let w = m(!1), [T, E] = h(() => te()), [D, O] = h(() => T ? n(T) : null), [k, A] = h(() => T ? t(T) : null), [j, M] = h(() => T ? ee(T) : null), [N, P] = h(() => {
25
- if (T && n(T)) return !1;
26
- if (b) try {
24
+ function h({ children: r, onTokenExpired: s, onSessionExpiringSoon: c, onRefreshToken: h, bridgeUrl: g, bridgeAllowedOrigins: _, bridgeDebug: v, onBridgeReady: le, onBeforeIdentityChange: y }) {
25
+ let b = d(!1), [x, S] = f(() => te()), [C, w] = f(() => x ? n(x) : null), [T, E] = f(() => x ? t(x) : null), [D, O] = f(() => x ? ee(x) : null), [k, A] = f(() => {
26
+ if (x && n(x)) return !1;
27
+ if (g) try {
27
28
  let e = i()?.id ?? null;
28
29
  if (e && localStorage.getItem(`bf-p-${e}-tokens`)) return !1;
29
30
  } catch {}
30
- return !!b;
31
- }), [F, I] = h(!1), [L, re] = h(null), [R, z] = h(() => v(T)), B = f(() => {
32
- z([]);
33
- }, []), V = f(() => {
34
- z(v(e()));
31
+ return !!g;
32
+ }), [j, ue] = f(!1), [M, de] = f(null), [N, P] = f(() => m(x)), F = l(() => {
33
+ P([]);
34
+ }, []), I = l(() => {
35
+ P(m(e()));
36
+ }, []), L = a(x, C?.id), R = d(L), z = d(!1), B = d(y);
37
+ se(() => {
38
+ R.current = L, z.current = !1, B.current = y;
39
+ });
40
+ let V = l((e, t) => {
41
+ z.current || a(t.profileId, t.userId) !== R.current && (z.current = !0, B.current?.(e));
35
42
  }, []);
36
- a({
37
- bridgeUrl: b,
38
- bridgeAllowedOrigins: x,
39
- bridgeDebug: S,
40
- onBridgeReady: C,
41
- bridgeSyncInProgress: w,
42
- setIsLoading: P,
43
- setActiveId: E,
44
- setUser: O,
45
- setTokens: A,
46
- setWorkspaceTokenLocal: M,
47
- clearAccounts: B,
48
- refreshAccounts: V
43
+ o({
44
+ bridgeUrl: g,
45
+ bridgeAllowedOrigins: _,
46
+ bridgeDebug: v,
47
+ onBridgeReady: le,
48
+ bridgeSyncInProgress: b,
49
+ setIsLoading: A,
50
+ setActiveId: S,
51
+ setUser: w,
52
+ setTokens: E,
53
+ setWorkspaceTokenLocal: O,
54
+ clearAccounts: F,
55
+ refreshAccounts: I,
56
+ announceIdentityChange: V
49
57
  });
50
- let { login: H, logout: U, logoutAll: W, updateUser: G, refreshAccessToken: K, hasPermission: q, setWorkspaceToken: J, setMfaState: Y, switchAccount: X, addAccount: Z, removeAccount: Q } = c({
51
- user: D,
52
- tokens: k,
53
- activeId: T,
54
- bridgeSyncInProgress: w,
55
- onRefreshToken: y,
56
- onTokenExpired: u,
57
- setActiveId: E,
58
- setUser: O,
59
- setTokens: A,
60
- setWorkspaceTokenLocal: M,
61
- setMfaRequiredState: I,
62
- setMfaChallengeIdState: re,
63
- setIsLoading: P,
64
- clearAccounts: B,
65
- refreshAccounts: V
58
+ let { login: H, logout: U, logoutAll: W, updateUser: G, refreshAccessToken: K, hasPermission: q, setWorkspaceToken: J, setMfaState: Y, switchAccount: X, addAccount: Z, removeAccount: Q } = ae({
59
+ user: C,
60
+ tokens: T,
61
+ activeId: x,
62
+ bridgeSyncInProgress: b,
63
+ onRefreshToken: h,
64
+ onTokenExpired: s,
65
+ setActiveId: S,
66
+ setUser: w,
67
+ setTokens: E,
68
+ setWorkspaceTokenLocal: O,
69
+ setMfaRequiredState: ue,
70
+ setMfaChallengeIdState: de,
71
+ setIsLoading: A,
72
+ clearAccounts: F,
73
+ refreshAccounts: I,
74
+ announceIdentityChange: V
66
75
  });
67
- o({
68
- tokens: k,
69
- onRefreshToken: y,
70
- onTokenExpired: u,
71
- onSessionExpiringSoon: d,
76
+ ne({
77
+ tokens: T,
78
+ onRefreshToken: h,
79
+ onTokenExpired: s,
80
+ onSessionExpiringSoon: c,
72
81
  refreshAccessToken: K
73
- }), ne({
74
- user: D,
75
- tokens: k,
76
- workspaceToken: j,
77
- activeId: T,
78
- setUser: O,
79
- setTokens: A,
80
- setWorkspaceTokenLocal: M,
81
- setActiveId: E,
82
- clearAccounts: B,
83
- refreshAccounts: V
84
- }), l(), s({
85
- tokens: k,
86
- bridgeUrl: b,
82
+ }), re({
83
+ user: C,
84
+ tokens: T,
85
+ workspaceToken: D,
86
+ activeId: x,
87
+ setUser: w,
88
+ setTokens: E,
89
+ setWorkspaceTokenLocal: O,
90
+ setActiveId: S,
91
+ clearAccounts: F,
92
+ refreshAccounts: I,
93
+ announceIdentityChange: V
94
+ }), oe(), ie({
95
+ tokens: T,
96
+ bridgeUrl: g,
87
97
  logout: U,
88
- setActiveId: E,
89
- setUser: O,
90
- setTokens: A,
91
- setWorkspaceTokenLocal: M,
92
- clearAccounts: B
98
+ setActiveId: S,
99
+ setUser: w,
100
+ setTokens: E,
101
+ setWorkspaceTokenLocal: O,
102
+ clearAccounts: F,
103
+ announceIdentityChange: V
93
104
  });
94
- let $ = p(() => !!D && !!k, [D, k]), ie = p(() => ({
95
- user: D,
96
- tokens: k,
105
+ let $ = u(() => !!C && !!T, [C, T]), fe = u(() => ({
106
+ user: C,
107
+ tokens: T,
97
108
  isAuthenticated: $,
98
- isLoading: N,
109
+ isLoading: k,
99
110
  login: H,
100
111
  logout: U,
101
112
  updateUser: G,
102
113
  refreshAccessToken: K,
103
114
  hasPermission: q,
104
115
  setWorkspaceToken: J,
105
- workspaceToken: j,
106
- mfaRequired: F,
107
- mfaChallengeId: L,
116
+ workspaceToken: D,
117
+ mfaRequired: j,
118
+ mfaChallengeId: M,
108
119
  setMfaState: Y,
109
- activeProfileId: T,
110
- accounts: R,
120
+ activeProfileId: x,
121
+ accounts: N,
111
122
  switchAccount: X,
112
123
  addAccount: Z,
113
124
  removeAccount: Q,
114
125
  logoutAll: W,
115
- currentUser: D
126
+ currentUser: C
116
127
  }), [
117
- D,
118
- k,
128
+ C,
129
+ T,
119
130
  $,
120
- N,
131
+ k,
121
132
  H,
122
133
  U,
123
134
  G,
124
135
  K,
125
136
  q,
126
137
  J,
138
+ D,
127
139
  j,
128
- F,
129
- L,
140
+ M,
130
141
  Y,
131
- T,
132
- R,
142
+ x,
143
+ N,
133
144
  X,
134
145
  Z,
135
146
  Q,
136
147
  W
137
148
  ]);
138
- return /* @__PURE__ */ g(_.Provider, {
139
- value: ie,
149
+ return /* @__PURE__ */ ce(p.Provider, {
150
+ value: fe,
140
151
  children: r
141
152
  });
142
153
  }
143
- function b() {
144
- let e = d(_);
154
+ function g() {
155
+ let e = c(p);
145
156
  if (!e) throw Error("useAuth must be used within an AuthProvider");
146
157
  return e;
147
158
  }
148
159
  //#endregion
149
- export { y as AuthProvider, b as useAuth };
160
+ export { h as AuthProvider, g as useAuth };
@@ -1,5 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { Gateway } from '../../graphql/client';
3
+ import { WorkspaceOperationGuardMode } from '../../graphql/workspaceOperationGuard';
3
4
  export interface MultiGatewayProviderProps {
4
5
  children: ReactNode;
5
6
  /** Base URL for workspace gateway */
@@ -22,5 +23,11 @@ export interface MultiGatewayProviderProps {
22
23
  onNetworkError?: (error: Error) => void;
23
24
  /** Callback to attempt token refresh on 401 */
24
25
  onRefreshToken?: () => Promise<boolean>;
26
+ /**
27
+ * BOFF-8106: `'enforce'` refuses workspace operations built for a workspace
28
+ * that is no longer active, and a switch no longer re-sends them. Default
29
+ * `'off'`. See `CreateClientOptions.workspaceOperationGuard`.
30
+ */
31
+ workspaceOperationGuard?: WorkspaceOperationGuardMode;
25
32
  }
26
- export declare function MultiGatewayProvider({ children, workspaceBaseUrl, globalBaseUrl, organizationId, productSlug, defaultGateway, debug, enableSubscriptions, onAuthError, onNetworkError, onRefreshToken, }: MultiGatewayProviderProps): import('react/jsx-runtime').JSX.Element;
33
+ export declare function MultiGatewayProvider({ children, workspaceBaseUrl, globalBaseUrl, organizationId, productSlug, defaultGateway, debug, enableSubscriptions, onAuthError, onNetworkError, onRefreshToken, workspaceOperationGuard: workspaceOperationGuardProp, }: MultiGatewayProviderProps): import('react/jsx-runtime').JSX.Element;
@@ -1,34 +1,36 @@
1
1
  import { isCapacitorNative as e } from "../../native/capacitor.js";
2
2
  import { readActiveContextValueWithUrlPrecedence as t } from "./ActiveContextStorage.js";
3
- import { createGraphQLClient as n } from "../../graphql/client.js";
4
- import { GatewayProvider as r } from "../../graphql/GatewayContext.js";
5
- import { useAuthToken as i } from "./AuthTokenProvider.js";
6
- import { useCallback as a, useEffect as o, useMemo as s, useRef as c } from "react";
7
- import { jsx as l } from "react/jsx-runtime";
8
- import { ApolloProvider as u } from "@apollo/client/react";
3
+ import { normalizeWorkspaceOperationGuardMode as n, refetchActiveQueries as r } from "../../graphql/workspaceOperationGuard.js";
4
+ import { createGraphQLClient as i } from "../../graphql/client.js";
5
+ import { GatewayProvider as a } from "../../graphql/GatewayContext.js";
6
+ import { useAuthToken as o } from "./AuthTokenProvider.js";
7
+ import { evictForContextChange as s, refetchForContextChange as c } from "./contextSwitchCache.js";
8
+ import { useCallback as l, useEffect as u, useMemo as d, useRef as f } from "react";
9
+ import { jsx as p } from "react/jsx-runtime";
10
+ import { ApolloProvider as m } from "@apollo/client/react";
9
11
  //#region src/shared/providers/shell/MultiGatewayProvider.tsx
10
- function d({ children: d, workspaceBaseUrl: f, globalBaseUrl: p, organizationId: m, productSlug: h, defaultGateway: g = "workspace", debug: _ = !1, enableSubscriptions: v = !1, onAuthError: y, onNetworkError: b, onRefreshToken: x }) {
11
- let { getAccessToken: S, getWorkspaceToken: C, accessToken: w, workspaceToken: T } = i(), E = c({
12
+ function h({ children: h, workspaceBaseUrl: g, globalBaseUrl: _, organizationId: v, productSlug: y, defaultGateway: b = "workspace", debug: x = !1, enableSubscriptions: S = !1, onAuthError: C, onNetworkError: w, onRefreshToken: T, workspaceOperationGuard: E }) {
13
+ let D = n(E), { getAccessToken: O, getWorkspaceToken: k, accessToken: A, workspaceToken: j } = o(), M = f({
12
14
  workspaceClient: null,
13
15
  globalClient: null
14
- }), D = c(null), O = a(() => {
15
- D.current ||= setTimeout(() => {
16
- D.current = null;
17
- let e = E.current, t = [];
18
- e.workspaceClient && t.push(e.workspaceClient.refetchQueries({ include: "active" })), e.globalClient && t.push(e.globalClient.refetchQueries({ include: "active" })), t.length !== 0 && Promise.allSettled(t).then((e) => {
19
- if (!_) return;
16
+ }), N = f(null), P = l(() => {
17
+ N.current ||= setTimeout(() => {
18
+ N.current = null;
19
+ let e = M.current, n = [], i = () => t("workspace");
20
+ e.workspaceClient && n.push(r(e.workspaceClient, D, i)), e.globalClient && n.push(r(e.globalClient, D, i)), n.length !== 0 && Promise.allSettled(n).then((e) => {
21
+ if (!x) return;
20
22
  let t = e.filter((e) => e.status === "rejected");
21
23
  t.length > 0 && console.warn("[MultiGatewayProvider] Active query refresh failed after mutation", t);
22
24
  });
23
25
  }, 0);
24
- }, [_]), k = a(() => {
26
+ }, [x, D]), F = l(() => {
25
27
  let e = sessionStorage.getItem("bf-active-profile");
26
28
  if (e) {
27
29
  let t = localStorage.getItem(`bf-p-${e}-locale`);
28
30
  if (t) return t;
29
31
  }
30
32
  return localStorage.getItem("burdenoff-locale") || "en";
31
- }, []), A = a(() => {
33
+ }, []), I = l(() => {
32
34
  let e = sessionStorage.getItem("bf-active-profile");
33
35
  if (e) {
34
36
  let t = localStorage.getItem(`bf-p-${e}-geography`);
@@ -41,122 +43,116 @@ function d({ children: d, workspaceBaseUrl: f, globalBaseUrl: p, organizationId:
41
43
  return JSON.parse(t);
42
44
  } catch {}
43
45
  return null;
44
- }, []), j = a(() => t("workspace"), []), M = a(() => t("project"), []), N = s(() => n({
46
+ }, []), L = l(() => t("workspace"), []), R = l(() => t("project"), []), z = d(() => i({
45
47
  gateway: "workspace",
46
- baseUrl: f,
47
- authToken: S,
48
- workspaceToken: C,
49
- workspaceId: j,
50
- projectId: M,
51
- organizationId: m,
52
- productSlug: h,
53
- locale: k,
54
- geography: A,
55
- enableSubscriptions: v,
56
- debug: _,
57
- onAuthError: y,
58
- onRefreshToken: x,
59
- onNetworkError: b,
60
- onMutationSuccess: O
48
+ baseUrl: g,
49
+ authToken: O,
50
+ workspaceToken: k,
51
+ workspaceId: L,
52
+ projectId: R,
53
+ organizationId: v,
54
+ productSlug: y,
55
+ locale: F,
56
+ geography: I,
57
+ enableSubscriptions: S,
58
+ debug: x,
59
+ onAuthError: C,
60
+ onRefreshToken: T,
61
+ onNetworkError: w,
62
+ onMutationSuccess: P,
63
+ workspaceOperationGuard: D
61
64
  }), [
62
- f,
63
- S,
64
- C,
65
- j,
66
- M,
67
- m,
68
- h,
65
+ g,
66
+ O,
69
67
  k,
70
- A,
68
+ L,
69
+ R,
71
70
  v,
72
- _,
73
71
  y,
72
+ F,
73
+ I,
74
+ S,
74
75
  x,
75
- b,
76
- O
77
- ]), P = s(() => n({
76
+ C,
77
+ T,
78
+ w,
79
+ P,
80
+ D
81
+ ]), B = d(() => i({
78
82
  gateway: "global",
79
- baseUrl: p,
80
- authToken: S,
81
- workspaceToken: C,
82
- workspaceId: j,
83
- projectId: M,
84
- organizationId: m,
85
- productSlug: h,
86
- locale: k,
87
- geography: A,
88
- enableSubscriptions: v,
89
- debug: _,
90
- onAuthError: y,
91
- onRefreshToken: x,
92
- onNetworkError: b,
93
- onMutationSuccess: O
83
+ baseUrl: _,
84
+ authToken: O,
85
+ workspaceToken: k,
86
+ workspaceId: L,
87
+ projectId: R,
88
+ organizationId: v,
89
+ productSlug: y,
90
+ locale: F,
91
+ geography: I,
92
+ enableSubscriptions: S,
93
+ debug: x,
94
+ onAuthError: C,
95
+ onRefreshToken: T,
96
+ onNetworkError: w,
97
+ onMutationSuccess: P,
98
+ workspaceOperationGuard: D
94
99
  }), [
95
- p,
96
- S,
97
- C,
98
- j,
99
- M,
100
- m,
101
- h,
100
+ _,
101
+ O,
102
102
  k,
103
- A,
103
+ L,
104
+ R,
104
105
  v,
105
- _,
106
106
  y,
107
+ F,
108
+ I,
109
+ S,
107
110
  x,
108
- b,
109
- O
111
+ C,
112
+ T,
113
+ w,
114
+ P,
115
+ D
110
116
  ]);
111
- o(() => {
112
- E.current = {
113
- workspaceClient: N,
114
- globalClient: P
117
+ u(() => {
118
+ M.current = {
119
+ workspaceClient: z,
120
+ globalClient: B
115
121
  };
116
- }, [N, P]), o(() => {
117
- let e = D;
122
+ }, [z, B]), u(() => {
123
+ let e = N;
118
124
  return () => {
119
125
  e.current &&= (clearTimeout(e.current), null);
120
126
  };
121
127
  }, []);
122
- let F = a((e) => e === "workspace" ? E.current.workspaceClient ?? N : E.current.globalClient ?? P, [N, P]);
123
- return o(() => {
124
- _ && console.log("[MultiGatewayProvider] Tokens updated:", {
125
- hasAccessToken: !!w,
126
- hasWorkspaceToken: !!T
128
+ let V = l((e) => e === "workspace" ? M.current.workspaceClient ?? z : M.current.globalClient ?? B, [z, B]);
129
+ return u(() => {
130
+ x && console.log("[MultiGatewayProvider] Tokens updated:", {
131
+ hasAccessToken: !!A,
132
+ hasWorkspaceToken: !!j
127
133
  });
128
134
  }, [
129
- w,
130
- T,
131
- _
132
- ]), o(() => {
135
+ A,
136
+ j,
137
+ x
138
+ ]), u(() => {
133
139
  if (typeof window > "u") return;
134
140
  let e = async (e) => {
135
- _ && console.log("[MultiGatewayProvider] Context changed; evicting cache + refetching", e);
136
- try {
137
- N.cache.evict({ id: "ROOT_QUERY" }), N.cache.gc();
138
- } catch {}
139
- try {
140
- P.cache.evict({ id: "ROOT_QUERY" }), P.cache.gc();
141
- } catch {}
142
- try {
143
- await N.refetchQueries({ include: "active" });
144
- } catch {}
145
- try {
146
- await P.refetchQueries({ include: "active" });
147
- } catch {}
141
+ x && console.log("[MultiGatewayProvider] Context changed; evicting cache + refetching", e), s(z, D), s(B, D), await c(z, D, L), await c(B, D, L);
148
142
  };
149
143
  return window.addEventListener("burdenoff:workspace-changed", e), window.addEventListener("burdenoff:organization-changed", e), window.addEventListener("burdenoff:project-changed", e), () => {
150
144
  window.removeEventListener("burdenoff:workspace-changed", e), window.removeEventListener("burdenoff:organization-changed", e), window.removeEventListener("burdenoff:project-changed", e);
151
145
  };
152
146
  }, [
153
- N,
154
- P,
155
- _
156
- ]), o(() => {
157
- let t = N, n = P;
147
+ z,
148
+ B,
149
+ x,
150
+ D,
151
+ L
152
+ ]), u(() => {
153
+ let t = z, n = B;
158
154
  return () => {
159
- if (_ && console.log("[MultiGatewayProvider] Cleaning up Apollo clients"), !(typeof window < "u" && !e() && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1" || window.location.hostname.endsWith(".local.burdenoff.com")))) {
155
+ if (x && console.log("[MultiGatewayProvider] Cleaning up Apollo clients"), !(typeof window < "u" && !e() && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1" || window.location.hostname.endsWith(".local.burdenoff.com")))) {
160
156
  try {
161
157
  t.stop();
162
158
  } catch {}
@@ -166,24 +162,24 @@ function d({ children: d, workspaceBaseUrl: f, globalBaseUrl: p, organizationId:
166
162
  }
167
163
  };
168
164
  }, [
169
- N,
170
- P,
171
- _
172
- ]), /* @__PURE__ */ l(r, {
173
- value: s(() => ({
174
- workspaceClient: N,
175
- globalClient: P,
176
- getClient: F
165
+ z,
166
+ B,
167
+ x
168
+ ]), /* @__PURE__ */ p(a, {
169
+ value: d(() => ({
170
+ workspaceClient: z,
171
+ globalClient: B,
172
+ getClient: V
177
173
  }), [
178
- N,
179
- P,
180
- F
174
+ z,
175
+ B,
176
+ V
181
177
  ]),
182
- children: /* @__PURE__ */ l(u, {
183
- client: g === "workspace" ? N : P,
184
- children: d
178
+ children: /* @__PURE__ */ p(m, {
179
+ client: b === "workspace" ? z : B,
180
+ children: h
185
181
  })
186
182
  });
187
183
  }
188
184
  //#endregion
189
- export { d as MultiGatewayProvider };
185
+ export { h as MultiGatewayProvider };
@@ -206,4 +206,4 @@ function U(e) {
206
206
  return g().some((t) => t.id === e) ? (C(e), !0) : !1;
207
207
  }
208
208
  //#endregion
209
- export { s as PROFILE_STORAGE_CHANGE_EVENT, t as ProfileStorageManager_exports, y as addProfile, w as clearActiveProfileId, z as getActiveContext, S as getActiveProfileId, L as getActiveTokens, I as getActiveUser, R as getActiveWorkspaceToken, M as getProfileContext, P as getProfileLocale, O as getProfileTokens, E as getProfileUser, A as getProfileWorkspaceToken, p as getProfiles, _ as getSwitchableProfiles, B as loginProfile, V as logoutActiveProfile, H as logoutAllProfiles, x as removeAllProfiles, b as removeProfile, T as resolveActiveProfileId, C as setActiveProfileId, N as setProfileContext, F as setProfileLocale, k as setProfileTokens, D as setProfileUser, j as setProfileWorkspaceToken, v as setProfiles, U as switchProfile };
209
+ export { s as PROFILE_STORAGE_CHANGE_EVENT, t as ProfileStorageManager_exports, y as addProfile, w as clearActiveProfileId, z as getActiveContext, S as getActiveProfileId, L as getActiveTokens, I as getActiveUser, R as getActiveWorkspaceToken, M as getProfileContext, P as getProfileLocale, O as getProfileTokens, E as getProfileUser, A as getProfileWorkspaceToken, p as getProfiles, g as getSelectableProfiles, _ as getSwitchableProfiles, B as loginProfile, V as logoutActiveProfile, H as logoutAllProfiles, x as removeAllProfiles, b as removeProfile, T as resolveActiveProfileId, C as setActiveProfileId, N as setProfileContext, F as setProfileLocale, k as setProfileTokens, D as setProfileUser, j as setProfileWorkspaceToken, v as setProfiles, U as switchProfile };
@@ -0,0 +1,4 @@
1
+ export declare const WORKSPACE_WRITE_REFUSED_TOAST_ID = "burdenoff-workspace-write-refused";
2
+ export declare const WORKSPACE_WRITE_REFUSED_TOAST_DEDUPE_MS = 3000;
3
+ export declare const WORKSPACE_WRITE_REFUSED_I18N_KEY = "shell.workspaceChanged.notSaved";
4
+ export declare function WorkspaceWriteRefusedToastListener(): null;
@@ -0,0 +1,23 @@
1
+ import { WORKSPACE_WRITE_REFUSED_EVENT as e, WORKSPACE_WRITE_REFUSED_MESSAGE as t } from "../../graphql/workspaceOperationGuard.js";
2
+ import { useOptionalI18n as n } from "./I18nProvider.js";
3
+ import { useEffect as r, useRef as i } from "react";
4
+ import { toast as a } from "sonner";
5
+ //#region src/shared/providers/shell/WorkspaceWriteRefusedToastListener.tsx
6
+ var o = "burdenoff-workspace-write-refused", s = "shell.workspaceChanged.notSaved";
7
+ function c() {
8
+ let c = n(), l = c ? c.t(s, t) : t, u = i(l), d = i(null);
9
+ return r(() => {
10
+ u.current = l;
11
+ }, [l]), r(() => {
12
+ let t = () => {
13
+ let e = Date.now(), t = d.current;
14
+ t !== null && e - t < 3e3 || (d.current = e, a.warning(u.current, {
15
+ id: o,
16
+ duration: 7e3
17
+ }));
18
+ };
19
+ return window.addEventListener(e, t), () => window.removeEventListener(e, t);
20
+ }, []), null;
21
+ }
22
+ //#endregion
23
+ export { c as WorkspaceWriteRefusedToastListener };