@plumile/relay 0.1.205 → 0.2.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/README.md CHANGED
@@ -11,6 +11,10 @@ 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
+ Relay query disposal aborts the active HTTP attempt and the complete retry
15
+ lifecycle, including a pending backoff. Disposed operations never publish a
16
+ late response or error to their observer.
17
+
14
18
  ## WebSocket transport contract
15
19
 
16
20
  Subscriptions use the `graphql-transport-ws` subprotocol through the package's
@@ -1,7 +1,7 @@
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, g = "require-preflight", ee = "true", te = (e) => typeof e == "object" && !!e && !Array.isArray(e), _ = (e) => {
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", g = "true", te = (e) => typeof e == "object" && !!e && !Array.isArray(e), _ = (e) => {
5
5
  if (!te(e) || typeof e.type != "string") return {
6
6
  ok: !1,
7
7
  reason: "invalid"
@@ -134,7 +134,7 @@ function de() {
134
134
  }
135
135
  }
136
136
  function fe() {
137
- for (let e of d) e.abort();
137
+ for (let e of d) e.abort(/* @__PURE__ */ Error(v));
138
138
  d.clear();
139
139
  }
140
140
  function pe(e) {
@@ -163,28 +163,28 @@ function he(e) {
163
163
  b.delete(e);
164
164
  };
165
165
  }
166
- function N() {
166
+ function ge() {
167
167
  return x;
168
168
  }
169
- function P(e) {
169
+ function N(e) {
170
170
  return w.add(e), () => {
171
171
  w.delete(e);
172
172
  };
173
173
  }
174
- function F(e = {}) {
174
+ function P(e = {}) {
175
175
  ue(), A("reconnecting", e.reason ?? "manual_reconnect");
176
176
  }
177
- async function I(e = {}) {
177
+ async function F(e = {}) {
178
178
  let t = l;
179
- t?.hasActiveConnection() && (await t.refreshAuthentication() || F({ reason: e.reason ?? "auth_refresh_fallback" }));
179
+ t?.hasActiveConnection() && (await t.refreshAuthentication() || P({ reason: e.reason ?? "auth_refresh_fallback" }));
180
180
  }
181
- function L(e = {}) {
181
+ function I(e = {}) {
182
182
  let { httpUrl: t, wsUrl: n, logEvents: r, getDataId: i, getAuthHeaders: a, fetchImpl: c } = e;
183
183
  typeof t == "string" && t !== "" && (o = t), typeof n == "string" && n !== "" && (s = n), r != null && (D = r ? (e) => {
184
184
  console.log("relayFieldLogger: ", e);
185
185
  } : E), h = i, f = a, m = c ?? p, M("configured", "configure");
186
186
  }
187
- function ge() {
187
+ function _e() {
188
188
  let e = s;
189
189
  if (e.startsWith("ws")) return e;
190
190
  if (e.startsWith("http")) return e.replace(/^http/, "ws");
@@ -195,13 +195,13 @@ function ge() {
195
195
  }
196
196
  return e;
197
197
  }
198
- function R(...t) {
198
+ function L(...t) {
199
199
  e() && console.log("[RelayNetwork]", ...t);
200
200
  }
201
- async function z() {
201
+ async function R() {
202
202
  return f == null ? {} : f();
203
203
  }
204
- var B = class {
204
+ var z = class {
205
205
  url;
206
206
  socket = null;
207
207
  connectPromise = null;
@@ -235,7 +235,7 @@ var B = class {
235
235
  payload: e,
236
236
  sink: t
237
237
  }), this.connectAndSubscribe(n).catch((e) => {
238
- R("subscription websocket connect failed", e), this.scheduleReconnect();
238
+ L("subscription websocket connect failed", e), this.scheduleReconnect();
239
239
  }), () => {
240
240
  this.unsubscribe(n);
241
241
  };
@@ -247,7 +247,7 @@ var B = class {
247
247
  if (this.pendingAuthUpdate != null) return !1;
248
248
  let t;
249
249
  try {
250
- t = await z();
250
+ t = await R();
251
251
  } catch {
252
252
  return !1;
253
253
  }
@@ -297,7 +297,7 @@ var B = class {
297
297
  n || (n = !0, t(e));
298
298
  }, a = new WebSocket(this.url, ne);
299
299
  this.socket = a, this.acknowledged = !1, a.onopen = () => {
300
- z().catch(() => ({})).then((e) => {
300
+ R().catch(() => ({})).then((e) => {
301
301
  if (a.readyState === WebSocket.OPEN) {
302
302
  if (Object.keys(e).length > 0) {
303
303
  this.send({
@@ -369,7 +369,7 @@ var B = class {
369
369
  let e = Math.min(8e3, oe * 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
- this.scheduleReconnect(), R("subscription websocket reconnect failed", e);
372
+ this.scheduleReconnect(), L("subscription websocket reconnect failed", e);
373
373
  });
374
374
  }, e);
375
375
  }
@@ -411,29 +411,29 @@ var B = class {
411
411
  t?.readyState === WebSocket.OPEN && t.send(JSON.stringify(e));
412
412
  }
413
413
  };
414
- function _e() {
414
+ function ve() {
415
415
  if (l != null) return l;
416
416
  if (typeof window > "u") throw Error("GraphQL subscriptions unavailable in non-browser environment");
417
- return l = new B(ge()), l;
417
+ return l = new z(_e()), l;
418
418
  }
419
- function V(e) {
419
+ function B(e) {
420
420
  return typeof File < "u" && e instanceof File || typeof Blob < "u" && e instanceof Blob;
421
421
  }
422
- function H(e, t, n) {
423
- if (V(e)) return n.push({
422
+ function V(e, t, n) {
423
+ if (B(e)) return n.push({
424
424
  path: t,
425
425
  file: e
426
426
  }), null;
427
- if (Array.isArray(e)) return e.map((e, r) => H(e, `${t}.${r}`, n));
427
+ if (Array.isArray(e)) return e.map((e, r) => V(e, `${t}.${r}`, n));
428
428
  if (typeof e == "object" && e) {
429
429
  let r = {};
430
- for (let [i, a] of Object.entries(e)) r[i] = H(a, `${t}.${i}`, n);
430
+ for (let [i, a] of Object.entries(e)) r[i] = V(a, `${t}.${i}`, n);
431
431
  return r;
432
432
  }
433
433
  return e;
434
434
  }
435
- function U(e, t) {
436
- let n = [], r = H(t, "variables", n), i = new FormData(), a = {
435
+ function H(e, t) {
436
+ let n = [], r = V(t, "variables", n), i = new FormData(), a = {
437
437
  query: e,
438
438
  variables: r
439
439
  };
@@ -445,40 +445,45 @@ function U(e, t) {
445
445
  i.append(String(t), e.file);
446
446
  }), i;
447
447
  }
448
- var W = {
448
+ var U = {
449
449
  maxAttempts: 3,
450
450
  baseDelayMs: 300,
451
451
  maxDelayMs: 4e3,
452
452
  fetchTimeoutMs: 6e5
453
453
  };
454
- async function ve(e) {
455
- await new Promise((t) => {
456
- setTimeout(() => {
457
- t();
458
- }, e);
454
+ async function ye(e, t) {
455
+ await new Promise((n, r) => {
456
+ if (t?.aborted === !0) {
457
+ r(t.reason ?? new DOMException("Aborted", "AbortError"));
458
+ return;
459
+ }
460
+ let i = setTimeout(n, e);
461
+ t?.addEventListener("abort", () => {
462
+ clearTimeout(i), r(t.reason ?? new DOMException("Aborted", "AbortError"));
463
+ }, { once: !0 });
459
464
  });
460
465
  }
461
- function G(e, t) {
466
+ function W(e, t) {
462
467
  let n = Math.min(t.maxDelayMs, t.baseDelayMs * 2 ** e);
463
468
  return n + Math.random() * .2 * n;
464
469
  }
465
- function K(e) {
470
+ function G(e) {
466
471
  return e === 408 || e === 429 || e >= 500 && e < 600;
467
472
  }
468
- function q(e) {
473
+ function K(e) {
469
474
  return e instanceof TypeError || e instanceof Error && e.name === "AbortError";
470
475
  }
471
- var J = class extends Error {
476
+ var q = class extends Error {
472
477
  errors;
473
478
  response;
474
479
  constructor(e, t) {
475
480
  super(e[0]?.message ?? "GraphQL response error"), this.errors = e, this.response = t, this.name = "GraphQLResponseError";
476
481
  }
477
482
  };
478
- function Y(e) {
483
+ function J(e) {
479
484
  return e == null ? !1 : typeof e != "object" || Object.values(e).some((e) => e != null);
480
485
  }
481
- function ye(e) {
486
+ function be(e) {
482
487
  let { data: t, errors: n } = e;
483
488
  if (typeof t != "object" || !t || !Array.isArray(n) || n.length === 0) return !1;
484
489
  let r = t;
@@ -487,79 +492,99 @@ function ye(e) {
487
492
  return typeof t != "string" || n.length === 0 ? !1 : Object.prototype.hasOwnProperty.call(r, t) && r[t] == null;
488
493
  });
489
494
  }
490
- function X(e) {
491
- return Array.isArray(e.errors) && e.errors.length > 0 && !Y(e.data) && !ye(e);
492
- }
493
- async function Z(e, t, n, r) {
494
- let i = u, a = e.text;
495
- if (a == null) throw Error("Missing GraphQL query text");
496
- let s = a, c = le(e);
497
- async function l(e) {
498
- if (i !== u) throw Error(v);
499
- let n = new AbortController();
500
- d.add(n);
501
- let r = setTimeout(() => {
495
+ function Y(e) {
496
+ return Array.isArray(e.errors) && e.errors.length > 0 && !J(e.data) && !be(e);
497
+ }
498
+ async function X(e, t, n, r, i = new AbortController()) {
499
+ let a = u, s = e.text;
500
+ if (s == null) throw Error("Missing GraphQL query text");
501
+ let c = s, l = le(e);
502
+ d.add(i);
503
+ async function p(e) {
504
+ if (a !== u) throw Error(v);
505
+ if (i.signal.aborted) throw i.signal.reason ?? new DOMException("Aborted", "AbortError");
506
+ let n = new AbortController(), r = () => {
507
+ n.abort(i.signal.reason);
508
+ };
509
+ i.signal.addEventListener("abort", r, { once: !0 });
510
+ let s = setTimeout(() => {
502
511
  n.abort();
503
- }, W.fetchTimeoutMs);
512
+ }, U.fetchTimeoutMs);
504
513
  try {
505
- let r, a = {};
514
+ let r, i = {};
506
515
  if (f != null) try {
507
- Object.assign(a, await f());
516
+ Object.assign(i, await f());
508
517
  } catch {}
509
- if (i !== u) throw Error(v);
518
+ if (a !== u) throw Error(v);
510
519
  (() => {
511
520
  try {
512
521
  let e = [t];
513
522
  for (; e.length > 0;) {
514
523
  let t = e.pop();
515
- if (V(t)) return !0;
524
+ if (B(t)) return !0;
516
525
  Array.isArray(t) ? e.push(...t) : typeof t == "object" && t && e.push(...Object.values(t));
517
526
  }
518
527
  } catch {}
519
528
  return !1;
520
- })() ? (r = U(s, t), a[g] = ee) : (a["Content-Type"] = "application/json", r = JSON.stringify({
521
- query: s,
529
+ })() ? (r = H(c, t), i[ee] = g) : (i["Content-Type"] = "application/json", r = JSON.stringify({
530
+ query: c,
522
531
  variables: t
523
532
  }));
524
- let c = await m(o, {
533
+ let s = await m(o, {
525
534
  method: "POST",
526
535
  body: r,
527
- headers: a,
536
+ headers: i,
528
537
  credentials: "include",
529
538
  signal: n.signal
530
539
  });
531
- if (i !== u) throw Error(v);
532
- if (!c.ok) {
533
- if (e < W.maxAttempts - 1 && K(c.status)) throw Error(`Retryable HTTP status ${c.status}`);
534
- let t = await c.text().catch(() => "");
535
- throw Error(`GraphQL HTTP error ${c.status}: ${t}`);
540
+ if (a !== u) throw Error(v);
541
+ if (!s.ok) {
542
+ if (e < U.maxAttempts - 1 && G(s.status)) throw Error(`Retryable HTTP status ${s.status}`);
543
+ let t = await s.text().catch(() => "");
544
+ throw Error(`GraphQL HTTP error ${s.status}: ${t}`);
536
545
  }
537
- let l = await c.json();
538
- if (Array.isArray(l.errors) && l.errors.length > 0 && R("GraphQL errors", l.errors), X(l)) throw new J(l.errors ?? [], l);
546
+ let l = await s.json();
547
+ if (Array.isArray(l.errors) && l.errors.length > 0 && L("GraphQL errors", l.errors), Y(l)) throw new q(l.errors ?? [], l);
539
548
  return l;
540
549
  } finally {
541
- clearTimeout(r), d.delete(n);
550
+ clearTimeout(s), i.signal.removeEventListener("abort", r);
542
551
  }
543
552
  }
544
553
  try {
545
- for (let e = 0; e < W.maxAttempts; e += 1) try {
546
- return await l(e);
554
+ for (let e = 0; e < U.maxAttempts; e += 1) try {
555
+ return await p(e);
547
556
  } catch (t) {
548
- if (i !== u) throw Error(v, { cause: t });
549
- let n = e === W.maxAttempts - 1;
550
- if (!(q(t) || t instanceof Error && t.message.includes("Retryable HTTP status")) || n) throw R("GraphQL fetch error", t), t;
551
- await ve(G(e, W));
557
+ if (i.signal.aborted) throw i.signal.reason ?? t;
558
+ if (a !== u) throw Error(v, { cause: t });
559
+ let n = e === U.maxAttempts - 1;
560
+ if (!(K(t) || t instanceof Error && t.message.includes("Retryable HTTP status")) || n) throw L("GraphQL fetch error", t), t;
561
+ await ye(W(e, U), i.signal);
552
562
  }
553
563
  throw Error("Exhausted retries without returning a result");
554
564
  } finally {
555
- c();
565
+ d.delete(i), l();
556
566
  }
557
567
  }
568
+ function Z(e, t, n, i) {
569
+ return r.create((r) => {
570
+ let a = new AbortController(), o = !1;
571
+ return X(e, t, n, i, a).then((e) => {
572
+ o || (r.next(e), r.complete());
573
+ }, (e) => {
574
+ if (!o) {
575
+ let t;
576
+ t = e instanceof Error ? e : Error(String(e)), r.error(t);
577
+ }
578
+ }), () => {
579
+ o = !0, a.abort(new DOMException("Relay operation disposed", "AbortError"));
580
+ };
581
+ });
582
+ }
558
583
  function Q(e, t) {
559
- return R("subscription:start", e.name, t), r.create((n) => {
584
+ return L("subscription:start", e.name, t), r.create((n) => {
560
585
  let r = e.text;
561
586
  if (r == null || r === "") return n.error(/* @__PURE__ */ Error("Subscription operation text is empty")), () => {};
562
- let i = _e().subscribe({
587
+ let i = ve().subscribe({
563
588
  query: r,
564
589
  variables: t,
565
590
  operationName: e.name
@@ -583,7 +608,7 @@ function Q(e, t) {
583
608
  function $() {
584
609
  return n.create(Z, Q);
585
610
  }
586
- function be() {
611
+ function xe() {
587
612
  return c ??= new t({
588
613
  getDataID: k,
589
614
  relayFieldLogger: D,
@@ -591,25 +616,26 @@ function be() {
591
616
  store: new a(new i())
592
617
  }), c;
593
618
  }
594
- function xe() {
619
+ function Se() {
595
620
  M("configured", "session_reset");
596
621
  }
597
- var Se = {
598
- RelayWebSocketClient: B,
599
- buildFormData: U,
600
- calcBackoff: G,
601
- collectFiles: H,
622
+ var Ce = {
623
+ RelayWebSocketClient: z,
624
+ buildFormData: H,
625
+ calcBackoff: W,
626
+ collectFiles: V,
602
627
  decodeGraphqlWsMessage: _,
603
- fetchFn: Z,
628
+ fetchFn: X,
604
629
  getDataId: k,
605
- hasUsableTopLevelData: Y,
606
- isNetworkError: q,
607
- isRetryableStatus: K,
608
- isUploadable: V,
609
- shouldThrowGraphQLResponseError: X,
630
+ hasUsableTopLevelData: J,
631
+ isNetworkError: K,
632
+ isRetryableStatus: G,
633
+ isUploadable: B,
634
+ shouldThrowGraphQLResponseError: Y,
635
+ observableFetchFn: Z,
610
636
  subscribeFn: Q
611
637
  };
612
638
  //#endregion
613
- export { J as GraphQLResponseError, Se as __test, L as configureRelayEnvironment, be as getEnvironment, $ as getNetwork, N as getRelayOperationActivitySnapshot, me as getRelayTransportSnapshot, F as reconnectRelayWebSocket, I as refreshRelayWebSocketAuthentication, xe as resetRelayStore, P as subscribeRelayOperationActivity, he as subscribeRelayTransport };
639
+ export { q as GraphQLResponseError, Ce as __test, I as configureRelayEnvironment, xe as getEnvironment, $ as getNetwork, ge as getRelayOperationActivitySnapshot, me as getRelayTransportSnapshot, P as reconnectRelayWebSocket, F as refreshRelayWebSocketAuthentication, Se as resetRelayStore, N as subscribeRelayOperationActivity, he as subscribeRelayTransport };
614
640
 
615
641
  //# 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();\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 with Promise */\nasync function sleep(ms: number): Promise<void> {\n await new Promise<void>((res) => {\n setTimeout(() => {\n res();\n }, ms);\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 // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _cacheConfig: unknown,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _uploadables: unknown,\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\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 const controller = new AbortController();\n activeHttpControllers.add(controller);\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 activeHttpControllers.delete(controller);\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 (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);\n }\n }\n throw new Error('Exhausted retries without returning a result');\n } finally {\n stopRelayOperationActivity();\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 fetchFn 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 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 (() => 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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"}
@@ -155,7 +155,8 @@ declare function fetchFn(request: {
155
155
  name?: string | null;
156
156
  operationKind?: unknown;
157
157
  text: string | null | undefined;
158
- }, variables: Record<string, unknown>, _cacheConfig: unknown, _uploadables: unknown): Promise<GraphQLResponseShape>;
158
+ }, variables: Record<string, unknown>, _cacheConfig: unknown, _uploadables: unknown, operationController?: AbortController): Promise<GraphQLResponseShape>;
159
+ declare function observableFetchFn(request: Parameters<typeof fetchFn>[0], variables: Parameters<typeof fetchFn>[1], cacheConfig: Parameters<typeof fetchFn>[2], uploadables: Parameters<typeof fetchFn>[3]): Observable<GraphQLResponseShape>;
159
160
  declare function subscribeFn(operation: {
160
161
  text: string | null | undefined;
161
162
  name: string;
@@ -176,6 +177,7 @@ export declare const __test: {
176
177
  isRetryableStatus: typeof isRetryableStatus;
177
178
  isUploadable: typeof isUploadable;
178
179
  shouldThrowGraphQLResponseError: typeof shouldThrowGraphQLResponseError;
180
+ observableFetchFn: typeof observableFetchFn;
179
181
  subscribeFn: typeof subscribeFn;
180
182
  };
181
183
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/environment.ts"],"names":[],"mappings":"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"}
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.1.205",
3
+ "version": "0.2.2",
4
4
  "description": "Shared Relay runtime helpers for Plumile applications",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -60,9 +60,9 @@
60
60
  "tslib": "^2.8.1"
61
61
  },
62
62
  "devDependencies": {
63
- "@plumile/auth": "^0.1.205",
63
+ "@plumile/auth": "^0.2.2",
64
64
  "@types/react": "19.2.18",
65
- "@types/react-dom": "19.2.4",
65
+ "@types/react-dom": "19.2.5",
66
66
  "@types/relay-runtime": "20.1.1",
67
67
  "@typescript/native": "npm:typescript@7.0.2",
68
68
  "react": "19.2.8",
@@ -72,7 +72,7 @@
72
72
  "rimraf": "6.1.3"
73
73
  },
74
74
  "peerDependencies": {
75
- "@plumile/auth": "^0.1.201",
75
+ "@plumile/auth": "^0.2.0",
76
76
  "react": "^19.2.8",
77
77
  "react-relay": "^21.0.1",
78
78
  "relay-runtime": "^21.0.1"