import { Effect, Layer, Option } from "effect"; import { HttpClient, HttpClientRequest } from "effect/unstable/http"; import { endpointForTelemetry } from "@executor-js/sdk/core"; import { GraphqlInvocationError } from "./errors"; import { type OperationBinding, InvocationResult } from "./types"; const endpointWithQueryParams = (endpoint: string, queryParams: Record): string => { if (Object.keys(queryParams).length === 0) return endpoint; const url = new URL(endpoint); for (const [name, value] of Object.entries(queryParams)) { url.searchParams.set(name, value); } return url.toString(); }; // Below Cloudflare's approximate 125-second subrequest limit while preserving // slow upstream requests that Executor's HTTP transports support. export const GRAPHQL_INVOCATION_TIMEOUT_MS = 110_000; export interface GraphqlInvokeOptions { readonly timeoutMs?: number; } const formatTimeout = (timeoutMs: number): string => timeoutMs % 1_000 === 0 ? `${timeoutMs / 1_000}s` : `${timeoutMs}ms`; const invocationTimeoutMessage = (timeoutMs: number): string => `GraphQL upstream did not complete within ${formatTimeout(timeoutMs)}. The request was aborted. Retry the operation or verify that the endpoint is responsive.`; /** The operation string to send for a call. A caller-supplied `select` overrides * the default scalar-leaf selection: it is spliced into the field's selection * set (`field {