@plumile/relay 0.2.6 → 0.2.8
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/README.md
CHANGED
|
@@ -11,6 +11,12 @@ after `401`; this transport owns multipart encoding, timeouts, and retries for
|
|
|
11
11
|
network, `408`, `429`, and `5xx` failures. It does not patch
|
|
12
12
|
`globalThis.fetch`.
|
|
13
13
|
|
|
14
|
+
`getAuthHeaders(signal?)` receives the same operation signal across HTTP retries.
|
|
15
|
+
An error from this provider rejects the operation with the original error before
|
|
16
|
+
sending any request, and is never retried as a network failure. The signal is
|
|
17
|
+
omitted for WebSocket authentication. Existing callbacks without a parameter
|
|
18
|
+
remain supported.
|
|
19
|
+
|
|
14
20
|
Relay query disposal aborts the active HTTP attempt and the complete retry
|
|
15
21
|
lifecycle, including a pending backoff. Disposed operations never publish a
|
|
16
22
|
late response or error to their observer.
|
package/lib/esm/environment.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isDevEnv as e } from "./envHelpers.js";
|
|
2
2
|
import { Environment as t, Network as n, Observable as r, RecordSource as i, Store as a } from "relay-runtime";
|
|
3
3
|
//#region src/environment.ts
|
|
4
|
-
var o = "/api/graphql", s = "/api/ws", c, l, u = 0, d = /* @__PURE__ */ new Set(), f, p = async (e, t) => globalThis.fetch(e, t), m = p, h, ee = "require-preflight",
|
|
5
|
-
if (!
|
|
4
|
+
var o = "/api/graphql", s = "/api/ws", c, l, u = 0, d = /* @__PURE__ */ new Set(), f, p = async (e, t) => globalThis.fetch(e, t), m = p, h, ee = "require-preflight", te = "true", ne = (e) => typeof e == "object" && !!e && !Array.isArray(e), g = (e) => {
|
|
5
|
+
if (!ne(e) || typeof e.type != "string") return {
|
|
6
6
|
ok: !1,
|
|
7
7
|
reason: "invalid"
|
|
8
8
|
};
|
|
@@ -61,63 +61,63 @@ var o = "/api/graphql", s = "/api/ws", c, l, u = 0, d = /* @__PURE__ */ new Set(
|
|
|
61
61
|
reason: "unsupported"
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
|
-
},
|
|
64
|
+
}, re = "graphql-transport-ws", ie = 5e3, ae = 1e4, oe = 10, se = 500, _ = "Relay operation cancelled after environment rotation", v = {
|
|
65
65
|
generation: 0,
|
|
66
66
|
reason: null,
|
|
67
67
|
status: "idle"
|
|
68
|
-
},
|
|
68
|
+
}, y = /* @__PURE__ */ new Set(), b = {
|
|
69
69
|
generation: 0,
|
|
70
70
|
pendingCount: 0,
|
|
71
71
|
pendingOperations: []
|
|
72
|
-
},
|
|
73
|
-
function
|
|
74
|
-
var
|
|
75
|
-
e() && (
|
|
72
|
+
}, x = 0, S = /* @__PURE__ */ new Map(), C = /* @__PURE__ */ new Set(), w = !1;
|
|
73
|
+
function T() {}
|
|
74
|
+
var E = T;
|
|
75
|
+
e() && (E = (e) => {
|
|
76
76
|
console.log("relayFieldLogger: ", e);
|
|
77
77
|
});
|
|
78
|
-
var
|
|
78
|
+
var D = (e) => {
|
|
79
79
|
if (typeof e != "object" || !e) return null;
|
|
80
80
|
let { id: t } = e;
|
|
81
81
|
return typeof t != "string" || t.trim() === "" ? null : t;
|
|
82
|
-
},
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
generation:
|
|
82
|
+
}, O = (e, t) => h?.(e, t) ?? D(e, t);
|
|
83
|
+
function k(e, t) {
|
|
84
|
+
v = {
|
|
85
|
+
generation: v.generation + 1,
|
|
86
86
|
reason: t,
|
|
87
87
|
status: e
|
|
88
88
|
};
|
|
89
|
-
for (let e of
|
|
90
|
-
}
|
|
91
|
-
function
|
|
92
|
-
|
|
93
|
-
generation:
|
|
94
|
-
pendingCount:
|
|
95
|
-
pendingOperations: [...
|
|
96
|
-
}, !
|
|
97
|
-
|
|
98
|
-
for (let e of
|
|
89
|
+
for (let e of y) e();
|
|
90
|
+
}
|
|
91
|
+
function A() {
|
|
92
|
+
b = {
|
|
93
|
+
generation: b.generation + 1,
|
|
94
|
+
pendingCount: S.size,
|
|
95
|
+
pendingOperations: [...S.values()]
|
|
96
|
+
}, !w && (w = !0, queueMicrotask(() => {
|
|
97
|
+
w = !1;
|
|
98
|
+
for (let e of C) e();
|
|
99
99
|
}));
|
|
100
100
|
}
|
|
101
|
-
function
|
|
102
|
-
|
|
101
|
+
function ce() {
|
|
102
|
+
S.size !== 0 && (S.clear(), A());
|
|
103
103
|
}
|
|
104
|
-
function
|
|
104
|
+
function le(e) {
|
|
105
105
|
return e === "query" || e === "mutation" ? e : "unknown";
|
|
106
106
|
}
|
|
107
|
-
function
|
|
108
|
-
let t =
|
|
109
|
-
|
|
107
|
+
function ue(e) {
|
|
108
|
+
let t = x;
|
|
109
|
+
x += 1, S.set(t, {
|
|
110
110
|
id: t,
|
|
111
|
-
kind:
|
|
111
|
+
kind: le(e.operationKind),
|
|
112
112
|
name: e.name ?? "AnonymousGraphQLOperation",
|
|
113
113
|
startedAt: Date.now()
|
|
114
|
-
}),
|
|
114
|
+
}), A();
|
|
115
115
|
let n = !1;
|
|
116
116
|
return () => {
|
|
117
|
-
n || (n = !0,
|
|
117
|
+
n || (n = !0, S.delete(t) && A());
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
|
-
function
|
|
120
|
+
function de() {
|
|
121
121
|
if (l != null) {
|
|
122
122
|
try {
|
|
123
123
|
l.dispose();
|
|
@@ -125,7 +125,7 @@ function ue() {
|
|
|
125
125
|
l = void 0;
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
function
|
|
128
|
+
function fe() {
|
|
129
129
|
if (l != null) {
|
|
130
130
|
try {
|
|
131
131
|
l.terminate();
|
|
@@ -133,11 +133,11 @@ function de() {
|
|
|
133
133
|
l = void 0;
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
-
function
|
|
137
|
-
for (let e of d) e.abort(/* @__PURE__ */ Error(
|
|
136
|
+
function pe() {
|
|
137
|
+
for (let e of d) e.abort(/* @__PURE__ */ Error(_));
|
|
138
138
|
d.clear();
|
|
139
139
|
}
|
|
140
|
-
function
|
|
140
|
+
function me(e) {
|
|
141
141
|
let t = e.getStore(), n = t.getSource(), r = new i();
|
|
142
142
|
for (let e of n.getRecordIDs()) r.delete(e);
|
|
143
143
|
try {
|
|
@@ -146,33 +146,33 @@ function pe(e) {
|
|
|
146
146
|
n instanceof i && n.clear();
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
|
-
function
|
|
149
|
+
function j(e, t) {
|
|
150
150
|
let n = c;
|
|
151
|
-
c = void 0, u += 1,
|
|
151
|
+
c = void 0, u += 1, pe(), fe();
|
|
152
152
|
try {
|
|
153
|
-
n != null &&
|
|
153
|
+
n != null && me(n);
|
|
154
154
|
} finally {
|
|
155
|
-
|
|
155
|
+
ce(), k(e, t);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
|
-
function
|
|
159
|
-
return
|
|
158
|
+
function he() {
|
|
159
|
+
return v;
|
|
160
160
|
}
|
|
161
|
-
function
|
|
162
|
-
return
|
|
163
|
-
|
|
161
|
+
function ge(e) {
|
|
162
|
+
return y.add(e), () => {
|
|
163
|
+
y.delete(e);
|
|
164
164
|
};
|
|
165
165
|
}
|
|
166
|
-
function
|
|
167
|
-
return
|
|
166
|
+
function M() {
|
|
167
|
+
return b;
|
|
168
168
|
}
|
|
169
169
|
function N(e) {
|
|
170
|
-
return
|
|
171
|
-
|
|
170
|
+
return C.add(e), () => {
|
|
171
|
+
C.delete(e);
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
174
|
function P(e = {}) {
|
|
175
|
-
|
|
175
|
+
de(), k("reconnecting", e.reason ?? "manual_reconnect");
|
|
176
176
|
}
|
|
177
177
|
async function F(e = {}) {
|
|
178
178
|
let t = l;
|
|
@@ -180,9 +180,9 @@ async function F(e = {}) {
|
|
|
180
180
|
}
|
|
181
181
|
function I(e = {}) {
|
|
182
182
|
let { httpUrl: t, wsUrl: n, logEvents: r, getDataId: i, getAuthHeaders: a, fetchImpl: c } = e;
|
|
183
|
-
typeof t == "string" && t !== "" && (o = t), typeof n == "string" && n !== "" && (s = n), r != null && (
|
|
183
|
+
typeof t == "string" && t !== "" && (o = t), typeof n == "string" && n !== "" && (s = n), r != null && (E = r ? (e) => {
|
|
184
184
|
console.log("relayFieldLogger: ", e);
|
|
185
|
-
} :
|
|
185
|
+
} : T), h = i, f = a, m = c ?? p, j("configured", "configure");
|
|
186
186
|
}
|
|
187
187
|
function _e() {
|
|
188
188
|
let e = s;
|
|
@@ -254,7 +254,7 @@ var z = class {
|
|
|
254
254
|
return Object.keys(t).length !== 0 && new Promise((e) => {
|
|
255
255
|
let n = setTimeout(() => {
|
|
256
256
|
this.pendingAuthUpdate = null, e(!1);
|
|
257
|
-
},
|
|
257
|
+
}, ie);
|
|
258
258
|
this.pendingAuthUpdate = {
|
|
259
259
|
resolve: e,
|
|
260
260
|
timeout: n
|
|
@@ -295,7 +295,7 @@ var z = class {
|
|
|
295
295
|
n || (n = !0, e());
|
|
296
296
|
}, i = (e) => {
|
|
297
297
|
n || (n = !0, t(e));
|
|
298
|
-
}, a = new WebSocket(this.url,
|
|
298
|
+
}, a = new WebSocket(this.url, re);
|
|
299
299
|
this.socket = a, this.acknowledged = !1, a.onopen = () => {
|
|
300
300
|
R().catch(() => ({})).then((e) => {
|
|
301
301
|
if (a.readyState === WebSocket.OPEN) {
|
|
@@ -328,7 +328,7 @@ var z = class {
|
|
|
328
328
|
n(/* @__PURE__ */ Error("Invalid GraphQL websocket message")), this.socket?.close(4400, "Invalid websocket message");
|
|
329
329
|
return;
|
|
330
330
|
}
|
|
331
|
-
let i =
|
|
331
|
+
let i = g(r);
|
|
332
332
|
if (!i.ok) {
|
|
333
333
|
let e = i.reason === "unsupported", t = "Invalid GraphQL websocket message", r = "Invalid websocket message";
|
|
334
334
|
e && (t = "Unsupported GraphQL websocket message", r = "Unsupported websocket message"), n(Error(t)), this.socket?.close(4400, r);
|
|
@@ -361,12 +361,12 @@ var z = class {
|
|
|
361
361
|
this.acknowledged = !1, this.socket = null, this.connectPromise = null, this.stopKeepAlive(), this.resolvePendingAuthUpdate(!1), !this.disposed && this.subscriptions.size > 0 && this.scheduleReconnect();
|
|
362
362
|
}
|
|
363
363
|
scheduleReconnect() {
|
|
364
|
-
if (this.retryCount >=
|
|
364
|
+
if (this.retryCount >= oe) {
|
|
365
365
|
let e = /* @__PURE__ */ Error("GraphQL subscription websocket retry exhausted");
|
|
366
366
|
for (let t of [...this.subscriptions.keys()]) this.failSubscription(t, e);
|
|
367
367
|
return;
|
|
368
368
|
}
|
|
369
|
-
let e = Math.min(8e3,
|
|
369
|
+
let e = Math.min(8e3, se * 2 ** this.retryCount) + Math.random() * 200;
|
|
370
370
|
this.retryCount += 1, setTimeout(() => {
|
|
371
371
|
this.disposed || this.subscriptions.size === 0 || this.ensureConnected().catch((e) => {
|
|
372
372
|
this.scheduleReconnect(), L("subscription websocket reconnect failed", e);
|
|
@@ -397,7 +397,7 @@ var z = class {
|
|
|
397
397
|
startKeepAlive() {
|
|
398
398
|
this.stopKeepAlive(), this.keepAliveTimer = setInterval(() => {
|
|
399
399
|
this.socket?.readyState === WebSocket.OPEN && this.send({ type: "ping" });
|
|
400
|
-
},
|
|
400
|
+
}, ae);
|
|
401
401
|
}
|
|
402
402
|
stopKeepAlive() {
|
|
403
403
|
this.keepAliveTimer != null && (clearInterval(this.keepAliveTimer), this.keepAliveTimer = null);
|
|
@@ -498,10 +498,11 @@ function Y(e) {
|
|
|
498
498
|
async function X(e, t, n, r, i = new AbortController()) {
|
|
499
499
|
let a = u, s = e.text;
|
|
500
500
|
if (s == null) throw Error("Missing GraphQL query text");
|
|
501
|
-
let c = s, l =
|
|
501
|
+
let c = s, l = ue(e);
|
|
502
502
|
d.add(i);
|
|
503
|
-
|
|
504
|
-
|
|
503
|
+
let p = { authHeadersFailed: !1 };
|
|
504
|
+
async function h(e) {
|
|
505
|
+
if (a !== u) throw Error(_);
|
|
505
506
|
if (i.signal.aborted) throw i.signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
506
507
|
let n = new AbortController(), r = () => {
|
|
507
508
|
n.abort(i.signal.reason);
|
|
@@ -511,12 +512,14 @@ async function X(e, t, n, r, i = new AbortController()) {
|
|
|
511
512
|
n.abort();
|
|
512
513
|
}, U.fetchTimeoutMs);
|
|
513
514
|
try {
|
|
514
|
-
let r,
|
|
515
|
+
let r, s = {};
|
|
515
516
|
if (f != null) try {
|
|
516
|
-
Object.assign(
|
|
517
|
-
} catch {
|
|
518
|
-
|
|
519
|
-
|
|
517
|
+
Object.assign(s, await f(i.signal));
|
|
518
|
+
} catch (e) {
|
|
519
|
+
throw p.authHeadersFailed = !0, e;
|
|
520
|
+
}
|
|
521
|
+
if (a !== u) throw Error(_);
|
|
522
|
+
n.signal.throwIfAborted(), (() => {
|
|
520
523
|
try {
|
|
521
524
|
let e = [t];
|
|
522
525
|
for (; e.length > 0;) {
|
|
@@ -526,36 +529,37 @@ async function X(e, t, n, r, i = new AbortController()) {
|
|
|
526
529
|
}
|
|
527
530
|
} catch {}
|
|
528
531
|
return !1;
|
|
529
|
-
})() ? (r = H(c, t),
|
|
532
|
+
})() ? (r = H(c, t), s[ee] = te) : (s["Content-Type"] = "application/json", r = JSON.stringify({
|
|
530
533
|
query: c,
|
|
531
534
|
variables: t
|
|
532
535
|
}));
|
|
533
|
-
let
|
|
536
|
+
let l = await m(o, {
|
|
534
537
|
method: "POST",
|
|
535
538
|
body: r,
|
|
536
|
-
headers:
|
|
539
|
+
headers: s,
|
|
537
540
|
credentials: "include",
|
|
538
541
|
signal: n.signal
|
|
539
542
|
});
|
|
540
|
-
if (a !== u) throw Error(
|
|
541
|
-
if (!
|
|
542
|
-
if (e < U.maxAttempts - 1 && G(
|
|
543
|
-
let t = await
|
|
544
|
-
throw Error(`GraphQL HTTP error ${
|
|
543
|
+
if (a !== u) throw Error(_);
|
|
544
|
+
if (!l.ok) {
|
|
545
|
+
if (e < U.maxAttempts - 1 && G(l.status)) throw Error(`Retryable HTTP status ${l.status}`);
|
|
546
|
+
let t = await l.text().catch(() => "");
|
|
547
|
+
throw Error(`GraphQL HTTP error ${l.status}: ${t}`);
|
|
545
548
|
}
|
|
546
|
-
let
|
|
547
|
-
if (Array.isArray(
|
|
548
|
-
return
|
|
549
|
+
let d = await l.json();
|
|
550
|
+
if (Array.isArray(d.errors) && d.errors.length > 0 && L("GraphQL errors", d.errors), Y(d)) throw new q(d.errors ?? [], d);
|
|
551
|
+
return d;
|
|
549
552
|
} finally {
|
|
550
553
|
clearTimeout(s), i.signal.removeEventListener("abort", r);
|
|
551
554
|
}
|
|
552
555
|
}
|
|
553
556
|
try {
|
|
554
557
|
for (let e = 0; e < U.maxAttempts; e += 1) try {
|
|
555
|
-
return await
|
|
558
|
+
return await h(e);
|
|
556
559
|
} catch (t) {
|
|
560
|
+
if (p.authHeadersFailed) throw t;
|
|
557
561
|
if (i.signal.aborted) throw i.signal.reason ?? t;
|
|
558
|
-
if (a !== u) throw Error(
|
|
562
|
+
if (a !== u) throw Error(_, { cause: t });
|
|
559
563
|
let n = e === U.maxAttempts - 1;
|
|
560
564
|
if (!(K(t) || t instanceof Error && t.message.includes("Retryable HTTP status")) || n) throw L("GraphQL fetch error", t), t;
|
|
561
565
|
await ye(W(e, U), i.signal);
|
|
@@ -610,23 +614,23 @@ function $() {
|
|
|
610
614
|
}
|
|
611
615
|
function xe() {
|
|
612
616
|
return c ??= new t({
|
|
613
|
-
getDataID:
|
|
614
|
-
relayFieldLogger:
|
|
617
|
+
getDataID: O,
|
|
618
|
+
relayFieldLogger: E,
|
|
615
619
|
network: $(),
|
|
616
620
|
store: new a(new i())
|
|
617
621
|
}), c;
|
|
618
622
|
}
|
|
619
623
|
function Se() {
|
|
620
|
-
|
|
624
|
+
j("configured", "session_reset");
|
|
621
625
|
}
|
|
622
626
|
var Ce = {
|
|
623
627
|
RelayWebSocketClient: z,
|
|
624
628
|
buildFormData: H,
|
|
625
629
|
calcBackoff: W,
|
|
626
630
|
collectFiles: V,
|
|
627
|
-
decodeGraphqlWsMessage:
|
|
631
|
+
decodeGraphqlWsMessage: g,
|
|
628
632
|
fetchFn: X,
|
|
629
|
-
getDataId:
|
|
633
|
+
getDataId: O,
|
|
630
634
|
hasUsableTopLevelData: J,
|
|
631
635
|
isNetworkError: K,
|
|
632
636
|
isRetryableStatus: G,
|
|
@@ -636,6 +640,6 @@ var Ce = {
|
|
|
636
640
|
subscribeFn: Q
|
|
637
641
|
};
|
|
638
642
|
//#endregion
|
|
639
|
-
export { q as GraphQLResponseError, Ce as __test, I as configureRelayEnvironment, xe as getEnvironment, $ as getNetwork,
|
|
643
|
+
export { q as GraphQLResponseError, Ce as __test, I as configureRelayEnvironment, xe as getEnvironment, $ as getNetwork, M as getRelayOperationActivitySnapshot, he as getRelayTransportSnapshot, P as reconnectRelayWebSocket, F as refreshRelayWebSocketAuthentication, Se as resetRelayStore, N as subscribeRelayOperationActivity, ge as subscribeRelayTransport };
|
|
640
644
|
|
|
641
645
|
//# sourceMappingURL=environment.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment.js","names":[],"sources":["../../src/environment.ts"],"sourcesContent":["import {\n Environment,\n Network,\n Observable,\n RecordSource,\n Store,\n type FetchFunction,\n type SubscribeFunction,\n type RelayFieldLogger,\n} from 'relay-runtime';\nimport { isDevEnv } from './envHelpers.js';\n\nlet graphqlHttpEndpoint = '/api/graphql';\nlet graphqlWsEndpoint = '/api/ws';\n\n// (anonymousEnvironment reserved if needed later for public access / logout scenarios)\n// Removed until actually required to avoid lint errors.\n// let anonymousEnvironment: Environment | undefined;\nlet environment: Environment | undefined;\nlet wsClient: RelayWebSocketClient | undefined;\nlet environmentGeneration = 0;\nconst activeHttpControllers = new Set<AbortController>();\nlet getAuthHeaders:\n (() => Record<string, string> | Promise<Record<string, string>>) | undefined;\nconst defaultGraphqlFetch: typeof fetch = async (input, init) => {\n return globalThis.fetch(input, init);\n};\nlet graphqlFetch: typeof fetch = defaultGraphqlFetch;\nlet customDataIdResolver:\n ((fieldValue: unknown, typeName: string) => string | null) | undefined;\n\nconst GRAPHQL_CSRF_PREFLIGHT_HEADER = 'require-preflight';\nconst GRAPHQL_CSRF_PREFLIGHT_HEADER_VALUE = 'true';\n\nexport type RelayTransportStatus = 'idle' | 'configured' | 'reconnecting';\n\nexport interface RelayTransportSnapshot {\n generation: number;\n reason: string | null;\n status: RelayTransportStatus;\n}\n\nexport type RelayOperationKind = 'mutation' | 'query' | 'unknown';\n\nexport type RelayPendingOperation = {\n id: number;\n kind: RelayOperationKind;\n name: string;\n startedAt: number;\n};\n\nexport interface RelayOperationActivitySnapshot {\n generation: number;\n pendingCount: number;\n pendingOperations: readonly RelayPendingOperation[];\n}\n\nexport interface RelayReconnectOptions {\n reason?: string;\n}\n\nexport interface RelayAuthRefreshOptions {\n reason?: string;\n}\n\ntype RelayTransportListener = () => void;\ntype RelayOperationActivityListener = () => void;\n\ntype GraphqlWsPayload = Record<string, unknown>;\n\ntype GraphqlWsMessage =\n | { type: 'connection_ack'; payload?: unknown }\n | { type: 'connection_auth_update_ack'; payload?: unknown }\n | { id: string; type: 'next'; payload: unknown }\n | { id?: string; type: 'error'; payload: unknown }\n | { id: string; type: 'complete' }\n | { type: 'ping'; payload?: unknown }\n | { type: 'pong'; payload?: unknown };\n\ntype GraphqlWsMessageDecodeResult =\n | { readonly ok: true; readonly value: GraphqlWsMessage }\n | {\n readonly ok: false;\n readonly reason: 'invalid' | 'unsupported';\n };\n\nconst isUnknownRecord = (\n value: unknown,\n): value is Readonly<Record<string, unknown>> => {\n return value != null && typeof value === 'object' && !Array.isArray(value);\n};\n\nconst decodeGraphqlWsMessage = (\n value: unknown,\n): GraphqlWsMessageDecodeResult => {\n if (!isUnknownRecord(value) || typeof value.type !== 'string') {\n return { ok: false, reason: 'invalid' };\n }\n const { payload } = value;\n switch (value.type) {\n case 'connection_ack':\n case 'connection_auth_update_ack':\n case 'ping':\n case 'pong':\n return { ok: true, value: { type: value.type, payload } };\n case 'next':\n if (typeof value.id !== 'string') {\n return { ok: false, reason: 'invalid' };\n }\n return { ok: true, value: { id: value.id, type: value.type, payload } };\n case 'error':\n if (value.id != null && typeof value.id !== 'string') {\n return { ok: false, reason: 'invalid' };\n }\n if (value.id == null) {\n return { ok: true, value: { type: value.type, payload } };\n }\n return {\n ok: true,\n value: { id: value.id, type: value.type, payload },\n };\n case 'complete':\n if (typeof value.id !== 'string') {\n return { ok: false, reason: 'invalid' };\n }\n return { ok: true, value: { id: value.id, type: value.type } };\n default:\n return { ok: false, reason: 'unsupported' };\n }\n};\n\ntype SubscriptionSink = {\n next: (value: unknown) => void;\n error: (error: unknown) => void;\n complete: () => void;\n};\n\ntype ActiveSubscription = {\n payload: {\n query: string;\n variables: Record<string, unknown>;\n operationName: string;\n };\n sink: SubscriptionSink;\n};\n\nconst GRAPHQL_TRANSPORT_WS_PROTOCOL = 'graphql-transport-ws';\nconst AUTH_UPDATE_TIMEOUT_MS = 5_000;\nconst WS_KEEP_ALIVE_MS = 10_000;\nconst WS_MAX_RETRY_ATTEMPTS = 10;\nconst WS_BASE_RETRY_DELAY_MS = 500;\nconst ENVIRONMENT_ROTATED_ERROR =\n 'Relay operation cancelled after environment rotation';\n\nlet relayTransportSnapshot: RelayTransportSnapshot = {\n generation: 0,\n reason: null,\n status: 'idle',\n};\nconst relayTransportListeners = new Set<RelayTransportListener>();\n\nlet relayOperationActivitySnapshot: RelayOperationActivitySnapshot = {\n generation: 0,\n pendingCount: 0,\n pendingOperations: [],\n};\nlet relayOperationActivityId = 0;\nconst relayPendingOperations = new Map<number, RelayPendingOperation>();\nconst relayOperationActivityListeners =\n new Set<RelayOperationActivityListener>();\nlet relayOperationActivityNotifyScheduled = false;\n\n/**\n * No-op Relay field logger used to satisfy @required(action: LOG).\n */\nfunction noopRelayFieldLogger(): void {}\n\nlet relayFieldLogger: RelayFieldLogger = noopRelayFieldLogger;\n\nif (isDevEnv()) {\n relayFieldLogger = (event) => {\n // eslint-disable-next-line no-console\n console.log('relayFieldLogger: ', event);\n };\n}\n\nconst defaultGetDataId: (\n fieldValue: unknown,\n typeName: string,\n) => string | null = (fieldValue) => {\n if (fieldValue == null || typeof fieldValue !== 'object') {\n return null;\n }\n const { id } = fieldValue as { id?: unknown };\n if (typeof id !== 'string' || id.trim() === '') {\n return null;\n }\n return id;\n};\n\nconst getDataId = (fieldValue: unknown, typeName: string): string | null => {\n const customId = customDataIdResolver?.(fieldValue, typeName);\n if (customId != null) {\n return customId;\n }\n return defaultGetDataId(fieldValue, typeName);\n};\n\n/**\n * Notify subscribers that the Relay transport state changed.\n */\nfunction emitRelayTransportChange(\n status: RelayTransportStatus,\n reason: string | null,\n): void {\n relayTransportSnapshot = {\n generation: relayTransportSnapshot.generation + 1,\n reason,\n status,\n };\n for (const listener of relayTransportListeners) {\n listener();\n }\n}\n\n/**\n * Publish the latest Relay HTTP operation activity snapshot.\n */\nfunction emitRelayOperationActivityChange(): void {\n relayOperationActivitySnapshot = {\n generation: relayOperationActivitySnapshot.generation + 1,\n pendingCount: relayPendingOperations.size,\n pendingOperations: [...relayPendingOperations.values()],\n };\n if (relayOperationActivityNotifyScheduled) {\n return;\n }\n relayOperationActivityNotifyScheduled = true;\n queueMicrotask(() => {\n relayOperationActivityNotifyScheduled = false;\n for (const listener of relayOperationActivityListeners) {\n listener();\n }\n });\n}\n\n/**\n * Clear pending Relay HTTP operations after environment reconfiguration.\n */\nfunction resetRelayOperationActivity(): void {\n if (relayPendingOperations.size === 0) {\n return;\n }\n relayPendingOperations.clear();\n emitRelayOperationActivityChange();\n}\n\n/**\n * Normalize Relay operation kind values from runtime requests.\n */\nfunction resolveRelayOperationKind(operationKind: unknown): RelayOperationKind {\n if (operationKind === 'query' || operationKind === 'mutation') {\n return operationKind;\n }\n return 'unknown';\n}\n\n/**\n * Track a Relay HTTP operation until its returned disposer is called.\n */\nfunction startRelayOperationActivity(request: {\n name?: string | null;\n operationKind?: unknown;\n}): () => void {\n const id = relayOperationActivityId;\n relayOperationActivityId += 1;\n relayPendingOperations.set(id, {\n id,\n kind: resolveRelayOperationKind(request.operationKind),\n name: request.name ?? 'AnonymousGraphQLOperation',\n startedAt: Date.now(),\n });\n emitRelayOperationActivityChange();\n\n let isSettled = false;\n return () => {\n if (isSettled) {\n return;\n }\n isSettled = true;\n if (!relayPendingOperations.delete(id)) {\n return;\n }\n emitRelayOperationActivityChange();\n };\n}\n\n/**\n * Dispose the active websocket client and ignore shutdown failures.\n */\nfunction disposeWsClient(): void {\n if (wsClient == null) {\n return;\n }\n try {\n wsClient.dispose();\n } catch {\n // ignore errors during dispose\n }\n wsClient = undefined;\n}\n\n/** End every subscription owned by an environment that is being replaced. */\nfunction terminateWsClient(): void {\n if (wsClient == null) {\n return;\n }\n try {\n wsClient.terminate();\n } catch {\n // ignore errors during termination\n }\n wsClient = undefined;\n}\n\n/** Abort every HTTP operation owned by the current Relay environment. */\nfunction abortActiveHttpOperations(): void {\n for (const controller of activeHttpControllers) {\n controller.abort(new Error(ENVIRONMENT_ROTATED_ERROR));\n }\n activeHttpControllers.clear();\n}\n\n/** Remove all records from an environment while notifying its active selectors. */\nfunction clearEnvironmentStore(currentEnvironment: Environment): void {\n const store = currentEnvironment.getStore();\n const source = store.getSource();\n const deletedRecords = new RecordSource();\n\n for (const dataId of source.getRecordIDs()) {\n deletedRecords.delete(dataId);\n }\n try {\n if (deletedRecords.size() > 0) {\n store.publish(deletedRecords);\n store.notify();\n }\n } finally {\n if (source instanceof RecordSource) {\n source.clear();\n }\n }\n}\n\n/** Replace the shared environment and terminate work owned by its generation. */\nfunction rotateRelayEnvironment(\n status: RelayTransportStatus,\n reason: string,\n): void {\n const previousEnvironment = environment;\n environment = undefined;\n environmentGeneration += 1;\n abortActiveHttpOperations();\n terminateWsClient();\n try {\n if (previousEnvironment != null) {\n clearEnvironmentStore(previousEnvironment);\n }\n } finally {\n resetRelayOperationActivity();\n emitRelayTransportChange(status, reason);\n }\n}\n\n/**\n * Return the current Relay transport state used by subscription hooks.\n */\nexport function getRelayTransportSnapshot(): RelayTransportSnapshot {\n return relayTransportSnapshot;\n}\n\n/**\n * Subscribe to Relay transport changes.\n */\nexport function subscribeRelayTransport(\n listener: RelayTransportListener,\n): () => void {\n relayTransportListeners.add(listener);\n return () => {\n relayTransportListeners.delete(listener);\n };\n}\n\n/**\n * Return the current Relay HTTP operation activity snapshot.\n */\nexport function getRelayOperationActivitySnapshot(): RelayOperationActivitySnapshot {\n return relayOperationActivitySnapshot;\n}\n\n/**\n * Subscribe to Relay HTTP operation activity changes.\n */\nexport function subscribeRelayOperationActivity(\n listener: RelayOperationActivityListener,\n): () => void {\n relayOperationActivityListeners.add(listener);\n return () => {\n relayOperationActivityListeners.delete(listener);\n };\n}\n\n/**\n * Force the websocket transport to reconnect and notify mounted subscriptions.\n */\nexport function reconnectRelayWebSocket(\n options: RelayReconnectOptions = {},\n): void {\n disposeWsClient();\n emitRelayTransportChange(\n 'reconnecting',\n options.reason ?? 'manual_reconnect',\n );\n}\n\n/**\n * Refresh the active websocket authentication without recreating subscriptions.\n */\nexport async function refreshRelayWebSocketAuthentication(\n options: RelayAuthRefreshOptions = {},\n): Promise<void> {\n const client = wsClient;\n if (!client?.hasActiveConnection()) {\n return;\n }\n\n const refreshed = await client.refreshAuthentication();\n if (!refreshed) {\n reconnectRelayWebSocket({\n reason: options.reason ?? 'auth_refresh_fallback',\n });\n }\n}\n\nexport interface RelayEnvironmentConfiguration {\n httpUrl?: string;\n wsUrl?: string;\n logEvents?: boolean;\n getDataId?: (fieldValue: unknown, typeName: string) => string | null;\n getAuthHeaders?: () =>\n Record<string, string> | Promise<Record<string, string>>;\n fetchImpl?: typeof fetch;\n}\n\n/**\n * Configure the endpoints and logging behavior used by the shared Relay environment.\n */\nexport function configureRelayEnvironment(\n options: RelayEnvironmentConfiguration = {},\n): void {\n const {\n httpUrl,\n wsUrl,\n logEvents,\n getDataId: nextGetDataId,\n getAuthHeaders: nextGetAuthHeaders,\n fetchImpl: nextFetchImpl,\n } = options;\n\n if (typeof httpUrl === 'string' && httpUrl !== '') {\n graphqlHttpEndpoint = httpUrl;\n }\n\n if (typeof wsUrl === 'string' && wsUrl !== '') {\n graphqlWsEndpoint = wsUrl;\n }\n\n if (logEvents != null) {\n if (logEvents) {\n relayFieldLogger = (event) => {\n // eslint-disable-next-line no-console\n console.log('relayFieldLogger: ', event);\n };\n } else {\n relayFieldLogger = noopRelayFieldLogger;\n }\n }\n\n customDataIdResolver = nextGetDataId;\n getAuthHeaders = nextGetAuthHeaders;\n graphqlFetch = nextFetchImpl ?? defaultGraphqlFetch;\n\n rotateRelayEnvironment('configured', 'configure');\n}\n\n/**\n * Resolve the websocket endpoint into an absolute GraphQL WebSocket URL.\n */\nfunction resolveWebsocketUrl(): string {\n const endpoint = graphqlWsEndpoint;\n\n if (endpoint.startsWith('ws')) {\n return endpoint;\n }\n\n if (endpoint.startsWith('http')) {\n return endpoint.replace(/^http/, 'ws');\n }\n\n if (endpoint.startsWith('/')) {\n if (typeof window === 'undefined') {\n return endpoint;\n }\n let protocol = 'ws:';\n if (window.location.protocol === 'https:') {\n protocol = 'wss:';\n }\n return `${protocol}//${window.location.host}${endpoint}`;\n }\n\n return endpoint;\n}\n\n/** Debug log helper (no-op en production) */\nfunction debugLog(...args: unknown[]): void {\n if (isDevEnv()) {\n // eslint-disable-next-line no-console\n console.log('[RelayNetwork]', ...args);\n }\n}\n\n/** Resolve authentication headers for Relay HTTP and websocket transports. */\nasync function resolveAuthHeaders(): Promise<Record<string, string>> {\n if (getAuthHeaders == null) {\n return {};\n }\n return getAuthHeaders();\n}\n\nclass RelayWebSocketClient {\n private socket: WebSocket | null = null;\n\n private connectPromise: Promise<void> | null = null;\n\n private disposed = false;\n\n private acknowledged = false;\n\n private retryCount = 0;\n\n private nextId = 1;\n\n private keepAliveTimer: ReturnType<typeof setInterval> | null = null;\n\n private readonly subscriptions = new Map<string, ActiveSubscription>();\n\n private pendingAuthUpdate: {\n resolve: (value: boolean) => void;\n timeout: ReturnType<typeof setTimeout>;\n } | null = null;\n\n public constructor(private readonly url: string) {}\n\n public hasActiveConnection(): boolean {\n return this.socket?.readyState === WebSocket.OPEN && this.acknowledged;\n }\n\n public dispose(): void {\n this.disposed = true;\n this.resolvePendingAuthUpdate(false);\n this.stopKeepAlive();\n const { socket } = this;\n this.socket = null;\n this.connectPromise = null;\n this.acknowledged = false;\n if (socket != null && socket.readyState !== WebSocket.CLOSED) {\n socket.close(1000, 'Normal Closure');\n }\n }\n\n public terminate(): void {\n for (const subscription of this.subscriptions.values()) {\n try {\n subscription.sink.complete();\n } catch {\n // ignore subscriber failures while ending an environment\n }\n }\n this.subscriptions.clear();\n this.dispose();\n }\n\n public subscribe(\n payload: ActiveSubscription['payload'],\n sink: SubscriptionSink,\n ): () => void {\n const id = String(this.nextId);\n this.nextId += 1;\n this.subscriptions.set(id, { payload, sink });\n this.connectAndSubscribe(id).catch((error: unknown) => {\n debugLog('subscription websocket connect failed', error);\n this.scheduleReconnect();\n });\n\n return () => {\n this.unsubscribe(id);\n };\n }\n\n public async refreshAuthentication(): Promise<boolean> {\n if (!this.hasActiveConnection()) {\n return true;\n }\n const { socket } = this;\n if (socket == null) {\n return true;\n }\n if (this.pendingAuthUpdate != null) {\n return false;\n }\n\n let payload: Record<string, string>;\n try {\n payload = await resolveAuthHeaders();\n } catch {\n return false;\n }\n if (Object.keys(payload).length === 0) {\n return false;\n }\n\n return new Promise<boolean>((resolve) => {\n const timeout = setTimeout(() => {\n this.pendingAuthUpdate = null;\n resolve(false);\n }, AUTH_UPDATE_TIMEOUT_MS);\n this.pendingAuthUpdate = { resolve, timeout };\n this.send({\n type: 'connection_auth_update',\n payload,\n });\n });\n }\n\n private async connectAndSubscribe(id: string): Promise<void> {\n const wasConnected = this.hasActiveConnection();\n await this.ensureConnected();\n if (!wasConnected) {\n return;\n }\n const subscription = this.subscriptions.get(id);\n if (subscription == null) {\n return;\n }\n this.send({\n id,\n type: 'subscribe',\n payload: subscription.payload,\n });\n }\n\n private async ensureConnected(): Promise<void> {\n if (this.hasActiveConnection()) {\n return;\n }\n if (this.connectPromise != null) {\n await this.connectPromise;\n return;\n }\n\n this.connectPromise = this.openSocket();\n try {\n await this.connectPromise;\n } finally {\n this.connectPromise = null;\n }\n }\n\n private async openSocket(): Promise<void> {\n if (this.disposed) {\n throw new Error('WebSocket client is disposed');\n }\n\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n const resolveConnected = (): void => {\n if (settled) {\n return;\n }\n settled = true;\n resolve();\n };\n const rejectConnection = (error: unknown): void => {\n if (settled) {\n return;\n }\n settled = true;\n reject(error);\n };\n const socket = new WebSocket(this.url, GRAPHQL_TRANSPORT_WS_PROTOCOL);\n this.socket = socket;\n this.acknowledged = false;\n\n socket.onopen = () => {\n resolveAuthHeaders()\n .catch(() => {\n return {};\n })\n .then((payload) => {\n if (socket.readyState !== WebSocket.OPEN) {\n return;\n }\n if (Object.keys(payload).length > 0) {\n this.send({ type: 'connection_init', payload });\n return;\n }\n this.send({ type: 'connection_init' });\n })\n .catch((error: unknown) => {\n rejectConnection(error);\n });\n };\n\n socket.onerror = () => {\n rejectConnection(new Error('GraphQL subscription websocket error'));\n };\n\n socket.onmessage = (event) => {\n this.handleMessage(event.data, resolveConnected, rejectConnection);\n };\n\n socket.onclose = () => {\n rejectConnection(new Error('GraphQL subscription websocket closed'));\n this.handleClose();\n };\n });\n }\n\n private handleMessage(\n data: unknown,\n connected: () => void,\n rejected: (error: unknown) => void,\n ): void {\n let parsed: unknown;\n try {\n parsed = JSON.parse(String(data));\n } catch {\n rejected(new Error('Invalid GraphQL websocket message'));\n this.socket?.close(4400, 'Invalid websocket message');\n return;\n }\n\n const decoded = decodeGraphqlWsMessage(parsed);\n if (!decoded.ok) {\n const unsupported = decoded.reason === 'unsupported';\n let errorMessage = 'Invalid GraphQL websocket message';\n let closeMessage = 'Invalid websocket message';\n if (unsupported) {\n errorMessage = 'Unsupported GraphQL websocket message';\n closeMessage = 'Unsupported websocket message';\n }\n rejected(new Error(errorMessage));\n this.socket?.close(4400, closeMessage);\n return;\n }\n const message = decoded.value;\n\n switch (message.type) {\n case 'connection_ack':\n this.acknowledged = true;\n this.retryCount = 0;\n this.startKeepAlive();\n connected();\n this.resubscribeActiveOperations();\n return;\n case 'connection_auth_update_ack':\n this.resolvePendingAuthUpdate(true);\n return;\n case 'next':\n this.subscriptions.get(message.id)?.sink.next(message.payload);\n return;\n case 'error':\n if (message.id != null) {\n this.failSubscription(message.id, message.payload);\n } else {\n this.resolvePendingAuthUpdate(false);\n }\n return;\n case 'complete':\n this.completeSubscription(message.id);\n return;\n case 'ping':\n this.send({ type: 'pong', payload: message.payload });\n break;\n case 'pong':\n break;\n default:\n break;\n }\n }\n\n private handleClose(): void {\n this.acknowledged = false;\n this.socket = null;\n this.connectPromise = null;\n this.stopKeepAlive();\n this.resolvePendingAuthUpdate(false);\n if (!this.disposed && this.subscriptions.size > 0) {\n this.scheduleReconnect();\n }\n }\n\n private scheduleReconnect(): void {\n if (this.retryCount >= WS_MAX_RETRY_ATTEMPTS) {\n const error = new Error('GraphQL subscription websocket retry exhausted');\n for (const id of [...this.subscriptions.keys()]) {\n this.failSubscription(id, error);\n }\n return;\n }\n const delay =\n Math.min(8_000, WS_BASE_RETRY_DELAY_MS * 2 ** this.retryCount) +\n Math.random() * 200;\n this.retryCount += 1;\n setTimeout(() => {\n if (this.disposed || this.subscriptions.size === 0) {\n return;\n }\n this.ensureConnected().catch((error: unknown) => {\n this.scheduleReconnect();\n debugLog('subscription websocket reconnect failed', error);\n });\n }, delay);\n }\n\n private resubscribeActiveOperations(): void {\n for (const [id, subscription] of this.subscriptions) {\n this.send({\n id,\n type: 'subscribe',\n payload: subscription.payload,\n });\n }\n }\n\n private unsubscribe(id: string): void {\n const hadSubscription = this.subscriptions.delete(id);\n if (hadSubscription && this.socket?.readyState === WebSocket.OPEN) {\n this.send({ id, type: 'complete' });\n }\n }\n\n private failSubscription(id: string, error: unknown): void {\n const subscription = this.subscriptions.get(id);\n if (subscription == null) {\n return;\n }\n this.subscriptions.delete(id);\n subscription.sink.error(error);\n }\n\n private completeSubscription(id: string): void {\n const subscription = this.subscriptions.get(id);\n if (subscription == null) {\n return;\n }\n this.subscriptions.delete(id);\n subscription.sink.complete();\n }\n\n private startKeepAlive(): void {\n this.stopKeepAlive();\n this.keepAliveTimer = setInterval(() => {\n if (this.socket?.readyState === WebSocket.OPEN) {\n this.send({ type: 'ping' });\n }\n }, WS_KEEP_ALIVE_MS);\n }\n\n private stopKeepAlive(): void {\n if (this.keepAliveTimer != null) {\n clearInterval(this.keepAliveTimer);\n this.keepAliveTimer = null;\n }\n }\n\n private resolvePendingAuthUpdate(value: boolean): void {\n const pending = this.pendingAuthUpdate;\n if (pending == null) {\n return;\n }\n clearTimeout(pending.timeout);\n this.pendingAuthUpdate = null;\n pending.resolve(value);\n }\n\n private send(message: GraphqlWsPayload): void {\n const { socket } = this;\n if (socket?.readyState !== WebSocket.OPEN) {\n return;\n }\n socket.send(JSON.stringify(message));\n }\n}\n\n/**\n * Build or get a singleton graphql-transport-ws client with auth refresh support.\n */\nfunction getWsClient(): RelayWebSocketClient {\n if (wsClient != null) {\n return wsClient;\n }\n if (typeof window === 'undefined') {\n throw new Error(\n 'GraphQL subscriptions unavailable in non-browser environment',\n );\n }\n\n const url = resolveWebsocketUrl();\n wsClient = new RelayWebSocketClient(url);\n\n return wsClient;\n}\n\n/**\n * Get organization slug from current window location\n */\n// export function getOrganizationSlug(): string | null {\n// const { pathname } = window.location;\n// const slug = pathname.split('/')[1];\n// if (slug == null) {\n// return null;\n// }\n\n// return slug;\n// }\n\n// -------------------------\n// Upload detection helpers\n// -------------------------\n/** Test if a value is an uploadable (File/Blob) */\nfunction isUploadable(value: unknown): value is File | Blob {\n return (\n (typeof File !== 'undefined' && value instanceof File) ||\n (typeof Blob !== 'undefined' && value instanceof Blob)\n );\n}\n\ninterface FileRef {\n path: string; // JSON pointer-like (e.g. variables.input.file)\n file: File | Blob;\n}\n\n/** Recursively clone a structure replacing files with null and collecting them */\nfunction collectFiles(value: unknown, path: string, acc: FileRef[]): unknown {\n if (isUploadable(value)) {\n acc.push({ path, file: value });\n return null; // placeholder per multipart spec\n }\n if (Array.isArray(value)) {\n return value.map((v, i) => {\n return collectFiles(v, `${path}.${i}`, acc);\n });\n }\n if (value != null && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = collectFiles(v, `${path}.${k}`, acc);\n }\n return out;\n }\n return value; // primitives unchanged\n}\n\n/** Build GraphQL multipart form-data payload */\nfunction buildFormData(\n query: string,\n variables: Record<string, unknown>,\n): FormData {\n const files: FileRef[] = [];\n // Deep clone variables while replacing files with null\n const clonedVars = collectFiles(variables, 'variables', files) as Record<\n string,\n unknown\n >;\n\n const form = new FormData();\n const operations = { query, variables: clonedVars };\n form.append('operations', JSON.stringify(operations));\n\n const map: Record<string, string[]> = {};\n files.forEach((ref, idx) => {\n map[idx] = [ref.path];\n });\n form.append('map', JSON.stringify(map));\n files.forEach((ref, idx) => {\n form.append(String(idx), ref.file);\n });\n return form;\n}\n\n// -------------------------\n// Retry / timeout helpers\n// -------------------------\ninterface RetryOptions {\n maxAttempts: number; // total attempts including initial\n baseDelayMs: number;\n maxDelayMs: number;\n fetchTimeoutMs: number;\n}\n\nconst RETRY_OPTIONS: RetryOptions = {\n maxAttempts: 3,\n baseDelayMs: 300,\n maxDelayMs: 4000,\n fetchTimeoutMs: 600_000, // 10 minutes (parité avec ancien middleware)\n};\n\n/** Sleep helper that ends immediately when its owning operation is cancelled. */\nasync function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n if (signal?.aborted === true) {\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n return;\n }\n const timeout = setTimeout(resolve, ms);\n signal?.addEventListener(\n 'abort',\n () => {\n clearTimeout(timeout);\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n },\n { once: true },\n );\n });\n}\n\n/** Exponential backoff with jitter */\nfunction calcBackoff(attempt: number, opts: RetryOptions): number {\n const exp = Math.min(opts.maxDelayMs, opts.baseDelayMs * 2 ** attempt);\n return exp + Math.random() * 0.2 * exp; // jitter 0-20%\n}\n\n/** Determine if an HTTP status is retryable */\nfunction isRetryableStatus(status: number): boolean {\n return status === 408 || status === 429 || (status >= 500 && status < 600);\n}\n\n/** Determine if an error should be treated as transient network issue */\nfunction isNetworkError(err: unknown): boolean {\n return (\n err instanceof TypeError ||\n (err instanceof Error && err.name === 'AbortError')\n );\n}\n\n// -------------------------\n// fetchFn implementation\n// -------------------------\ninterface GraphQLResponseErrorItem {\n [key: string]: unknown;\n message: string;\n path?: readonly unknown[];\n}\n\ninterface GraphQLResponseShape<T = unknown> {\n data?: T;\n errors?: GraphQLResponseErrorItem[];\n extensions?: Record<string, unknown>;\n}\n\nexport class GraphQLResponseError extends Error {\n public constructor(\n public readonly errors: readonly GraphQLResponseErrorItem[],\n public readonly response: GraphQLResponseShape,\n ) {\n super(errors[0]?.message ?? 'GraphQL response error');\n this.name = 'GraphQLResponseError';\n }\n}\n\n/** Determine whether a GraphQL payload includes non-null top-level data. */\nfunction hasUsableTopLevelData(data: unknown): boolean {\n if (data == null) {\n return false;\n }\n if (typeof data !== 'object') {\n return true;\n }\n return Object.values(data as Record<string, unknown>).some((value) => {\n return value != null;\n });\n}\n\n/** Determine whether all errors are child-field errors under top-level null data. */\nfunction hasOnlyErrorsBelowNullTopLevelFields(\n response: GraphQLResponseShape,\n): boolean {\n const { data, errors } = response;\n if (\n data == null ||\n typeof data !== 'object' ||\n !Array.isArray(errors) ||\n errors.length === 0\n ) {\n return false;\n }\n\n const dataRecord = data as Record<string, unknown>;\n return errors.every((error) => {\n const [topLevelField, ...childPath] = error.path ?? [];\n if (typeof topLevelField !== 'string' || childPath.length === 0) {\n return false;\n }\n return (\n Object.prototype.hasOwnProperty.call(dataRecord, topLevelField) &&\n dataRecord[topLevelField] == null\n );\n });\n}\n\n/** Determine whether GraphQL errors should be surfaced as a thrown response error. */\nfunction shouldThrowGraphQLResponseError(\n response: GraphQLResponseShape,\n): boolean {\n return (\n Array.isArray(response.errors) &&\n response.errors.length > 0 &&\n !hasUsableTopLevelData(response.data) &&\n !hasOnlyErrorsBelowNullTopLevelFields(response)\n );\n}\n\n/** Fetch GraphQL (with retry + upload) */\nasync function fetchFn(\n request: {\n name?: string | null;\n operationKind?: unknown;\n text: string | null | undefined;\n },\n variables: Record<string, unknown>,\n _cacheConfig: unknown,\n _uploadables: unknown,\n operationController: AbortController = new AbortController(),\n): Promise<GraphQLResponseShape> {\n const operationEnvironmentGeneration = environmentGeneration;\n const queryText: string | null | undefined = request.text; // no persisted queries here (yet)\n if (queryText == null) {\n throw new Error('Missing GraphQL query text');\n }\n const safeQueryText: string = queryText; // narrowed non-null\n const stopRelayOperationActivity = startRelayOperationActivity(request);\n activeHttpControllers.add(operationController);\n\n /** Execute one network attempt */\n async function execOnce(attempt: number): Promise<GraphQLResponseShape> {\n if (operationEnvironmentGeneration !== environmentGeneration) {\n throw new Error(ENVIRONMENT_ROTATED_ERROR);\n }\n if (operationController.signal.aborted) {\n throw (\n operationController.signal.reason ??\n new DOMException('Aborted', 'AbortError')\n );\n }\n const controller = new AbortController();\n const abortAttempt = (): void => {\n controller.abort(operationController.signal.reason);\n };\n operationController.signal.addEventListener('abort', abortAttempt, {\n once: true,\n });\n const timeout = setTimeout(() => {\n controller.abort();\n }, RETRY_OPTIONS.fetchTimeoutMs);\n try {\n let body: BodyInit;\n const headers: Record<string, string> = {};\n if (getAuthHeaders != null) {\n try {\n Object.assign(headers, await getAuthHeaders());\n } catch {\n // ignore auth header failures\n }\n }\n if (operationEnvironmentGeneration !== environmentGeneration) {\n throw new Error(ENVIRONMENT_ROTATED_ERROR);\n }\n const hasFiles = ((): boolean => {\n try {\n const stack: unknown[] = [variables];\n while (stack.length > 0) {\n const v = stack.pop();\n if (isUploadable(v)) {\n return true;\n }\n if (Array.isArray(v)) {\n stack.push(...v);\n } else if (v != null && typeof v === 'object') {\n stack.push(...Object.values(v as Record<string, unknown>));\n }\n }\n } catch {\n // ignore traversal errors\n }\n return false;\n })();\n\n if (hasFiles) {\n body = buildFormData(safeQueryText, variables);\n headers[GRAPHQL_CSRF_PREFLIGHT_HEADER] =\n GRAPHQL_CSRF_PREFLIGHT_HEADER_VALUE;\n } else {\n headers['Content-Type'] = 'application/json';\n body = JSON.stringify({ query: safeQueryText, variables });\n }\n\n const response = await graphqlFetch(graphqlHttpEndpoint, {\n method: 'POST',\n body,\n headers,\n credentials: 'include',\n signal: controller.signal,\n });\n\n if (operationEnvironmentGeneration !== environmentGeneration) {\n throw new Error(ENVIRONMENT_ROTATED_ERROR);\n }\n\n if (!response.ok) {\n if (\n attempt < RETRY_OPTIONS.maxAttempts - 1 &&\n isRetryableStatus(response.status)\n ) {\n throw new Error(`Retryable HTTP status ${response.status}`);\n }\n const text = await response.text().catch(() => {\n return '';\n });\n throw new Error(`GraphQL HTTP error ${response.status}: ${text}`);\n }\n\n const json: GraphQLResponseShape = await response.json();\n if (Array.isArray(json.errors) && json.errors.length > 0) {\n debugLog('GraphQL errors', json.errors);\n }\n if (shouldThrowGraphQLResponseError(json)) {\n throw new GraphQLResponseError(json.errors ?? [], json);\n }\n return json;\n } finally {\n clearTimeout(timeout);\n operationController.signal.removeEventListener('abort', abortAttempt);\n }\n }\n\n try {\n for (let attempt = 0; attempt < RETRY_OPTIONS.maxAttempts; attempt += 1) {\n try {\n return await execOnce(attempt);\n } catch (err) {\n if (operationController.signal.aborted) {\n throw operationController.signal.reason ?? err;\n }\n if (operationEnvironmentGeneration !== environmentGeneration) {\n throw new Error(ENVIRONMENT_ROTATED_ERROR, { cause: err });\n }\n const last = attempt === RETRY_OPTIONS.maxAttempts - 1;\n const retryable =\n isNetworkError(err) ||\n (err instanceof Error &&\n err.message.includes('Retryable HTTP status'));\n if (!retryable || last) {\n debugLog('GraphQL fetch error', err);\n throw err;\n }\n const delay = calcBackoff(attempt, RETRY_OPTIONS);\n await sleep(delay, operationController.signal);\n }\n }\n throw new Error('Exhausted retries without returning a result');\n } finally {\n activeHttpControllers.delete(operationController);\n stopRelayOperationActivity();\n }\n}\n\n/** Relay fetch function whose disposal cancels the complete HTTP retry lifecycle. */\nfunction observableFetchFn(\n request: Parameters<typeof fetchFn>[0],\n variables: Parameters<typeof fetchFn>[1],\n cacheConfig: Parameters<typeof fetchFn>[2],\n uploadables: Parameters<typeof fetchFn>[3],\n): Observable<GraphQLResponseShape> {\n return Observable.create<GraphQLResponseShape>((sink) => {\n const controller = new AbortController();\n let disposed = false;\n fetchFn(request, variables, cacheConfig, uploadables, controller).then(\n (response) => {\n if (disposed) {\n return;\n }\n sink.next(response);\n sink.complete();\n },\n (error: unknown) => {\n if (!disposed) {\n let relayError: Error;\n if (error instanceof Error) {\n relayError = error;\n } else {\n relayError = new Error(String(error));\n }\n sink.error(relayError);\n }\n },\n );\n return () => {\n disposed = true;\n controller.abort(\n new DOMException('Relay operation disposed', 'AbortError'),\n );\n };\n });\n}\n\n// -------------------------\n// subscribeFn implementation (wrap existing logic in Relay Observable)\n// -------------------------\n/** Subscription function bridging the owned GraphQL WebSocket client to Relay. */\nfunction subscribeFn(\n operation: { text: string | null | undefined; name: string },\n variables: Record<string, unknown>,\n): Observable<unknown> {\n debugLog('subscription:start', operation.name, variables);\n return Observable.create<unknown>((sink) => {\n const query = operation.text;\n if (query == null || query === '') {\n sink.error(new Error('Subscription operation text is empty'));\n return () => {\n // noop\n };\n }\n const client = getWsClient();\n const dispose = client.subscribe(\n { query, variables, operationName: operation.name },\n {\n next: (data) => {\n sink.next(data);\n },\n error: (err) => {\n let errorObj: Error;\n if (err instanceof Error) {\n errorObj = err;\n } else {\n errorObj = new Error('Subscription error');\n }\n sink.error(errorObj);\n },\n complete: () => {\n sink.complete();\n },\n },\n );\n return () => {\n dispose();\n };\n });\n}\n\n/**\n * Create native Relay network layer (fetch + subscribe)\n */\nexport function getNetwork(): ReturnType<typeof Network.create> {\n return Network.create(\n observableFetchFn as FetchFunction,\n subscribeFn as SubscribeFunction,\n );\n}\n\n/**\n * Get anonymous relay environment\n */\nexport function getEnvironment(): Environment {\n environment ??= new Environment({\n getDataID: getDataId,\n relayFieldLogger,\n network: getNetwork(),\n store: new Store(new RecordSource()),\n });\n\n return environment;\n}\n\n/**\n * End the current Relay session and expose a new empty environment.\n */\nexport function resetRelayStore(): void {\n rotateRelayEnvironment('configured', 'session_reset');\n}\n\nexport const __test = {\n RelayWebSocketClient,\n buildFormData,\n calcBackoff,\n collectFiles,\n decodeGraphqlWsMessage,\n fetchFn,\n getDataId,\n hasUsableTopLevelData,\n isNetworkError,\n isRetryableStatus,\n isUploadable,\n shouldThrowGraphQLResponseError,\n observableFetchFn,\n subscribeFn,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"environment.js","names":[],"sources":["../../src/environment.ts"],"sourcesContent":["import {\n Environment,\n Network,\n Observable,\n RecordSource,\n Store,\n type FetchFunction,\n type SubscribeFunction,\n type RelayFieldLogger,\n} from 'relay-runtime';\nimport { isDevEnv } from './envHelpers.js';\n\nlet graphqlHttpEndpoint = '/api/graphql';\nlet graphqlWsEndpoint = '/api/ws';\n\n// (anonymousEnvironment reserved if needed later for public access / logout scenarios)\n// Removed until actually required to avoid lint errors.\n// let anonymousEnvironment: Environment | undefined;\nlet environment: Environment | undefined;\nlet wsClient: RelayWebSocketClient | undefined;\nlet environmentGeneration = 0;\nconst activeHttpControllers = new Set<AbortController>();\nlet getAuthHeaders:\n | ((\n signal?: AbortSignal,\n ) => Record<string, string> | Promise<Record<string, string>>)\n | undefined;\nconst defaultGraphqlFetch: typeof fetch = async (input, init) => {\n return globalThis.fetch(input, init);\n};\nlet graphqlFetch: typeof fetch = defaultGraphqlFetch;\nlet customDataIdResolver:\n ((fieldValue: unknown, typeName: string) => string | null) | undefined;\n\nconst GRAPHQL_CSRF_PREFLIGHT_HEADER = 'require-preflight';\nconst GRAPHQL_CSRF_PREFLIGHT_HEADER_VALUE = 'true';\n\nexport type RelayTransportStatus = 'idle' | 'configured' | 'reconnecting';\n\nexport interface RelayTransportSnapshot {\n generation: number;\n reason: string | null;\n status: RelayTransportStatus;\n}\n\nexport type RelayOperationKind = 'mutation' | 'query' | 'unknown';\n\nexport type RelayPendingOperation = {\n id: number;\n kind: RelayOperationKind;\n name: string;\n startedAt: number;\n};\n\nexport interface RelayOperationActivitySnapshot {\n generation: number;\n pendingCount: number;\n pendingOperations: readonly RelayPendingOperation[];\n}\n\nexport interface RelayReconnectOptions {\n reason?: string;\n}\n\nexport interface RelayAuthRefreshOptions {\n reason?: string;\n}\n\ntype RelayTransportListener = () => void;\ntype RelayOperationActivityListener = () => void;\n\ntype GraphqlWsPayload = Record<string, unknown>;\n\ntype GraphqlWsMessage =\n | { type: 'connection_ack'; payload?: unknown }\n | { type: 'connection_auth_update_ack'; payload?: unknown }\n | { id: string; type: 'next'; payload: unknown }\n | { id?: string; type: 'error'; payload: unknown }\n | { id: string; type: 'complete' }\n | { type: 'ping'; payload?: unknown }\n | { type: 'pong'; payload?: unknown };\n\ntype GraphqlWsMessageDecodeResult =\n | { readonly ok: true; readonly value: GraphqlWsMessage }\n | {\n readonly ok: false;\n readonly reason: 'invalid' | 'unsupported';\n };\n\nconst isUnknownRecord = (\n value: unknown,\n): value is Readonly<Record<string, unknown>> => {\n return value != null && typeof value === 'object' && !Array.isArray(value);\n};\n\nconst decodeGraphqlWsMessage = (\n value: unknown,\n): GraphqlWsMessageDecodeResult => {\n if (!isUnknownRecord(value) || typeof value.type !== 'string') {\n return { ok: false, reason: 'invalid' };\n }\n const { payload } = value;\n switch (value.type) {\n case 'connection_ack':\n case 'connection_auth_update_ack':\n case 'ping':\n case 'pong':\n return { ok: true, value: { type: value.type, payload } };\n case 'next':\n if (typeof value.id !== 'string') {\n return { ok: false, reason: 'invalid' };\n }\n return { ok: true, value: { id: value.id, type: value.type, payload } };\n case 'error':\n if (value.id != null && typeof value.id !== 'string') {\n return { ok: false, reason: 'invalid' };\n }\n if (value.id == null) {\n return { ok: true, value: { type: value.type, payload } };\n }\n return {\n ok: true,\n value: { id: value.id, type: value.type, payload },\n };\n case 'complete':\n if (typeof value.id !== 'string') {\n return { ok: false, reason: 'invalid' };\n }\n return { ok: true, value: { id: value.id, type: value.type } };\n default:\n return { ok: false, reason: 'unsupported' };\n }\n};\n\ntype SubscriptionSink = {\n next: (value: unknown) => void;\n error: (error: unknown) => void;\n complete: () => void;\n};\n\ntype ActiveSubscription = {\n payload: {\n query: string;\n variables: Record<string, unknown>;\n operationName: string;\n };\n sink: SubscriptionSink;\n};\n\nconst GRAPHQL_TRANSPORT_WS_PROTOCOL = 'graphql-transport-ws';\nconst AUTH_UPDATE_TIMEOUT_MS = 5_000;\nconst WS_KEEP_ALIVE_MS = 10_000;\nconst WS_MAX_RETRY_ATTEMPTS = 10;\nconst WS_BASE_RETRY_DELAY_MS = 500;\nconst ENVIRONMENT_ROTATED_ERROR =\n 'Relay operation cancelled after environment rotation';\n\nlet relayTransportSnapshot: RelayTransportSnapshot = {\n generation: 0,\n reason: null,\n status: 'idle',\n};\nconst relayTransportListeners = new Set<RelayTransportListener>();\n\nlet relayOperationActivitySnapshot: RelayOperationActivitySnapshot = {\n generation: 0,\n pendingCount: 0,\n pendingOperations: [],\n};\nlet relayOperationActivityId = 0;\nconst relayPendingOperations = new Map<number, RelayPendingOperation>();\nconst relayOperationActivityListeners =\n new Set<RelayOperationActivityListener>();\nlet relayOperationActivityNotifyScheduled = false;\n\n/**\n * No-op Relay field logger used to satisfy @required(action: LOG).\n */\nfunction noopRelayFieldLogger(): void {}\n\nlet relayFieldLogger: RelayFieldLogger = noopRelayFieldLogger;\n\nif (isDevEnv()) {\n relayFieldLogger = (event) => {\n // eslint-disable-next-line no-console\n console.log('relayFieldLogger: ', event);\n };\n}\n\nconst defaultGetDataId: (\n fieldValue: unknown,\n typeName: string,\n) => string | null = (fieldValue) => {\n if (fieldValue == null || typeof fieldValue !== 'object') {\n return null;\n }\n const { id } = fieldValue as { id?: unknown };\n if (typeof id !== 'string' || id.trim() === '') {\n return null;\n }\n return id;\n};\n\nconst getDataId = (fieldValue: unknown, typeName: string): string | null => {\n const customId = customDataIdResolver?.(fieldValue, typeName);\n if (customId != null) {\n return customId;\n }\n return defaultGetDataId(fieldValue, typeName);\n};\n\n/**\n * Notify subscribers that the Relay transport state changed.\n */\nfunction emitRelayTransportChange(\n status: RelayTransportStatus,\n reason: string | null,\n): void {\n relayTransportSnapshot = {\n generation: relayTransportSnapshot.generation + 1,\n reason,\n status,\n };\n for (const listener of relayTransportListeners) {\n listener();\n }\n}\n\n/**\n * Publish the latest Relay HTTP operation activity snapshot.\n */\nfunction emitRelayOperationActivityChange(): void {\n relayOperationActivitySnapshot = {\n generation: relayOperationActivitySnapshot.generation + 1,\n pendingCount: relayPendingOperations.size,\n pendingOperations: [...relayPendingOperations.values()],\n };\n if (relayOperationActivityNotifyScheduled) {\n return;\n }\n relayOperationActivityNotifyScheduled = true;\n queueMicrotask(() => {\n relayOperationActivityNotifyScheduled = false;\n for (const listener of relayOperationActivityListeners) {\n listener();\n }\n });\n}\n\n/**\n * Clear pending Relay HTTP operations after environment reconfiguration.\n */\nfunction resetRelayOperationActivity(): void {\n if (relayPendingOperations.size === 0) {\n return;\n }\n relayPendingOperations.clear();\n emitRelayOperationActivityChange();\n}\n\n/**\n * Normalize Relay operation kind values from runtime requests.\n */\nfunction resolveRelayOperationKind(operationKind: unknown): RelayOperationKind {\n if (operationKind === 'query' || operationKind === 'mutation') {\n return operationKind;\n }\n return 'unknown';\n}\n\n/**\n * Track a Relay HTTP operation until its returned disposer is called.\n */\nfunction startRelayOperationActivity(request: {\n name?: string | null;\n operationKind?: unknown;\n}): () => void {\n const id = relayOperationActivityId;\n relayOperationActivityId += 1;\n relayPendingOperations.set(id, {\n id,\n kind: resolveRelayOperationKind(request.operationKind),\n name: request.name ?? 'AnonymousGraphQLOperation',\n startedAt: Date.now(),\n });\n emitRelayOperationActivityChange();\n\n let isSettled = false;\n return () => {\n if (isSettled) {\n return;\n }\n isSettled = true;\n if (!relayPendingOperations.delete(id)) {\n return;\n }\n emitRelayOperationActivityChange();\n };\n}\n\n/**\n * Dispose the active websocket client and ignore shutdown failures.\n */\nfunction disposeWsClient(): void {\n if (wsClient == null) {\n return;\n }\n try {\n wsClient.dispose();\n } catch {\n // ignore errors during dispose\n }\n wsClient = undefined;\n}\n\n/** End every subscription owned by an environment that is being replaced. */\nfunction terminateWsClient(): void {\n if (wsClient == null) {\n return;\n }\n try {\n wsClient.terminate();\n } catch {\n // ignore errors during termination\n }\n wsClient = undefined;\n}\n\n/** Abort every HTTP operation owned by the current Relay environment. */\nfunction abortActiveHttpOperations(): void {\n for (const controller of activeHttpControllers) {\n controller.abort(new Error(ENVIRONMENT_ROTATED_ERROR));\n }\n activeHttpControllers.clear();\n}\n\n/** Remove all records from an environment while notifying its active selectors. */\nfunction clearEnvironmentStore(currentEnvironment: Environment): void {\n const store = currentEnvironment.getStore();\n const source = store.getSource();\n const deletedRecords = new RecordSource();\n\n for (const dataId of source.getRecordIDs()) {\n deletedRecords.delete(dataId);\n }\n try {\n if (deletedRecords.size() > 0) {\n store.publish(deletedRecords);\n store.notify();\n }\n } finally {\n if (source instanceof RecordSource) {\n source.clear();\n }\n }\n}\n\n/** Replace the shared environment and terminate work owned by its generation. */\nfunction rotateRelayEnvironment(\n status: RelayTransportStatus,\n reason: string,\n): void {\n const previousEnvironment = environment;\n environment = undefined;\n environmentGeneration += 1;\n abortActiveHttpOperations();\n terminateWsClient();\n try {\n if (previousEnvironment != null) {\n clearEnvironmentStore(previousEnvironment);\n }\n } finally {\n resetRelayOperationActivity();\n emitRelayTransportChange(status, reason);\n }\n}\n\n/**\n * Return the current Relay transport state used by subscription hooks.\n */\nexport function getRelayTransportSnapshot(): RelayTransportSnapshot {\n return relayTransportSnapshot;\n}\n\n/**\n * Subscribe to Relay transport changes.\n */\nexport function subscribeRelayTransport(\n listener: RelayTransportListener,\n): () => void {\n relayTransportListeners.add(listener);\n return () => {\n relayTransportListeners.delete(listener);\n };\n}\n\n/**\n * Return the current Relay HTTP operation activity snapshot.\n */\nexport function getRelayOperationActivitySnapshot(): RelayOperationActivitySnapshot {\n return relayOperationActivitySnapshot;\n}\n\n/**\n * Subscribe to Relay HTTP operation activity changes.\n */\nexport function subscribeRelayOperationActivity(\n listener: RelayOperationActivityListener,\n): () => void {\n relayOperationActivityListeners.add(listener);\n return () => {\n relayOperationActivityListeners.delete(listener);\n };\n}\n\n/**\n * Force the websocket transport to reconnect and notify mounted subscriptions.\n */\nexport function reconnectRelayWebSocket(\n options: RelayReconnectOptions = {},\n): void {\n disposeWsClient();\n emitRelayTransportChange(\n 'reconnecting',\n options.reason ?? 'manual_reconnect',\n );\n}\n\n/**\n * Refresh the active websocket authentication without recreating subscriptions.\n */\nexport async function refreshRelayWebSocketAuthentication(\n options: RelayAuthRefreshOptions = {},\n): Promise<void> {\n const client = wsClient;\n if (!client?.hasActiveConnection()) {\n return;\n }\n\n const refreshed = await client.refreshAuthentication();\n if (!refreshed) {\n reconnectRelayWebSocket({\n reason: options.reason ?? 'auth_refresh_fallback',\n });\n }\n}\n\nexport interface RelayEnvironmentConfiguration {\n httpUrl?: string;\n wsUrl?: string;\n logEvents?: boolean;\n getDataId?: (fieldValue: unknown, typeName: string) => string | null;\n getAuthHeaders?: (\n signal?: AbortSignal,\n ) => Record<string, string> | Promise<Record<string, string>>;\n fetchImpl?: typeof fetch;\n}\n\n/**\n * Configure the endpoints and logging behavior used by the shared Relay environment.\n */\nexport function configureRelayEnvironment(\n options: RelayEnvironmentConfiguration = {},\n): void {\n const {\n httpUrl,\n wsUrl,\n logEvents,\n getDataId: nextGetDataId,\n getAuthHeaders: nextGetAuthHeaders,\n fetchImpl: nextFetchImpl,\n } = options;\n\n if (typeof httpUrl === 'string' && httpUrl !== '') {\n graphqlHttpEndpoint = httpUrl;\n }\n\n if (typeof wsUrl === 'string' && wsUrl !== '') {\n graphqlWsEndpoint = wsUrl;\n }\n\n if (logEvents != null) {\n if (logEvents) {\n relayFieldLogger = (event) => {\n // eslint-disable-next-line no-console\n console.log('relayFieldLogger: ', event);\n };\n } else {\n relayFieldLogger = noopRelayFieldLogger;\n }\n }\n\n customDataIdResolver = nextGetDataId;\n getAuthHeaders = nextGetAuthHeaders;\n graphqlFetch = nextFetchImpl ?? defaultGraphqlFetch;\n\n rotateRelayEnvironment('configured', 'configure');\n}\n\n/**\n * Resolve the websocket endpoint into an absolute GraphQL WebSocket URL.\n */\nfunction resolveWebsocketUrl(): string {\n const endpoint = graphqlWsEndpoint;\n\n if (endpoint.startsWith('ws')) {\n return endpoint;\n }\n\n if (endpoint.startsWith('http')) {\n return endpoint.replace(/^http/, 'ws');\n }\n\n if (endpoint.startsWith('/')) {\n if (typeof window === 'undefined') {\n return endpoint;\n }\n let protocol = 'ws:';\n if (window.location.protocol === 'https:') {\n protocol = 'wss:';\n }\n return `${protocol}//${window.location.host}${endpoint}`;\n }\n\n return endpoint;\n}\n\n/** Debug log helper (no-op en production) */\nfunction debugLog(...args: unknown[]): void {\n if (isDevEnv()) {\n // eslint-disable-next-line no-console\n console.log('[RelayNetwork]', ...args);\n }\n}\n\n/** Resolve authentication headers for Relay HTTP and websocket transports. */\nasync function resolveAuthHeaders(): Promise<Record<string, string>> {\n if (getAuthHeaders == null) {\n return {};\n }\n return getAuthHeaders();\n}\n\nclass RelayWebSocketClient {\n private socket: WebSocket | null = null;\n\n private connectPromise: Promise<void> | null = null;\n\n private disposed = false;\n\n private acknowledged = false;\n\n private retryCount = 0;\n\n private nextId = 1;\n\n private keepAliveTimer: ReturnType<typeof setInterval> | null = null;\n\n private readonly subscriptions = new Map<string, ActiveSubscription>();\n\n private pendingAuthUpdate: {\n resolve: (value: boolean) => void;\n timeout: ReturnType<typeof setTimeout>;\n } | null = null;\n\n public constructor(private readonly url: string) {}\n\n public hasActiveConnection(): boolean {\n return this.socket?.readyState === WebSocket.OPEN && this.acknowledged;\n }\n\n public dispose(): void {\n this.disposed = true;\n this.resolvePendingAuthUpdate(false);\n this.stopKeepAlive();\n const { socket } = this;\n this.socket = null;\n this.connectPromise = null;\n this.acknowledged = false;\n if (socket != null && socket.readyState !== WebSocket.CLOSED) {\n socket.close(1000, 'Normal Closure');\n }\n }\n\n public terminate(): void {\n for (const subscription of this.subscriptions.values()) {\n try {\n subscription.sink.complete();\n } catch {\n // ignore subscriber failures while ending an environment\n }\n }\n this.subscriptions.clear();\n this.dispose();\n }\n\n public subscribe(\n payload: ActiveSubscription['payload'],\n sink: SubscriptionSink,\n ): () => void {\n const id = String(this.nextId);\n this.nextId += 1;\n this.subscriptions.set(id, { payload, sink });\n this.connectAndSubscribe(id).catch((error: unknown) => {\n debugLog('subscription websocket connect failed', error);\n this.scheduleReconnect();\n });\n\n return () => {\n this.unsubscribe(id);\n };\n }\n\n public async refreshAuthentication(): Promise<boolean> {\n if (!this.hasActiveConnection()) {\n return true;\n }\n const { socket } = this;\n if (socket == null) {\n return true;\n }\n if (this.pendingAuthUpdate != null) {\n return false;\n }\n\n let payload: Record<string, string>;\n try {\n payload = await resolveAuthHeaders();\n } catch {\n return false;\n }\n if (Object.keys(payload).length === 0) {\n return false;\n }\n\n return new Promise<boolean>((resolve) => {\n const timeout = setTimeout(() => {\n this.pendingAuthUpdate = null;\n resolve(false);\n }, AUTH_UPDATE_TIMEOUT_MS);\n this.pendingAuthUpdate = { resolve, timeout };\n this.send({\n type: 'connection_auth_update',\n payload,\n });\n });\n }\n\n private async connectAndSubscribe(id: string): Promise<void> {\n const wasConnected = this.hasActiveConnection();\n await this.ensureConnected();\n if (!wasConnected) {\n return;\n }\n const subscription = this.subscriptions.get(id);\n if (subscription == null) {\n return;\n }\n this.send({\n id,\n type: 'subscribe',\n payload: subscription.payload,\n });\n }\n\n private async ensureConnected(): Promise<void> {\n if (this.hasActiveConnection()) {\n return;\n }\n if (this.connectPromise != null) {\n await this.connectPromise;\n return;\n }\n\n this.connectPromise = this.openSocket();\n try {\n await this.connectPromise;\n } finally {\n this.connectPromise = null;\n }\n }\n\n private async openSocket(): Promise<void> {\n if (this.disposed) {\n throw new Error('WebSocket client is disposed');\n }\n\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n const resolveConnected = (): void => {\n if (settled) {\n return;\n }\n settled = true;\n resolve();\n };\n const rejectConnection = (error: unknown): void => {\n if (settled) {\n return;\n }\n settled = true;\n reject(error);\n };\n const socket = new WebSocket(this.url, GRAPHQL_TRANSPORT_WS_PROTOCOL);\n this.socket = socket;\n this.acknowledged = false;\n\n socket.onopen = () => {\n resolveAuthHeaders()\n .catch(() => {\n return {};\n })\n .then((payload) => {\n if (socket.readyState !== WebSocket.OPEN) {\n return;\n }\n if (Object.keys(payload).length > 0) {\n this.send({ type: 'connection_init', payload });\n return;\n }\n this.send({ type: 'connection_init' });\n })\n .catch((error: unknown) => {\n rejectConnection(error);\n });\n };\n\n socket.onerror = () => {\n rejectConnection(new Error('GraphQL subscription websocket error'));\n };\n\n socket.onmessage = (event) => {\n this.handleMessage(event.data, resolveConnected, rejectConnection);\n };\n\n socket.onclose = () => {\n rejectConnection(new Error('GraphQL subscription websocket closed'));\n this.handleClose();\n };\n });\n }\n\n private handleMessage(\n data: unknown,\n connected: () => void,\n rejected: (error: unknown) => void,\n ): void {\n let parsed: unknown;\n try {\n parsed = JSON.parse(String(data));\n } catch {\n rejected(new Error('Invalid GraphQL websocket message'));\n this.socket?.close(4400, 'Invalid websocket message');\n return;\n }\n\n const decoded = decodeGraphqlWsMessage(parsed);\n if (!decoded.ok) {\n const unsupported = decoded.reason === 'unsupported';\n let errorMessage = 'Invalid GraphQL websocket message';\n let closeMessage = 'Invalid websocket message';\n if (unsupported) {\n errorMessage = 'Unsupported GraphQL websocket message';\n closeMessage = 'Unsupported websocket message';\n }\n rejected(new Error(errorMessage));\n this.socket?.close(4400, closeMessage);\n return;\n }\n const message = decoded.value;\n\n switch (message.type) {\n case 'connection_ack':\n this.acknowledged = true;\n this.retryCount = 0;\n this.startKeepAlive();\n connected();\n this.resubscribeActiveOperations();\n return;\n case 'connection_auth_update_ack':\n this.resolvePendingAuthUpdate(true);\n return;\n case 'next':\n this.subscriptions.get(message.id)?.sink.next(message.payload);\n return;\n case 'error':\n if (message.id != null) {\n this.failSubscription(message.id, message.payload);\n } else {\n this.resolvePendingAuthUpdate(false);\n }\n return;\n case 'complete':\n this.completeSubscription(message.id);\n return;\n case 'ping':\n this.send({ type: 'pong', payload: message.payload });\n break;\n case 'pong':\n break;\n default:\n break;\n }\n }\n\n private handleClose(): void {\n this.acknowledged = false;\n this.socket = null;\n this.connectPromise = null;\n this.stopKeepAlive();\n this.resolvePendingAuthUpdate(false);\n if (!this.disposed && this.subscriptions.size > 0) {\n this.scheduleReconnect();\n }\n }\n\n private scheduleReconnect(): void {\n if (this.retryCount >= WS_MAX_RETRY_ATTEMPTS) {\n const error = new Error('GraphQL subscription websocket retry exhausted');\n for (const id of [...this.subscriptions.keys()]) {\n this.failSubscription(id, error);\n }\n return;\n }\n const delay =\n Math.min(8_000, WS_BASE_RETRY_DELAY_MS * 2 ** this.retryCount) +\n Math.random() * 200;\n this.retryCount += 1;\n setTimeout(() => {\n if (this.disposed || this.subscriptions.size === 0) {\n return;\n }\n this.ensureConnected().catch((error: unknown) => {\n this.scheduleReconnect();\n debugLog('subscription websocket reconnect failed', error);\n });\n }, delay);\n }\n\n private resubscribeActiveOperations(): void {\n for (const [id, subscription] of this.subscriptions) {\n this.send({\n id,\n type: 'subscribe',\n payload: subscription.payload,\n });\n }\n }\n\n private unsubscribe(id: string): void {\n const hadSubscription = this.subscriptions.delete(id);\n if (hadSubscription && this.socket?.readyState === WebSocket.OPEN) {\n this.send({ id, type: 'complete' });\n }\n }\n\n private failSubscription(id: string, error: unknown): void {\n const subscription = this.subscriptions.get(id);\n if (subscription == null) {\n return;\n }\n this.subscriptions.delete(id);\n subscription.sink.error(error);\n }\n\n private completeSubscription(id: string): void {\n const subscription = this.subscriptions.get(id);\n if (subscription == null) {\n return;\n }\n this.subscriptions.delete(id);\n subscription.sink.complete();\n }\n\n private startKeepAlive(): void {\n this.stopKeepAlive();\n this.keepAliveTimer = setInterval(() => {\n if (this.socket?.readyState === WebSocket.OPEN) {\n this.send({ type: 'ping' });\n }\n }, WS_KEEP_ALIVE_MS);\n }\n\n private stopKeepAlive(): void {\n if (this.keepAliveTimer != null) {\n clearInterval(this.keepAliveTimer);\n this.keepAliveTimer = null;\n }\n }\n\n private resolvePendingAuthUpdate(value: boolean): void {\n const pending = this.pendingAuthUpdate;\n if (pending == null) {\n return;\n }\n clearTimeout(pending.timeout);\n this.pendingAuthUpdate = null;\n pending.resolve(value);\n }\n\n private send(message: GraphqlWsPayload): void {\n const { socket } = this;\n if (socket?.readyState !== WebSocket.OPEN) {\n return;\n }\n socket.send(JSON.stringify(message));\n }\n}\n\n/**\n * Build or get a singleton graphql-transport-ws client with auth refresh support.\n */\nfunction getWsClient(): RelayWebSocketClient {\n if (wsClient != null) {\n return wsClient;\n }\n if (typeof window === 'undefined') {\n throw new Error(\n 'GraphQL subscriptions unavailable in non-browser environment',\n );\n }\n\n const url = resolveWebsocketUrl();\n wsClient = new RelayWebSocketClient(url);\n\n return wsClient;\n}\n\n/**\n * Get organization slug from current window location\n */\n// export function getOrganizationSlug(): string | null {\n// const { pathname } = window.location;\n// const slug = pathname.split('/')[1];\n// if (slug == null) {\n// return null;\n// }\n\n// return slug;\n// }\n\n// -------------------------\n// Upload detection helpers\n// -------------------------\n/** Test if a value is an uploadable (File/Blob) */\nfunction isUploadable(value: unknown): value is File | Blob {\n return (\n (typeof File !== 'undefined' && value instanceof File) ||\n (typeof Blob !== 'undefined' && value instanceof Blob)\n );\n}\n\ninterface FileRef {\n path: string; // JSON pointer-like (e.g. variables.input.file)\n file: File | Blob;\n}\n\n/** Recursively clone a structure replacing files with null and collecting them */\nfunction collectFiles(value: unknown, path: string, acc: FileRef[]): unknown {\n if (isUploadable(value)) {\n acc.push({ path, file: value });\n return null; // placeholder per multipart spec\n }\n if (Array.isArray(value)) {\n return value.map((v, i) => {\n return collectFiles(v, `${path}.${i}`, acc);\n });\n }\n if (value != null && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = collectFiles(v, `${path}.${k}`, acc);\n }\n return out;\n }\n return value; // primitives unchanged\n}\n\n/** Build GraphQL multipart form-data payload */\nfunction buildFormData(\n query: string,\n variables: Record<string, unknown>,\n): FormData {\n const files: FileRef[] = [];\n // Deep clone variables while replacing files with null\n const clonedVars = collectFiles(variables, 'variables', files) as Record<\n string,\n unknown\n >;\n\n const form = new FormData();\n const operations = { query, variables: clonedVars };\n form.append('operations', JSON.stringify(operations));\n\n const map: Record<string, string[]> = {};\n files.forEach((ref, idx) => {\n map[idx] = [ref.path];\n });\n form.append('map', JSON.stringify(map));\n files.forEach((ref, idx) => {\n form.append(String(idx), ref.file);\n });\n return form;\n}\n\n// -------------------------\n// Retry / timeout helpers\n// -------------------------\ninterface RetryOptions {\n maxAttempts: number; // total attempts including initial\n baseDelayMs: number;\n maxDelayMs: number;\n fetchTimeoutMs: number;\n}\n\nconst RETRY_OPTIONS: RetryOptions = {\n maxAttempts: 3,\n baseDelayMs: 300,\n maxDelayMs: 4000,\n fetchTimeoutMs: 600_000, // 10 minutes (parité avec ancien middleware)\n};\n\n/** Sleep helper that ends immediately when its owning operation is cancelled. */\nasync function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n if (signal?.aborted === true) {\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n return;\n }\n const timeout = setTimeout(resolve, ms);\n signal?.addEventListener(\n 'abort',\n () => {\n clearTimeout(timeout);\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n },\n { once: true },\n );\n });\n}\n\n/** Exponential backoff with jitter */\nfunction calcBackoff(attempt: number, opts: RetryOptions): number {\n const exp = Math.min(opts.maxDelayMs, opts.baseDelayMs * 2 ** attempt);\n return exp + Math.random() * 0.2 * exp; // jitter 0-20%\n}\n\n/** Determine if an HTTP status is retryable */\nfunction isRetryableStatus(status: number): boolean {\n return status === 408 || status === 429 || (status >= 500 && status < 600);\n}\n\n/** Determine if an error should be treated as transient network issue */\nfunction isNetworkError(err: unknown): boolean {\n return (\n err instanceof TypeError ||\n (err instanceof Error && err.name === 'AbortError')\n );\n}\n\n// -------------------------\n// fetchFn implementation\n// -------------------------\ninterface GraphQLResponseErrorItem {\n [key: string]: unknown;\n message: string;\n path?: readonly unknown[];\n}\n\ninterface GraphQLResponseShape<T = unknown> {\n data?: T;\n errors?: GraphQLResponseErrorItem[];\n extensions?: Record<string, unknown>;\n}\n\nexport class GraphQLResponseError extends Error {\n public constructor(\n public readonly errors: readonly GraphQLResponseErrorItem[],\n public readonly response: GraphQLResponseShape,\n ) {\n super(errors[0]?.message ?? 'GraphQL response error');\n this.name = 'GraphQLResponseError';\n }\n}\n\n/** Determine whether a GraphQL payload includes non-null top-level data. */\nfunction hasUsableTopLevelData(data: unknown): boolean {\n if (data == null) {\n return false;\n }\n if (typeof data !== 'object') {\n return true;\n }\n return Object.values(data as Record<string, unknown>).some((value) => {\n return value != null;\n });\n}\n\n/** Determine whether all errors are child-field errors under top-level null data. */\nfunction hasOnlyErrorsBelowNullTopLevelFields(\n response: GraphQLResponseShape,\n): boolean {\n const { data, errors } = response;\n if (\n data == null ||\n typeof data !== 'object' ||\n !Array.isArray(errors) ||\n errors.length === 0\n ) {\n return false;\n }\n\n const dataRecord = data as Record<string, unknown>;\n return errors.every((error) => {\n const [topLevelField, ...childPath] = error.path ?? [];\n if (typeof topLevelField !== 'string' || childPath.length === 0) {\n return false;\n }\n return (\n Object.prototype.hasOwnProperty.call(dataRecord, topLevelField) &&\n dataRecord[topLevelField] == null\n );\n });\n}\n\n/** Determine whether GraphQL errors should be surfaced as a thrown response error. */\nfunction shouldThrowGraphQLResponseError(\n response: GraphQLResponseShape,\n): boolean {\n return (\n Array.isArray(response.errors) &&\n response.errors.length > 0 &&\n !hasUsableTopLevelData(response.data) &&\n !hasOnlyErrorsBelowNullTopLevelFields(response)\n );\n}\n\n/** Fetch GraphQL (with retry + upload) */\nasync function fetchFn(\n request: {\n name?: string | null;\n operationKind?: unknown;\n text: string | null | undefined;\n },\n variables: Record<string, unknown>,\n _cacheConfig: unknown,\n _uploadables: unknown,\n operationController: AbortController = new AbortController(),\n): Promise<GraphQLResponseShape> {\n const operationEnvironmentGeneration = environmentGeneration;\n const queryText: string | null | undefined = request.text; // no persisted queries here (yet)\n if (queryText == null) {\n throw new Error('Missing GraphQL query text');\n }\n const safeQueryText: string = queryText; // narrowed non-null\n const stopRelayOperationActivity = startRelayOperationActivity(request);\n activeHttpControllers.add(operationController);\n\n const operationState = { authHeadersFailed: false };\n\n /** Execute one network attempt */\n async function execOnce(attempt: number): Promise<GraphQLResponseShape> {\n if (operationEnvironmentGeneration !== environmentGeneration) {\n throw new Error(ENVIRONMENT_ROTATED_ERROR);\n }\n if (operationController.signal.aborted) {\n throw (\n operationController.signal.reason ??\n new DOMException('Aborted', 'AbortError')\n );\n }\n const controller = new AbortController();\n const abortAttempt = (): void => {\n controller.abort(operationController.signal.reason);\n };\n operationController.signal.addEventListener('abort', abortAttempt, {\n once: true,\n });\n const timeout = setTimeout(() => {\n controller.abort();\n }, RETRY_OPTIONS.fetchTimeoutMs);\n try {\n let body: BodyInit;\n const headers: Record<string, string> = {};\n if (getAuthHeaders != null) {\n try {\n Object.assign(\n headers,\n await getAuthHeaders(operationController.signal),\n );\n } catch (error: unknown) {\n operationState.authHeadersFailed = true;\n throw error;\n }\n }\n if (operationEnvironmentGeneration !== environmentGeneration) {\n throw new Error(ENVIRONMENT_ROTATED_ERROR);\n }\n controller.signal.throwIfAborted();\n const hasFiles = ((): boolean => {\n try {\n const stack: unknown[] = [variables];\n while (stack.length > 0) {\n const v = stack.pop();\n if (isUploadable(v)) {\n return true;\n }\n if (Array.isArray(v)) {\n stack.push(...v);\n } else if (v != null && typeof v === 'object') {\n stack.push(...Object.values(v as Record<string, unknown>));\n }\n }\n } catch {\n // ignore traversal errors\n }\n return false;\n })();\n\n if (hasFiles) {\n body = buildFormData(safeQueryText, variables);\n headers[GRAPHQL_CSRF_PREFLIGHT_HEADER] =\n GRAPHQL_CSRF_PREFLIGHT_HEADER_VALUE;\n } else {\n headers['Content-Type'] = 'application/json';\n body = JSON.stringify({ query: safeQueryText, variables });\n }\n\n const response = await graphqlFetch(graphqlHttpEndpoint, {\n method: 'POST',\n body,\n headers,\n credentials: 'include',\n signal: controller.signal,\n });\n\n if (operationEnvironmentGeneration !== environmentGeneration) {\n throw new Error(ENVIRONMENT_ROTATED_ERROR);\n }\n\n if (!response.ok) {\n if (\n attempt < RETRY_OPTIONS.maxAttempts - 1 &&\n isRetryableStatus(response.status)\n ) {\n throw new Error(`Retryable HTTP status ${response.status}`);\n }\n const text = await response.text().catch(() => {\n return '';\n });\n throw new Error(`GraphQL HTTP error ${response.status}: ${text}`);\n }\n\n const json: GraphQLResponseShape = await response.json();\n if (Array.isArray(json.errors) && json.errors.length > 0) {\n debugLog('GraphQL errors', json.errors);\n }\n if (shouldThrowGraphQLResponseError(json)) {\n throw new GraphQLResponseError(json.errors ?? [], json);\n }\n return json;\n } finally {\n clearTimeout(timeout);\n operationController.signal.removeEventListener('abort', abortAttempt);\n }\n }\n\n try {\n for (let attempt = 0; attempt < RETRY_OPTIONS.maxAttempts; attempt += 1) {\n try {\n return await execOnce(attempt);\n } catch (err) {\n if (operationState.authHeadersFailed) {\n throw err;\n }\n if (operationController.signal.aborted) {\n throw operationController.signal.reason ?? err;\n }\n if (operationEnvironmentGeneration !== environmentGeneration) {\n throw new Error(ENVIRONMENT_ROTATED_ERROR, { cause: err });\n }\n const last = attempt === RETRY_OPTIONS.maxAttempts - 1;\n const retryable =\n isNetworkError(err) ||\n (err instanceof Error &&\n err.message.includes('Retryable HTTP status'));\n if (!retryable || last) {\n debugLog('GraphQL fetch error', err);\n throw err;\n }\n const delay = calcBackoff(attempt, RETRY_OPTIONS);\n await sleep(delay, operationController.signal);\n }\n }\n throw new Error('Exhausted retries without returning a result');\n } finally {\n activeHttpControllers.delete(operationController);\n stopRelayOperationActivity();\n }\n}\n\n/** Relay fetch function whose disposal cancels the complete HTTP retry lifecycle. */\nfunction observableFetchFn(\n request: Parameters<typeof fetchFn>[0],\n variables: Parameters<typeof fetchFn>[1],\n cacheConfig: Parameters<typeof fetchFn>[2],\n uploadables: Parameters<typeof fetchFn>[3],\n): Observable<GraphQLResponseShape> {\n return Observable.create<GraphQLResponseShape>((sink) => {\n const controller = new AbortController();\n let disposed = false;\n fetchFn(request, variables, cacheConfig, uploadables, controller).then(\n (response) => {\n if (disposed) {\n return;\n }\n sink.next(response);\n sink.complete();\n },\n (error: unknown) => {\n if (!disposed) {\n let relayError: Error;\n if (error instanceof Error) {\n relayError = error;\n } else {\n relayError = new Error(String(error));\n }\n sink.error(relayError);\n }\n },\n );\n return () => {\n disposed = true;\n controller.abort(\n new DOMException('Relay operation disposed', 'AbortError'),\n );\n };\n });\n}\n\n// -------------------------\n// subscribeFn implementation (wrap existing logic in Relay Observable)\n// -------------------------\n/** Subscription function bridging the owned GraphQL WebSocket client to Relay. */\nfunction subscribeFn(\n operation: { text: string | null | undefined; name: string },\n variables: Record<string, unknown>,\n): Observable<unknown> {\n debugLog('subscription:start', operation.name, variables);\n return Observable.create<unknown>((sink) => {\n const query = operation.text;\n if (query == null || query === '') {\n sink.error(new Error('Subscription operation text is empty'));\n return () => {\n // noop\n };\n }\n const client = getWsClient();\n const dispose = client.subscribe(\n { query, variables, operationName: operation.name },\n {\n next: (data) => {\n sink.next(data);\n },\n error: (err) => {\n let errorObj: Error;\n if (err instanceof Error) {\n errorObj = err;\n } else {\n errorObj = new Error('Subscription error');\n }\n sink.error(errorObj);\n },\n complete: () => {\n sink.complete();\n },\n },\n );\n return () => {\n dispose();\n };\n });\n}\n\n/**\n * Create native Relay network layer (fetch + subscribe)\n */\nexport function getNetwork(): ReturnType<typeof Network.create> {\n return Network.create(\n observableFetchFn as FetchFunction,\n subscribeFn as SubscribeFunction,\n );\n}\n\n/**\n * Get anonymous relay environment\n */\nexport function getEnvironment(): Environment {\n environment ??= new Environment({\n getDataID: getDataId,\n relayFieldLogger,\n network: getNetwork(),\n store: new Store(new RecordSource()),\n });\n\n return environment;\n}\n\n/**\n * End the current Relay session and expose a new empty environment.\n */\nexport function resetRelayStore(): void {\n rotateRelayEnvironment('configured', 'session_reset');\n}\n\nexport const __test = {\n RelayWebSocketClient,\n buildFormData,\n calcBackoff,\n collectFiles,\n decodeGraphqlWsMessage,\n fetchFn,\n getDataId,\n hasUsableTopLevelData,\n isNetworkError,\n isRetryableStatus,\n isUploadable,\n shouldThrowGraphQLResponseError,\n observableFetchFn,\n subscribeFn,\n};\n"],"mappings":"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"}
|
|
@@ -82,7 +82,7 @@ export interface RelayEnvironmentConfiguration {
|
|
|
82
82
|
wsUrl?: string;
|
|
83
83
|
logEvents?: boolean;
|
|
84
84
|
getDataId?: (fieldValue: unknown, typeName: string) => string | null;
|
|
85
|
-
getAuthHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
|
|
85
|
+
getAuthHeaders?: (signal?: AbortSignal) => Record<string, string> | Promise<Record<string, string>>;
|
|
86
86
|
fetchImpl?: typeof fetch;
|
|
87
87
|
}
|
|
88
88
|
export declare function configureRelayEnvironment(options?: RelayEnvironmentConfiguration): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,OAAO,EACP,UAAU,EAMX,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/environment.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plumile/relay",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"description": "Shared Relay runtime helpers for Plumile applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"tslib": "^2.8.1"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
|
-
"@plumile/auth": "^0.2.
|
|
63
|
+
"@plumile/auth": "^0.2.8",
|
|
64
64
|
"@types/react": "19.2.18",
|
|
65
65
|
"@types/react-dom": "19.2.7",
|
|
66
66
|
"@types/relay-runtime": "20.1.1",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"rimraf": "6.1.3"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
|
-
"@plumile/auth": "^0.2.
|
|
75
|
+
"@plumile/auth": "^0.2.7",
|
|
76
76
|
"react": "^19.2.8",
|
|
77
77
|
"react-relay": "^21.0.1",
|
|
78
78
|
"relay-runtime": "^21.0.1"
|