@burdenoff/fe-libs 2026.1010.1 → 2026.1010.2
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.
- package/dist/shared/assistant/appControls/grammar.js +48 -41
- package/dist/shared/graphql/client.d.ts +20 -0
- package/dist/shared/graphql/client.js +196 -191
- package/dist/shared/graphql/retryPolicy.d.ts +27 -0
- package/dist/shared/graphql/retryPolicy.js +10 -0
- package/dist/shared/utils/apollo.d.ts +6 -2
- package/dist/shared/utils/apollo.js +26 -25
- package/package.json +2 -2
|
@@ -16,15 +16,15 @@ function c(e, t) {
|
|
|
16
16
|
for (let e of i.matchAll(r)) a = e[0];
|
|
17
17
|
return a ?? t;
|
|
18
18
|
}
|
|
19
|
-
var l = 60, u = /^(?:log ?out|sign ?out|(?:log|sign) (?:me )?out(?: of (?:the |my |this )?(?:app|application|account|session))?)$/, d = "(?:workspace|workspaces|context|contexts|organi[sz]ation|organi[sz]ations|org|project)", f = "(?:switcher|selector|picker|menu|dropdown|list)", p = /^(?:another|other|a different|different|a new|new|a|the|another one|other one)$/, m = RegExp(`^${i} ${r}(?:notification|notifications) (?:panel|bell|centre|center|menu|tray|drawer|list)$`), h = RegExp(`^${i} ${r}(?:notification )?bell$`),
|
|
19
|
+
var l = 60, u = /^(?:log ?out|sign ?out|(?:log|sign) (?:me )?out(?: of (?:the |my |this )?(?:app|application|account|session))?)$/, d = "(?:workspace|workspaces|context|contexts|organi[sz]ation|organi[sz]ations|org|project)", f = "(?:switcher|selector|picker|menu|dropdown|list)", p = /^(?:another|other|a different|different|a new|new|a|the|another one|other one)$/, m = RegExp(`^${i} ${r}(?:notification|notifications) (?:panel|bell|centre|center|menu|tray|drawer|list)$`), h = RegExp(`^${i} ${r}(?:notification )?bell$`), ee = RegExp(`^${i} ${r}notifications?$`), g = RegExp(`^${i} ${r}(?:help (?:menu|panel|dialog|dialogue|centre|center)|keyboard shortcuts|keyboard help|shortcuts)$`), _ = RegExp(`^${i} ${r}help$`), v = RegExp(`^(?:open|show|start|use|pull up|bring up) ${r}(?:global |app )search(?: (?:bar|box|dialog|dialogue|panel))?$|^(?:open|show|start|use|pull up|bring up) ${r}search (?:bar|box|dialog|dialogue|panel)$`), y = /^(?:open|start|use|pull up|bring up) (?:(?:the|my) )?search$/, b = [
|
|
20
20
|
/^(?:open|start|use|pull up|bring up) (?:(?:the|my) )?(?:global |app )?search (?:for|with) (.+)$/,
|
|
21
21
|
/^(?:global search|search everything|search everywhere|search globally|search the app|search all|search across the app) (?:for )?(.+)$/,
|
|
22
22
|
/^search (?:the app|everything|everywhere|globally|all|across the app) for (.+)$/
|
|
23
|
-
],
|
|
23
|
+
], x = "(?:side ?bar|side menu|side navigation|side nav|navigation (?:bar|menu|panel|drawer)|nav (?:bar|menu|panel|drawer)|left (?:menu|sidebar|panel))", S = RegExp(`^(?:collapse|close|hide|minimi[sz]e|shrink|fold) ${r}${x}$`), C = RegExp(`^(?:expand|open|show|reveal|unhide|bring up|widen|unfold) ${r}${x}$`), w = "(?: (?:group|section|menu|folder|submenu|sub menu|list|dropdown))?", T = RegExp(`^(expand|unfold|open up|open|show) ${r}(.+?)${w}$`), E = RegExp(`^(collapse|fold up|close|hide) ${r}(.+?)${w}$`), D = [
|
|
24
24
|
RegExp(`^(?:change|switch|set|update|turn|put|make)(?: over)? ${r}(?:(?:app|ui|user interface|interface|screen|display|site|system|menu|application) )?language (?:to|into|as|over to) (.+)$`),
|
|
25
25
|
RegExp(`^(?:switch|change|set|put|turn) ${r}(?:app|ui|user interface|interface|screen|display|site|application|menus?) (?:language )?(?:to|into) (.+)$`),
|
|
26
26
|
RegExp(`^(?:show|display|use|run) ${r}(?:app|ui|user interface|interface|screen|display|site|application)(?: menus?)? in (.+)$`)
|
|
27
|
-
], k = RegExp(`^${i} ${r}(?:(?:assistant|ai|conversation|conversations|chat) history|history of (?:my )?(?:conversations|chats)|(?:past|previous|old|earlier) conversations)$`), A = RegExp(`^${i} ${r}history$`), j = RegExp(`^${i} ${r}(?:voice|spoken|speech) transcript$`), M = RegExp(`^${i} ${r}transcript$`),
|
|
27
|
+
], O = RegExp(`^(?:switch|change)(?: over)? to ${r}(.+)$`), k = RegExp(`^${i} ${r}(?:(?:assistant|ai|conversation|conversations|chat) history|history of (?:my )?(?:conversations|chats)|(?:past|previous|old|earlier) conversations)$`), A = RegExp(`^${i} ${r}history$`), j = RegExp(`^${i} ${r}(?:voice|spoken|speech) transcript$`), M = RegExp(`^${i} ${r}transcript$`), N = RegExp(`^${i} ${r}(?:ai|assistant) preview(?: panel| pane| surface)?$`), P = RegExp(`^${i} ${r}preview(?: panel| pane)?$`), F = RegExp(`^(?:close|hide|dismiss) ${r}(?:ai|assistant) preview(?: panel| pane| surface)?$`), te = RegExp(`^(?:close|hide) ${r}preview(?: panel| pane)?$`), I = /^(?:(?:start|begin|open) (?:a |an |another )?(?:new |fresh |blank )?conversation|new conversation|(?:start|begin) (?:a )?(?:new|fresh) conversation with you)$/, L = [RegExp(`^(?:go to|open|show|show me|switch to|select|view|change to|move to|take me to|bring up) ${r}(.+) tab$`), /^(?:switch|change|move) tabs? to (.+)$/], R = "(?:filter|narrow|limit)(?: down)?", z = [RegExp(`^${R}(?: ${r}(?:page|list|table|results|items|rows|view))? (?:by|to|for|on) ${r}(.+)$`)], B = [/^(?:show|display|list|keep) only (.+)$/, /^only (?:show|display|list|keep) (.+)$/], V = [
|
|
28
28
|
RegExp(`^(?:set|change|switch|put|make) ${r}(.+?) filter (?:to|as|on) (.+)$`),
|
|
29
29
|
RegExp(`^${R} ${r}(.+?) (?:by|to|for|on) (.+)$`),
|
|
30
30
|
RegExp(`^(?:use|apply) ${r}(.+?) filter (?:of|with|for|set to) (.+)$`)
|
|
@@ -62,60 +62,60 @@ function $(e) {
|
|
|
62
62
|
let t = e.replace(/\b(?:please|pls)$/, "").trim();
|
|
63
63
|
return !t || t.length > l ? null : t;
|
|
64
64
|
}
|
|
65
|
-
function
|
|
66
|
-
let
|
|
65
|
+
function ne(s, l, x) {
|
|
66
|
+
let w = x.registered;
|
|
67
67
|
if (X.test(s)) return null;
|
|
68
|
-
if (
|
|
69
|
-
if (
|
|
68
|
+
if (w["account.logout"] && u.test(s)) return a({ control: "account.logout" });
|
|
69
|
+
if (w["header.workspace"] || w["header.context"]) {
|
|
70
70
|
let e = RegExp(`^(?:switch|change|move|go|jump|hop)(?: over)? to ${r}(.+?) ${d}$`).exec(s) ?? RegExp(`^(?:switch|change|move) ${r}${d} (?:to|over to) ${r}(.+)$`).exec(s);
|
|
71
|
-
if (e &&
|
|
71
|
+
if (e && w["header.workspace"]) {
|
|
72
72
|
let t = (e[1] ?? "").trim();
|
|
73
73
|
if (t && !p.test(t)) return a({
|
|
74
74
|
control: "header.workspace",
|
|
75
75
|
target: t
|
|
76
76
|
});
|
|
77
|
-
if (
|
|
77
|
+
if (w["header.context"]) return a({ control: "header.context" });
|
|
78
78
|
}
|
|
79
|
-
if (
|
|
79
|
+
if (w["header.context"] && (RegExp(`^${i} ${r}${d} ${f}$`).test(s) || RegExp(`^(?:switch|change) ${r}${d}$`).test(s))) return a({ control: "header.context" });
|
|
80
80
|
}
|
|
81
|
-
if (
|
|
81
|
+
if (w["header.notifications"]) {
|
|
82
82
|
if (m.test(s) || h.test(s)) return a({ control: "header.notifications" });
|
|
83
|
-
if (
|
|
83
|
+
if (ee.test(s)) return o({ control: "header.notifications" });
|
|
84
84
|
}
|
|
85
|
-
if (
|
|
86
|
-
if (
|
|
87
|
-
if (
|
|
85
|
+
if (w["header.help"]) {
|
|
86
|
+
if (g.test(s)) return a({ control: "header.help" });
|
|
87
|
+
if (_.test(s)) return o({ control: "header.help" });
|
|
88
88
|
}
|
|
89
|
-
if (
|
|
90
|
-
for (let e of
|
|
89
|
+
if (w["header.search"]) {
|
|
90
|
+
for (let e of b) {
|
|
91
91
|
let t = e.exec(s), n = t ? $(t[1] ?? "") : null;
|
|
92
92
|
if (n) return a({
|
|
93
93
|
control: "header.search",
|
|
94
94
|
query: c(l, n)
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
|
-
if (
|
|
97
|
+
if (v.test(s)) return a({
|
|
98
98
|
control: "header.search",
|
|
99
99
|
query: null
|
|
100
100
|
});
|
|
101
|
-
if (
|
|
101
|
+
if (y.test(s)) return o({
|
|
102
102
|
control: "header.search",
|
|
103
103
|
query: null
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
|
-
if (
|
|
107
|
-
if (
|
|
106
|
+
if (w.sidebar) {
|
|
107
|
+
if (S.test(s)) return a({
|
|
108
108
|
control: "sidebar",
|
|
109
109
|
collapsed: !0
|
|
110
110
|
});
|
|
111
|
-
if (
|
|
111
|
+
if (C.test(s)) return a({
|
|
112
112
|
control: "sidebar",
|
|
113
113
|
collapsed: !1
|
|
114
114
|
});
|
|
115
|
-
let e =
|
|
116
|
-
if (r &&
|
|
115
|
+
let e = T.exec(s), t = e ? null : E.exec(s), r = e ?? t;
|
|
116
|
+
if (r && x.sidebarEntries.length > 0) {
|
|
117
117
|
let t = (r[2] ?? "").trim(), i = r[1] ?? "";
|
|
118
|
-
if (t && n(t,
|
|
118
|
+
if (t && n(t, x.sidebarEntries).kind !== "none") return {
|
|
119
119
|
request: {
|
|
120
120
|
control: "sidebar.entry",
|
|
121
121
|
name: t,
|
|
@@ -125,31 +125,38 @@ function te(s, l, S) {
|
|
|
125
125
|
};
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
if (
|
|
129
|
-
let
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
128
|
+
if (w.language) {
|
|
129
|
+
for (let e of D) {
|
|
130
|
+
let n = e.exec(s);
|
|
131
|
+
if (!n) continue;
|
|
132
|
+
let r = t(n[1] ?? "");
|
|
133
|
+
if (r) return a({
|
|
134
|
+
control: "language",
|
|
135
|
+
code: r
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
let e = O.exec(s), n = e ? t(e[1] ?? "") : null;
|
|
139
|
+
if (n) return o({
|
|
133
140
|
control: "language",
|
|
134
|
-
code:
|
|
141
|
+
code: n
|
|
135
142
|
});
|
|
136
143
|
}
|
|
137
|
-
if (
|
|
144
|
+
if (w["assistant.history"]) {
|
|
138
145
|
if (k.test(s)) return a({ control: "assistant.history" });
|
|
139
146
|
if (A.test(s)) return o({ control: "assistant.history" });
|
|
140
147
|
}
|
|
141
|
-
if (
|
|
148
|
+
if (w["assistant.transcript"]) {
|
|
142
149
|
if (j.test(s)) return a({ control: "assistant.transcript" });
|
|
143
150
|
if (M.test(s)) return o({ control: "assistant.transcript" });
|
|
144
151
|
}
|
|
145
|
-
if (
|
|
146
|
-
if (
|
|
147
|
-
if (
|
|
148
|
-
if (
|
|
149
|
-
if (
|
|
152
|
+
if (w["assistant.preview"]) {
|
|
153
|
+
if (N.test(s)) return a({ control: "assistant.preview" });
|
|
154
|
+
if (P.test(s)) return o({ control: "assistant.preview" });
|
|
155
|
+
if (F.test(s)) return a({ control: "assistant.preview.close" });
|
|
156
|
+
if (te.test(s)) return o({ control: "assistant.preview.close" });
|
|
150
157
|
}
|
|
151
|
-
if (
|
|
152
|
-
let R =
|
|
158
|
+
if (w["assistant.conversation.new"] && I.test(s)) return a({ control: "assistant.conversation.new" });
|
|
159
|
+
let R = x.page;
|
|
153
160
|
if (!R) return null;
|
|
154
161
|
if (R.tabs.length > 0) {
|
|
155
162
|
let e = Z(L, s), t = e ? (e[1] ?? "").trim() : "";
|
|
@@ -235,4 +242,4 @@ function te(s, l, S) {
|
|
|
235
242
|
return null;
|
|
236
243
|
}
|
|
237
244
|
//#endregion
|
|
238
|
-
export {
|
|
245
|
+
export { ne as matchAppControl, c as queryAsSaid };
|
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
import { ApolloClient, InMemoryCache } from '@apollo/client/core';
|
|
2
|
+
import { RetryLink } from '@apollo/client/link/retry';
|
|
2
3
|
import { Gateway } from '../config';
|
|
4
|
+
import { RetryPolicyOperation } from './retryPolicy';
|
|
5
|
+
/**
|
|
6
|
+
* Decide whether the transport may retry a failed operation. Pure so it can be
|
|
7
|
+
* unit-tested without a client. Mutations are never retried (an ambiguous
|
|
8
|
+
* 504/timeout may have committed the write; a replay could duplicate it) unless
|
|
9
|
+
* the operation context sets `retryMutation: true`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function shouldRetryOperationError(error: Error | undefined | null, operation: RetryPolicyOperation | undefined, circuitOpen: boolean): boolean;
|
|
12
|
+
export interface CreateRetryLinkOptions {
|
|
13
|
+
maxAttempts: number;
|
|
14
|
+
/** Backoff override (tests); defaults to 1s..8s with jitter. */
|
|
15
|
+
delay?: {
|
|
16
|
+
initial: number;
|
|
17
|
+
max: number;
|
|
18
|
+
jitter: boolean;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Shared RetryLink: transient-failure retries for queries only (mutations opt in). */
|
|
22
|
+
export declare function createRetryLink({ maxAttempts, delay }: CreateRetryLinkOptions): RetryLink;
|
|
3
23
|
/**
|
|
4
24
|
* Check if the network circuit breaker is currently open (backend unreachable).
|
|
5
25
|
* Useful for showing "backend offline" banners in the UI.
|
|
@@ -1,97 +1,116 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
1
|
+
import { isOperationRetryable as e } from "./retryPolicy.js";
|
|
2
|
+
import { GATEWAYS as t, getGatewayUrl as n } from "../../shared-config.js";
|
|
3
|
+
import { validateGatewayBaseUrl as r } from "./security.js";
|
|
4
|
+
import { isWorkspaceTokenValidForContext as i } from "./workspaceToken.js";
|
|
5
|
+
import { dispatchBackendErrorEvent as a, markConnectionHealthy as o } from "../utils/backendErrors.js";
|
|
6
|
+
import { clearGraphqlFetchResponseCache as s, enqueueGraphQLFetch as c, ensureWorkspaceToken as l } from "./fetch.js";
|
|
7
|
+
import { SSELink as u } from "./links/sse-link.js";
|
|
8
|
+
import { onError as d } from "@apollo/client/link/error";
|
|
9
|
+
import { RetryLink as f } from "@apollo/client/link/retry";
|
|
10
|
+
import { setContext as p } from "@apollo/client/link/context";
|
|
11
|
+
import { ApolloClient as m, ApolloLink as h, InMemoryCache as ee, Observable as g, from as te, split as _ } from "@apollo/client/core";
|
|
12
|
+
import { getMainDefinition as v } from "@apollo/client/utilities";
|
|
13
|
+
import { print as y } from "graphql";
|
|
13
14
|
//#region src/shared/graphql/client.ts
|
|
14
|
-
var
|
|
15
|
+
var b = {
|
|
15
16
|
consecutiveFailures: 0,
|
|
16
17
|
lastFailureTime: 0,
|
|
17
18
|
isOpen: !1,
|
|
18
19
|
openCount: 0,
|
|
19
20
|
nextRetryTime: 0
|
|
20
|
-
},
|
|
21
|
-
function
|
|
22
|
-
if (
|
|
23
|
-
|
|
24
|
-
let e = Math.min(
|
|
25
|
-
|
|
21
|
+
}, x = 20, S = 5e3, C = 3e4;
|
|
22
|
+
function ne() {
|
|
23
|
+
if (b.consecutiveFailures++, b.lastFailureTime = Date.now(), !b.isOpen && b.consecutiveFailures >= x) {
|
|
24
|
+
b.isOpen = !0, b.openCount++;
|
|
25
|
+
let e = Math.min(S * 2 ** (b.openCount - 1), C);
|
|
26
|
+
b.nextRetryTime = Date.now() + e;
|
|
26
27
|
}
|
|
27
|
-
return
|
|
28
|
+
return b.isOpen;
|
|
29
|
+
}
|
|
30
|
+
function w() {
|
|
31
|
+
b.consecutiveFailures = 0, b.isOpen = !1, b.openCount = 0, b.nextRetryTime = 0, o();
|
|
28
32
|
}
|
|
29
|
-
function
|
|
30
|
-
|
|
33
|
+
function re() {
|
|
34
|
+
return !(!b.isOpen || Date.now() >= b.nextRetryTime);
|
|
31
35
|
}
|
|
32
|
-
function
|
|
33
|
-
|
|
36
|
+
function T(t, n, r) {
|
|
37
|
+
if (r || !t) return !1;
|
|
38
|
+
let i = t.message?.toLowerCase?.() ?? "";
|
|
39
|
+
return !(i.includes("401") || i.includes("403") || i.includes("unauthorized") || i.includes("forbidden") || i.includes("unauthenticated") || !e(n));
|
|
34
40
|
}
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
function ie({ maxAttempts: e, delay: t }) {
|
|
42
|
+
return new f({
|
|
43
|
+
delay: t ?? {
|
|
44
|
+
initial: 1e3,
|
|
45
|
+
max: 8e3,
|
|
46
|
+
jitter: !0
|
|
47
|
+
},
|
|
48
|
+
attempts: {
|
|
49
|
+
max: e,
|
|
50
|
+
retryIf: (e, t) => T(e, t, re())
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
var E = /(?:\b40[13]\b|status code 40[13]|unauthori[sz]ed|unauthenticated|forbidden|invalid email or password)/i;
|
|
55
|
+
function D(e) {
|
|
37
56
|
return typeof e == "number" && Number.isInteger(e) ? e : typeof e == "string" && /^\d{3}$/.test(e) ? Number(e) : null;
|
|
38
57
|
}
|
|
39
|
-
function
|
|
58
|
+
function ae(e) {
|
|
40
59
|
let t = /* @__PURE__ */ new Set(), n = (e, r) => {
|
|
41
60
|
if (r > 3 || e == null || t.has(e)) return !1;
|
|
42
|
-
if (typeof e == "string") return
|
|
61
|
+
if (typeof e == "string") return E.test(e);
|
|
43
62
|
if (typeof e != "object") return !1;
|
|
44
63
|
t.add(e);
|
|
45
|
-
let i = e, a =
|
|
64
|
+
let i = e, a = D(i.status) ?? D(i.statusCode) ?? D(i.response?.status);
|
|
46
65
|
if (a === 401 || a === 403) return !0;
|
|
47
66
|
let o = i.message;
|
|
48
|
-
return typeof o == "string" &&
|
|
67
|
+
return typeof o == "string" && E.test(o) ? !0 : n(i.cause, r + 1);
|
|
49
68
|
};
|
|
50
69
|
return n(e, 0);
|
|
51
70
|
}
|
|
52
|
-
function
|
|
71
|
+
function oe(e) {
|
|
53
72
|
if (!e || typeof e != "object") return null;
|
|
54
73
|
let t = e, n = t.workspaceId || t.input?.workspaceId;
|
|
55
74
|
return typeof n == "string" && n.trim() ? n : null;
|
|
56
75
|
}
|
|
57
|
-
function
|
|
76
|
+
function se(e) {
|
|
58
77
|
if (!e || typeof e != "object") return null;
|
|
59
78
|
let t = e.projectId;
|
|
60
79
|
return typeof t == "string" && t.trim() ? t : null;
|
|
61
80
|
}
|
|
62
|
-
function
|
|
63
|
-
let t =
|
|
81
|
+
function ce(e) {
|
|
82
|
+
let t = v(e);
|
|
64
83
|
return t.kind === "OperationDefinition" && t.operation === "mutation";
|
|
65
84
|
}
|
|
66
|
-
function
|
|
85
|
+
function le(e) {
|
|
67
86
|
let t = e.errors;
|
|
68
87
|
return Array.isArray(t) && t.length > 0;
|
|
69
88
|
}
|
|
70
|
-
function
|
|
89
|
+
function O(e) {
|
|
71
90
|
let t = e.headers;
|
|
72
91
|
if (!t || typeof t != "object" || Array.isArray(t)) return {};
|
|
73
92
|
let n = {};
|
|
74
93
|
for (let [e, r] of Object.entries(t)) typeof r == "string" && (n[e] = r);
|
|
75
94
|
return n;
|
|
76
95
|
}
|
|
77
|
-
function
|
|
96
|
+
function k(e) {
|
|
78
97
|
let t = e.fetchOptions;
|
|
79
98
|
if (!t || typeof t != "object" || !("signal" in t)) return;
|
|
80
99
|
let n = t.signal;
|
|
81
100
|
return n instanceof AbortSignal ? n : void 0;
|
|
82
101
|
}
|
|
83
|
-
function
|
|
84
|
-
return new
|
|
85
|
-
let a = r.getContext(), o = { query:
|
|
102
|
+
function ue({ uri: e, batchMax: t, batchInterval: n }) {
|
|
103
|
+
return new h((r) => new g((i) => {
|
|
104
|
+
let a = r.getContext(), o = { query: y(r.query) };
|
|
86
105
|
r.operationName && (o.operationName = r.operationName);
|
|
87
|
-
let
|
|
88
|
-
Object.keys(
|
|
106
|
+
let s = r.variables ?? {}, l = r.extensions ?? {};
|
|
107
|
+
Object.keys(s).length > 0 && (o.variables = s), Object.keys(l).length > 0 && (o.extensions = l);
|
|
89
108
|
let u = !1;
|
|
90
|
-
return
|
|
109
|
+
return c(e, {
|
|
91
110
|
"content-type": "application/json",
|
|
92
111
|
"Apollo-Require-Preflight": "true",
|
|
93
|
-
...
|
|
94
|
-
}, o,
|
|
112
|
+
...O(a)
|
|
113
|
+
}, o, k(a), {
|
|
95
114
|
batchMax: t,
|
|
96
115
|
batchInterval: n
|
|
97
116
|
}).then((e) => {
|
|
@@ -103,136 +122,122 @@ function le({ uri: e, batchMax: t, batchInterval: n }) {
|
|
|
103
122
|
};
|
|
104
123
|
}));
|
|
105
124
|
}
|
|
106
|
-
function
|
|
107
|
-
let { gateway:
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
gateway:
|
|
125
|
+
function A(e) {
|
|
126
|
+
let { gateway: o, baseUrl: c, authToken: f, workspaceToken: y, locale: x, geography: S, organizationId: C, productId: T, productSlug: E, workspaceId: D, projectId: O, tenantId: k, cache: A, enableSubscriptions: j = !1, sseUrl: M, onAuthError: N, onRefreshToken: P, onNetworkError: F, onNetworkStatusChange: I, onMutationSuccess: L, maxRetryAttempts: de = 3, batchMax: fe = 10, batchInterval: pe, debug: R = !1 } = e, z = null, B = null, me = (e) => {
|
|
127
|
+
B ||= setTimeout(() => {
|
|
128
|
+
B = null, z && z.refetchQueries({ include: "active" }).catch((t) => {
|
|
129
|
+
R && console.warn("[GraphQL] Active query refresh failed after mutation:", {
|
|
130
|
+
gateway: o,
|
|
112
131
|
operationName: e,
|
|
113
132
|
error: t
|
|
114
133
|
});
|
|
115
134
|
});
|
|
116
135
|
}, 0);
|
|
117
|
-
},
|
|
118
|
-
uri:
|
|
119
|
-
batchMax:
|
|
120
|
-
batchInterval:
|
|
121
|
-
}),
|
|
122
|
-
let n = t.headers ?? {}, r = typeof
|
|
136
|
+
}, V = t[o], H = r(n(c, o)), he = ue({
|
|
137
|
+
uri: H,
|
|
138
|
+
batchMax: fe,
|
|
139
|
+
batchInterval: pe
|
|
140
|
+
}), U = p((e, t) => {
|
|
141
|
+
let n = t.headers ?? {}, r = typeof f == "function" ? f() : f;
|
|
123
142
|
return { headers: {
|
|
124
143
|
...n,
|
|
125
144
|
...r ? { authorization: `Bearer ${r}` } : {}
|
|
126
145
|
} };
|
|
127
|
-
}),
|
|
146
|
+
}), W = p((e, t) => {
|
|
128
147
|
let n = t.headers ?? {}, r = typeof x == "function" ? x() : x;
|
|
129
148
|
return { headers: {
|
|
130
149
|
...n,
|
|
131
150
|
...r ? { "accept-language": r } : {}
|
|
132
151
|
} };
|
|
133
|
-
}),
|
|
134
|
-
let n = t.headers ?? {}, r = typeof
|
|
152
|
+
}), G = p((e, t) => {
|
|
153
|
+
let n = t.headers ?? {}, r = typeof S == "function" ? S() : null;
|
|
135
154
|
return { headers: {
|
|
136
155
|
...n,
|
|
137
156
|
...r?.country ? { "x-geo-country": r.country } : {},
|
|
138
157
|
...r?.currency ? { "x-geo-currency": r.currency } : {},
|
|
139
158
|
...r?.timezone ? { "x-geo-timezone": r.timezone } : {}
|
|
140
159
|
} };
|
|
141
|
-
}),
|
|
142
|
-
let n = t.headers ?? {}, r = typeof
|
|
160
|
+
}), K = p((e, t) => {
|
|
161
|
+
let n = t.headers ?? {}, r = typeof C == "function" ? C() : C;
|
|
143
162
|
return { headers: {
|
|
144
163
|
...n,
|
|
145
164
|
...r ? { "x-org-id": r } : {}
|
|
146
165
|
} };
|
|
147
|
-
}),
|
|
148
|
-
let n = t.headers ?? {}, r = typeof
|
|
166
|
+
}), q = p((e, t) => {
|
|
167
|
+
let n = t.headers ?? {}, r = typeof T == "function" ? T() : T, i = typeof E == "function" ? E() : E;
|
|
149
168
|
return { headers: {
|
|
150
169
|
...n,
|
|
151
170
|
...r ? { "x-product-id": r } : {},
|
|
152
171
|
...i ? { "x-product-slug": i } : {}
|
|
153
172
|
} };
|
|
154
|
-
}),
|
|
155
|
-
let n = t.headers ?? {}, r = (typeof
|
|
173
|
+
}), J = p((e, t) => {
|
|
174
|
+
let n = t.headers ?? {}, r = (typeof D == "function" ? D() : D) || oe(e.variables);
|
|
156
175
|
return { headers: {
|
|
157
176
|
...n,
|
|
158
177
|
...r ? { "x-workspace-id": r } : {}
|
|
159
178
|
} };
|
|
160
|
-
}),
|
|
161
|
-
let n = t.headers ?? {}, r = (typeof
|
|
179
|
+
}), Y = p((e, t) => {
|
|
180
|
+
let n = t.headers ?? {}, r = (typeof O == "function" ? O() : O) || se(e.variables);
|
|
162
181
|
return { headers: {
|
|
163
182
|
...n,
|
|
164
183
|
...r ? { "x-project-id": r } : {}
|
|
165
184
|
} };
|
|
166
|
-
}),
|
|
167
|
-
let n = t.headers ?? {}, r = typeof
|
|
185
|
+
}), ge = p((e, t) => {
|
|
186
|
+
let n = t.headers ?? {}, r = typeof k == "function" ? k() : k;
|
|
168
187
|
return { headers: {
|
|
169
188
|
...n,
|
|
170
189
|
...r ? { "x-tenant-id": r } : {}
|
|
171
190
|
} };
|
|
172
|
-
}),
|
|
173
|
-
let
|
|
174
|
-
if (
|
|
175
|
-
let
|
|
191
|
+
}), X = p(async (e, t) => {
|
|
192
|
+
let r = t.headers ?? {}, a = t.requiredWorkspaceAuth === !0;
|
|
193
|
+
if (o === "global" && !a) return { headers: r };
|
|
194
|
+
let s = typeof f == "function" ? f() : f, c = typeof y == "function" ? y() : y, u = typeof D == "function" ? D() : D, d = typeof C == "function" ? C() : C, p = typeof k == "function" ? k() : k, m = typeof O == "function" ? O() : O, h = i(c, {
|
|
176
195
|
workspaceId: u,
|
|
177
196
|
organizationId: d,
|
|
178
|
-
tenantId:
|
|
179
|
-
projectId:
|
|
180
|
-
}) ?
|
|
181
|
-
if (a &&
|
|
197
|
+
tenantId: p,
|
|
198
|
+
projectId: m
|
|
199
|
+
}) ? c : null;
|
|
200
|
+
if (a && t.requiredWorkspaceId && t.requiredWorkspaceId !== u) throw Error("The active workspace changed; retry the request");
|
|
182
201
|
if (a && !u) throw Error("Workspace authentication requires an active workspace");
|
|
183
|
-
if (!
|
|
184
|
-
let
|
|
185
|
-
if (
|
|
186
|
-
let
|
|
187
|
-
url:
|
|
188
|
-
authToken:
|
|
202
|
+
if (!h && (o === "workspace" || a)) try {
|
|
203
|
+
let t = typeof f == "function" ? f() : f;
|
|
204
|
+
if (t) {
|
|
205
|
+
let r = await Promise.race([l({
|
|
206
|
+
url: o === "workspace" ? H : n(void 0, "workspace"),
|
|
207
|
+
authToken: t,
|
|
189
208
|
workspaceId: u ?? void 0,
|
|
190
209
|
organizationId: d ?? void 0,
|
|
191
|
-
projectId:
|
|
210
|
+
projectId: m ?? void 0,
|
|
192
211
|
currentQuery: e.operationName ?? ""
|
|
193
212
|
}), new Promise((e) => setTimeout(() => e(null), 4e3))]);
|
|
194
|
-
r
|
|
213
|
+
i(r, {
|
|
195
214
|
workspaceId: u,
|
|
196
215
|
organizationId: d,
|
|
197
|
-
tenantId:
|
|
198
|
-
projectId:
|
|
199
|
-
}) && (
|
|
216
|
+
tenantId: p,
|
|
217
|
+
projectId: m
|
|
218
|
+
}) && (h = r);
|
|
200
219
|
}
|
|
201
220
|
} catch {}
|
|
202
221
|
if (a) {
|
|
203
|
-
if (!
|
|
204
|
-
if (
|
|
222
|
+
if (!h) throw Error("Workspace authentication is unavailable; retry the request");
|
|
223
|
+
if (s !== (typeof f == "function" ? f() : f) || u !== (typeof D == "function" ? D() : D) || d !== (typeof C == "function" ? C() : C) || m !== (typeof O == "function" ? O() : O) || p !== (typeof k == "function" ? k() : k)) throw Error("The active workspace changed; retry the request");
|
|
205
224
|
}
|
|
206
225
|
return { headers: {
|
|
207
|
-
...
|
|
208
|
-
...
|
|
226
|
+
...r,
|
|
227
|
+
...h ? { "x-workspace-authorization": `Bearer ${h}` } : {}
|
|
209
228
|
} };
|
|
210
|
-
}), ve = new
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
max
|
|
214
|
-
|
|
215
|
-
},
|
|
216
|
-
attempts: {
|
|
217
|
-
max: ue,
|
|
218
|
-
retryIf: (e) => {
|
|
219
|
-
if (C() || !e) return !1;
|
|
220
|
-
let t = e.message?.toLowerCase?.() ?? "";
|
|
221
|
-
return !(t.includes("401") || t.includes("403") || t.includes("unauthorized") || t.includes("forbidden") || t.includes("unauthenticated"));
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}), ye = new m((e, t) => {
|
|
225
|
-
if (C()) {
|
|
226
|
-
z && console.warn("[CircuitBreaker] Circuit is open, blocking request:", e.operationName);
|
|
227
|
-
let t = Math.max(0, Math.ceil((v.nextRetryTime - Date.now()) / 1e3)), n = /* @__PURE__ */ Error(`Network circuit breaker is open — backend appears unreachable. Retrying in ${t} seconds.`);
|
|
228
|
-
return I?.(n), new h((e) => {
|
|
229
|
+
}), _e = ie({ maxAttempts: de }), ve = new h((e, t) => {
|
|
230
|
+
if (re()) {
|
|
231
|
+
R && console.warn("[CircuitBreaker] Circuit is open, blocking request:", e.operationName);
|
|
232
|
+
let t = Math.max(0, Math.ceil((b.nextRetryTime - Date.now()) / 1e3)), n = /* @__PURE__ */ Error(`Network circuit breaker is open — backend appears unreachable. Retrying in ${t} seconds.`);
|
|
233
|
+
return F?.(n), new g((e) => {
|
|
229
234
|
e.error(n);
|
|
230
235
|
});
|
|
231
236
|
}
|
|
232
|
-
return new
|
|
237
|
+
return new g((n) => {
|
|
233
238
|
let r = t(e).subscribe({
|
|
234
239
|
next: (e) => {
|
|
235
|
-
|
|
240
|
+
w(), b.consecutiveFailures === 0 && I?.(!1), n.next(e);
|
|
236
241
|
},
|
|
237
242
|
error: (e) => {
|
|
238
243
|
n.error(e);
|
|
@@ -245,16 +250,16 @@ function O(a) {
|
|
|
245
250
|
r.unsubscribe();
|
|
246
251
|
};
|
|
247
252
|
});
|
|
248
|
-
}),
|
|
249
|
-
function
|
|
250
|
-
|
|
253
|
+
}), Z = !1, Q = [];
|
|
254
|
+
function $(e) {
|
|
255
|
+
Q.forEach(({ resolve: t }) => t(e)), Q = [];
|
|
251
256
|
}
|
|
252
|
-
let
|
|
257
|
+
let ye = d(({ error: e, operation: t, forward: n }) => {
|
|
253
258
|
let r = e.errors;
|
|
254
259
|
if (r) {
|
|
255
|
-
let
|
|
256
|
-
for (let e of r)
|
|
257
|
-
|
|
260
|
+
let i = r.some((e) => e.extensions?.code === "UNAUTHENTICATED" || e.message.includes("Unauthorized") || e.message.includes("Unauthenticated"));
|
|
261
|
+
for (let e of r) R && console.error("[GraphQL Error]:", e.message);
|
|
262
|
+
i && P || a({ errors: r }, { operationName: t.operationName });
|
|
258
263
|
let o = new Set(["STORAGE_QUOTA_EXCEEDED", "RESOURCE_CAP_EXCEEDED"]);
|
|
259
264
|
for (let e of r) {
|
|
260
265
|
let t = e.extensions?.code;
|
|
@@ -263,65 +268,65 @@ function O(a) {
|
|
|
263
268
|
break;
|
|
264
269
|
}
|
|
265
270
|
}
|
|
266
|
-
if (
|
|
271
|
+
if (i && P) return new g((r) => {
|
|
267
272
|
(async () => {
|
|
268
|
-
if (
|
|
269
|
-
|
|
273
|
+
if (Z) if (await new Promise((e) => {
|
|
274
|
+
Q.push({ resolve: e });
|
|
270
275
|
})) {
|
|
271
276
|
let e = n(t).subscribe(r);
|
|
272
277
|
return () => e.unsubscribe();
|
|
273
|
-
} else return
|
|
274
|
-
|
|
278
|
+
} else return N?.(), r.error(e), () => {};
|
|
279
|
+
Z = !0;
|
|
275
280
|
try {
|
|
276
|
-
let i = await
|
|
277
|
-
if (
|
|
278
|
-
|
|
281
|
+
let i = await P();
|
|
282
|
+
if (Z = !1, i) {
|
|
283
|
+
$(!0);
|
|
279
284
|
let e = n(t).subscribe(r);
|
|
280
285
|
return () => e.unsubscribe();
|
|
281
|
-
} else return
|
|
286
|
+
} else return $(!1), N?.(), r.error(e), () => {};
|
|
282
287
|
} catch {
|
|
283
|
-
return
|
|
288
|
+
return Z = !1, $(!1), N?.(), r.error(e), () => {};
|
|
284
289
|
}
|
|
285
290
|
})();
|
|
286
291
|
});
|
|
287
|
-
|
|
292
|
+
i && N?.(), w();
|
|
288
293
|
} else {
|
|
289
|
-
if (
|
|
290
|
-
|
|
294
|
+
if (R && console.error("[Network Error]:", e), ae(e)) {
|
|
295
|
+
w(), e instanceof Error && a(e, {
|
|
291
296
|
operationName: t.operationName,
|
|
292
297
|
fallbackMessage: "Your session is no longer valid. Please sign in again."
|
|
293
298
|
});
|
|
294
299
|
return;
|
|
295
300
|
}
|
|
296
|
-
if (
|
|
301
|
+
if (ne() && I?.(!0), e instanceof Error) F?.(e), a(e, {
|
|
297
302
|
operationName: t.operationName,
|
|
298
303
|
fallbackMessage: "We could not reach the server. Please check your connection and try again."
|
|
299
304
|
});
|
|
300
305
|
else {
|
|
301
306
|
let n = Error(String(e));
|
|
302
|
-
|
|
307
|
+
F?.(n), a(n, {
|
|
303
308
|
operationName: t.operationName,
|
|
304
309
|
fallbackMessage: "We could not reach the server. Please check your connection and try again."
|
|
305
310
|
});
|
|
306
311
|
}
|
|
307
312
|
}
|
|
308
|
-
}),
|
|
309
|
-
let n =
|
|
310
|
-
return new
|
|
313
|
+
}), be = new h((e, t) => {
|
|
314
|
+
let n = ce(e.query), r = n && e.getContext().autoRefreshAfterMutation !== !1 && e.getContext().skipMutationAutoRefresh !== !0;
|
|
315
|
+
return new g((i) => {
|
|
311
316
|
let a = t(e).subscribe({
|
|
312
317
|
next: (t) => {
|
|
313
|
-
if (i.next(t),
|
|
318
|
+
if (i.next(t), le(t) || (n && s(), !r)) return;
|
|
314
319
|
let a = e.operationName || "anonymous mutation";
|
|
315
|
-
|
|
316
|
-
gateway:
|
|
320
|
+
L ? Promise.resolve(L({
|
|
321
|
+
gateway: o,
|
|
317
322
|
operationName: a
|
|
318
323
|
})).catch((e) => {
|
|
319
|
-
|
|
320
|
-
gateway:
|
|
324
|
+
R && console.warn("[GraphQL] Mutation refresh callback failed:", {
|
|
325
|
+
gateway: o,
|
|
321
326
|
operationName: a,
|
|
322
327
|
error: e
|
|
323
328
|
});
|
|
324
|
-
}) :
|
|
329
|
+
}) : me(a);
|
|
325
330
|
},
|
|
326
331
|
error: (e) => {
|
|
327
332
|
i.error(e);
|
|
@@ -334,51 +339,51 @@ function O(a) {
|
|
|
334
339
|
a.unsubscribe();
|
|
335
340
|
};
|
|
336
341
|
});
|
|
337
|
-
}),
|
|
342
|
+
}), xe = te([
|
|
343
|
+
_e,
|
|
338
344
|
ve,
|
|
339
345
|
ye,
|
|
340
346
|
be,
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
_e,
|
|
344
|
-
J,
|
|
345
|
-
me,
|
|
346
|
-
he,
|
|
347
|
-
ge,
|
|
348
|
-
Y,
|
|
347
|
+
U,
|
|
348
|
+
X,
|
|
349
349
|
K,
|
|
350
350
|
q,
|
|
351
|
-
|
|
352
|
-
|
|
351
|
+
J,
|
|
352
|
+
Y,
|
|
353
|
+
ge,
|
|
354
|
+
W,
|
|
355
|
+
G,
|
|
356
|
+
_(({ query: e }) => {
|
|
357
|
+
let t = v(e);
|
|
353
358
|
return t.kind === "OperationDefinition" && t.operation === "subscription";
|
|
354
|
-
}, new
|
|
359
|
+
}, new h((e) => new g((t) => {
|
|
355
360
|
t.error(/* @__PURE__ */ Error(`[graphql] Refusing to send subscription "${e.operationName ?? "anonymous"}" over the batched HTTP transport — this gateway client was created without enableSubscriptions/SSE. Enable subscriptions on this client so it routes over SSE.`));
|
|
356
|
-
})),
|
|
361
|
+
})), he)
|
|
357
362
|
]);
|
|
358
|
-
if (
|
|
359
|
-
let e =
|
|
360
|
-
t && (
|
|
363
|
+
if (j) {
|
|
364
|
+
let e = V.sse, t = M || (e ? r(c || V.defaultBaseUrl) + e : void 0);
|
|
365
|
+
t && (xe = te([
|
|
366
|
+
_e,
|
|
361
367
|
ve,
|
|
362
368
|
ye,
|
|
363
369
|
be,
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
_e,
|
|
367
|
-
J,
|
|
368
|
-
me,
|
|
369
|
-
he,
|
|
370
|
-
ge,
|
|
371
|
-
Y,
|
|
370
|
+
U,
|
|
371
|
+
X,
|
|
372
372
|
K,
|
|
373
373
|
q,
|
|
374
|
-
|
|
375
|
-
|
|
374
|
+
J,
|
|
375
|
+
Y,
|
|
376
|
+
ge,
|
|
377
|
+
W,
|
|
378
|
+
G,
|
|
379
|
+
_(({ query: e }) => {
|
|
380
|
+
let t = v(e);
|
|
376
381
|
return t.kind === "OperationDefinition" && t.operation === "subscription";
|
|
377
|
-
}, new
|
|
382
|
+
}, new u({
|
|
378
383
|
url: t,
|
|
379
384
|
headers: {},
|
|
380
|
-
debug:
|
|
381
|
-
}),
|
|
385
|
+
debug: R
|
|
386
|
+
}), he)
|
|
382
387
|
]));
|
|
383
388
|
}
|
|
384
389
|
let Se = new ee({ typePolicies: {
|
|
@@ -416,9 +421,9 @@ function O(a) {
|
|
|
416
421
|
VibecontrolsAgent: { keyFields: ["id"] },
|
|
417
422
|
Query: { fields: { vibes: { keyArgs: ["filter"] } } }
|
|
418
423
|
} });
|
|
419
|
-
return
|
|
420
|
-
link:
|
|
421
|
-
cache:
|
|
424
|
+
return z = new m({
|
|
425
|
+
link: xe,
|
|
426
|
+
cache: A ?? Se,
|
|
422
427
|
defaultOptions: {
|
|
423
428
|
watchQuery: {
|
|
424
429
|
fetchPolicy: "cache-and-network",
|
|
@@ -430,19 +435,19 @@ function O(a) {
|
|
|
430
435
|
},
|
|
431
436
|
mutate: { errorPolicy: "all" }
|
|
432
437
|
}
|
|
433
|
-
}),
|
|
438
|
+
}), z;
|
|
434
439
|
}
|
|
435
|
-
var
|
|
436
|
-
function
|
|
440
|
+
var j = null, M = null;
|
|
441
|
+
function N(e) {
|
|
437
442
|
let { workspaceBaseUrl: t, globalBaseUrl: n, authToken: r, enableSubscriptions: i = !1, onAuthError: a, debug: o = !1 } = e;
|
|
438
|
-
|
|
443
|
+
j = A({
|
|
439
444
|
gateway: "workspace",
|
|
440
445
|
baseUrl: t,
|
|
441
446
|
authToken: r,
|
|
442
447
|
enableSubscriptions: i,
|
|
443
448
|
onAuthError: a,
|
|
444
449
|
debug: o
|
|
445
|
-
}),
|
|
450
|
+
}), M = A({
|
|
446
451
|
gateway: "global",
|
|
447
452
|
baseUrl: n,
|
|
448
453
|
authToken: r,
|
|
@@ -450,16 +455,16 @@ function j(e) {
|
|
|
450
455
|
debug: o
|
|
451
456
|
});
|
|
452
457
|
}
|
|
453
|
-
function
|
|
454
|
-
if (!
|
|
455
|
-
return
|
|
458
|
+
function P() {
|
|
459
|
+
if (!j) throw Error("Workspace client not initialized. Call initializeAppClients first.");
|
|
460
|
+
return j;
|
|
456
461
|
}
|
|
457
|
-
function
|
|
458
|
-
if (!
|
|
459
|
-
return
|
|
462
|
+
function F() {
|
|
463
|
+
if (!M) throw Error("Global client not initialized. Call initializeAppClients first.");
|
|
464
|
+
return M;
|
|
460
465
|
}
|
|
461
|
-
function
|
|
462
|
-
|
|
466
|
+
function I() {
|
|
467
|
+
j &&= (j.clearStore(), null), M &&= (M.clearStore(), null);
|
|
463
468
|
}
|
|
464
469
|
//#endregion
|
|
465
|
-
export {
|
|
470
|
+
export { A as createGraphQLClient, F as getGlobalClient, P as getWorkspaceClient, N as initializeAppClients, I as resetAppClients };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { DocumentNode } from 'graphql';
|
|
2
|
+
/**
|
|
3
|
+
* Operation-context key that explicitly opts a MUTATION in to automatic
|
|
4
|
+
* transport-level retries. Nothing opts in today.
|
|
5
|
+
*
|
|
6
|
+
* A mutation can change server state even when the response never arrives
|
|
7
|
+
* (a 504 / dropped connection is ambiguous: the write may have committed).
|
|
8
|
+
* Replaying it blindly can duplicate or silently re-apply the write, so the
|
|
9
|
+
* shared retry links never retry mutations unless the caller sets
|
|
10
|
+
* `context: { retryMutation: true }` AND guarantees the mutation is idempotent
|
|
11
|
+
* (for example a keyed upsert). Callers that need recovery from an ambiguous
|
|
12
|
+
* failure should reconcile explicitly (read the state back) instead.
|
|
13
|
+
*/
|
|
14
|
+
export declare const RETRY_MUTATION_CONTEXT_KEY = "retryMutation";
|
|
15
|
+
/** The minimal operation surface the retry policy needs (ApolloLink.Operation fits). */
|
|
16
|
+
export interface RetryPolicyOperation {
|
|
17
|
+
query: DocumentNode;
|
|
18
|
+
getContext: () => Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
/** True when any operation definition in the document is a mutation. */
|
|
21
|
+
export declare function isMutationOperation(operation: Pick<RetryPolicyOperation, 'query'>): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Whether the transport may replay this operation after a failure. Queries and
|
|
24
|
+
* subscriptions are replayable; mutations only with an explicit
|
|
25
|
+
* `retryMutation: true` context opt-in.
|
|
26
|
+
*/
|
|
27
|
+
export declare function isOperationRetryable(operation: RetryPolicyOperation | undefined): boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/shared/graphql/retryPolicy.ts
|
|
2
|
+
var e = "retryMutation";
|
|
3
|
+
function t(e) {
|
|
4
|
+
return e.query.definitions.some((e) => e.kind === "OperationDefinition" && e.operation === "mutation");
|
|
5
|
+
}
|
|
6
|
+
function n(n) {
|
|
7
|
+
return !n || !t(n) ? !0 : n.getContext()[e] === !0;
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { n as isOperationRetryable };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ApolloClient, InMemoryCache } from '@apollo/client';
|
|
2
|
+
import { RetryPolicyOperation } from '../graphql/retryPolicy';
|
|
2
3
|
export interface CreateApolloClientOptions {
|
|
3
4
|
uri: string;
|
|
4
5
|
getAuthToken?: () => string | null | undefined;
|
|
@@ -15,11 +16,14 @@ export declare function withBrowserTraceHeader(headersInit?: HeadersInit): Heade
|
|
|
15
16
|
*
|
|
16
17
|
* Retries any unrecognised error (default-true) so genuine transient
|
|
17
18
|
* network / 5xx failures still benefit from the link's retry budget;
|
|
18
|
-
* permanent failures are filtered via three signals, in order
|
|
19
|
+
* permanent failures are filtered via three signals, in order.
|
|
20
|
+
* Mutations are never retried (an ambiguous 5xx/timeout may have committed the
|
|
21
|
+
* write) unless the operation context sets `retryMutation: true`.
|
|
22
|
+
* Signals:
|
|
19
23
|
* 1. Numeric `statusCode` (Apollo Client 4's `ServerError`)
|
|
20
24
|
* 2. `errors[].extensions.code` (GraphQL response auth codes)
|
|
21
25
|
* 3. Substring match on `message` (fallback for link errors that
|
|
22
26
|
* surface auth codes only in their message string)
|
|
23
27
|
*/
|
|
24
|
-
export declare function shouldRetryApolloError(error: unknown): boolean;
|
|
28
|
+
export declare function shouldRetryApolloError(error: unknown, operation?: RetryPolicyOperation): boolean;
|
|
25
29
|
export declare function createApolloClient(options: CreateApolloClientOptions): ApolloClient;
|
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
import { createBrowserTraceContext as e } from "../events/metadata.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { isOperationRetryable as t } from "../graphql/retryPolicy.js";
|
|
3
|
+
import { ApolloClient as n, InMemoryCache as r, from as i } from "@apollo/client";
|
|
4
|
+
import { BatchHttpLink as a } from "@apollo/client/link/batch-http";
|
|
5
|
+
import { onError as o } from "@apollo/client/link/error";
|
|
6
|
+
import { RetryLink as s } from "@apollo/client/link/retry";
|
|
7
|
+
import { setContext as c } from "@apollo/client/link/context";
|
|
7
8
|
//#region src/shared/utils/apollo.ts
|
|
8
|
-
function
|
|
9
|
+
function l(t) {
|
|
9
10
|
let n = new Headers(t);
|
|
10
11
|
return n.has("traceparent") || n.set("traceparent", e().traceparent), n;
|
|
11
12
|
}
|
|
12
|
-
var
|
|
13
|
+
var u = new Set([
|
|
13
14
|
401,
|
|
14
15
|
403,
|
|
15
16
|
413
|
|
16
17
|
]);
|
|
17
|
-
function
|
|
18
|
-
if (!e) return !1;
|
|
19
|
-
let
|
|
20
|
-
if (typeof
|
|
21
|
-
let
|
|
22
|
-
return !(
|
|
18
|
+
function d(e, n) {
|
|
19
|
+
if (!e || !t(n)) return !1;
|
|
20
|
+
let r = e.statusCode;
|
|
21
|
+
if (typeof r == "number" && u.has(r) || e.errors?.some((e) => e.extensions?.code === "UNAUTHENTICATED" || e.extensions?.code === "FORBIDDEN")) return !1;
|
|
22
|
+
let i = e.message;
|
|
23
|
+
return !(i && /UNAUTHENTICATED|FORBIDDEN/.test(i));
|
|
23
24
|
}
|
|
24
|
-
function
|
|
25
|
-
let { uri:
|
|
25
|
+
function f(e) {
|
|
26
|
+
let { uri: t, getAuthToken: u, onAuthError: f, onNetworkError: p, cache: m = new r(), retryAttempts: h = 3, retryDelay: g = 1e3 } = e, _ = new s({
|
|
26
27
|
delay: {
|
|
27
28
|
initial: g,
|
|
28
29
|
max: g * 4,
|
|
@@ -30,15 +31,15 @@ function d(e) {
|
|
|
30
31
|
},
|
|
31
32
|
attempts: {
|
|
32
33
|
max: h,
|
|
33
|
-
retryIf:
|
|
34
|
+
retryIf: d
|
|
34
35
|
}
|
|
35
|
-
}), v =
|
|
36
|
+
}), v = o(({ error: e }) => {
|
|
36
37
|
let t = e.errors;
|
|
37
38
|
t ? t.forEach((e) => {
|
|
38
39
|
console.error(`[GraphQL error]: Message: ${e.message}, Location: ${JSON.stringify(e.locations)}, Path: ${e.path}`), e.extensions?.code === "UNAUTHENTICATED" && f?.();
|
|
39
40
|
}) : e && (console.error(`[Network error]: ${e.message}`), p?.(e));
|
|
40
|
-
}), y =
|
|
41
|
-
let n =
|
|
41
|
+
}), y = c((e, { headers: t }) => {
|
|
42
|
+
let n = u?.();
|
|
42
43
|
console.log("[fe-libs apollo] getAuthToken returned:", n ? n.substring(0, 20) + "..." : "null");
|
|
43
44
|
let r = { headers: {
|
|
44
45
|
...t,
|
|
@@ -47,15 +48,15 @@ function d(e) {
|
|
|
47
48
|
return console.log("[fe-libs apollo] Authorization header:", r.headers.authorization ? r.headers.authorization.substring(0, 30) + "..." : "MISSING"), r;
|
|
48
49
|
}), b = fetch, x = ((e, t) => fetch(e, {
|
|
49
50
|
...t,
|
|
50
|
-
headers:
|
|
51
|
+
headers: l(t?.headers)
|
|
51
52
|
}));
|
|
52
|
-
return b.preconnect && (x.preconnect = b.preconnect), new
|
|
53
|
-
link:
|
|
53
|
+
return b.preconnect && (x.preconnect = b.preconnect), new n({
|
|
54
|
+
link: i([
|
|
54
55
|
_,
|
|
55
56
|
v,
|
|
56
57
|
y,
|
|
57
|
-
new
|
|
58
|
-
uri:
|
|
58
|
+
new a({
|
|
59
|
+
uri: t,
|
|
59
60
|
credentials: "include",
|
|
60
61
|
batchMax: 10,
|
|
61
62
|
batchInterval: 100,
|
|
@@ -77,4 +78,4 @@ function d(e) {
|
|
|
77
78
|
});
|
|
78
79
|
}
|
|
79
80
|
//#endregion
|
|
80
|
-
export {
|
|
81
|
+
export { f as createApolloClient };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/fe-libs",
|
|
3
|
-
"version": "2026.1010.
|
|
3
|
+
"version": "2026.1010.2",
|
|
4
4
|
"description": "Burdenoff frontend primitives and domain libraries",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -314,7 +314,7 @@
|
|
|
314
314
|
"test:package-css-exports": "node scripts/validate-package-css-exports.mjs",
|
|
315
315
|
"verify:package": "node scripts/verify-package-contents.mjs",
|
|
316
316
|
"test:handsfree-browser": "node scripts/handsfree-browser-run.mjs",
|
|
317
|
-
"test": "bun test scripts/graphql-schema-drift/__tests__ scripts/a11y-audit/__tests__ src/credentials src/connections src/storage src/shared/assistant src/shared/components src/shared/graphql/links/sse-link.test.ts src/shared/graphql/fetch.test.ts src/shared/graphql/tourWorkspaceAuth.test.ts src/shared/config/gatewayUrls.test.ts src/shared/config/authBridgeUrls.test.ts src/shared/config/gatewayFallback.test.ts scripts/__tests__ src/shared/config/products.test.ts src/shared/config/productSlug.test.ts src/shared/hooks/shell/useProducts.test.ts src/shared/providers/shell/brandAttribute.test.ts src/chrome/ProductSwitcher.test.ts src/shared/utils/gatewayFetchRewrite.test.ts src/shared/utils/authCookie.test.ts src/shared/providers/AppShellProvider.test.ts src/shared/providers/shell/interpolate.test.ts src/shared/providers/shell/resolveTranslation.test.ts src/shared/providers/shell/I18nProvider.render.test.tsx src/shared/providers/shell/I18nProvider.client.test.tsx src/shared/providers/shell/translationStore.test.ts src/shared/providers/shell/translationLayers.test.ts src/shared/providers/shell/directionMode.test.ts src/shared/providers/shell/authProvider/ssoRelay.test.ts src/shared/providers/shell/personaSurfaceRemote.test.ts src/shared/providers/shell/workspaceSwitch.client.test.tsx src/shared/events/sinks/RybbitSink.test.ts src/shell-native src/shared/native src/shared/navigation src/shared/tours src/chrome/__tests__ src/ui/__tests__",
|
|
317
|
+
"test": "bun test scripts/graphql-schema-drift/__tests__ scripts/a11y-audit/__tests__ src/credentials src/connections src/storage src/shared/assistant src/shared/components src/shared/graphql/links/sse-link.test.ts src/shared/graphql/fetch.test.ts src/shared/graphql/client.test.ts src/shared/utils/apollo.test.ts src/shared/graphql/tourWorkspaceAuth.test.ts src/shared/config/gatewayUrls.test.ts src/shared/config/authBridgeUrls.test.ts src/shared/config/gatewayFallback.test.ts scripts/__tests__ src/shared/config/products.test.ts src/shared/config/productSlug.test.ts src/shared/hooks/shell/useProducts.test.ts src/shared/providers/shell/brandAttribute.test.ts src/chrome/ProductSwitcher.test.ts src/shared/utils/gatewayFetchRewrite.test.ts src/shared/utils/authCookie.test.ts src/shared/providers/AppShellProvider.test.ts src/shared/providers/shell/interpolate.test.ts src/shared/providers/shell/resolveTranslation.test.ts src/shared/providers/shell/I18nProvider.render.test.tsx src/shared/providers/shell/I18nProvider.client.test.tsx src/shared/providers/shell/translationStore.test.ts src/shared/providers/shell/translationLayers.test.ts src/shared/providers/shell/directionMode.test.ts src/shared/providers/shell/authProvider/ssoRelay.test.ts src/shared/providers/shell/personaSurfaceRemote.test.ts src/shared/providers/shell/workspaceSwitch.client.test.tsx src/shared/events/sinks/RybbitSink.test.ts src/shell-native src/shared/native src/shared/navigation src/shared/tours src/chrome/__tests__ src/ui/__tests__",
|
|
318
318
|
"sanity": "bash scripts/build-limits.sh --gate bash -c 'bun run lint:sanity && bun run format && bun run type:check && bun run test && bun run build && bun run verify:package'",
|
|
319
319
|
"switch:status": "bun scripts/deps-mode.ts status",
|
|
320
320
|
"switch:remote": "bun scripts/deps-mode.ts remote",
|