@effect-gql/core 1.0.0 → 1.1.1
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 +27 -1
- package/builder/index.cjs +17 -2
- package/builder/index.cjs.map +1 -1
- package/builder/index.d.cts +3 -2
- package/builder/index.d.ts +3 -2
- package/builder/index.js +17 -2
- package/builder/index.js.map +1 -1
- package/index.cjs +141 -74
- package/index.cjs.map +1 -1
- package/index.d.cts +9 -3
- package/index.d.ts +9 -3
- package/index.js +143 -76
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/{schema-builder-Cvdq7Kz_.d.cts → schema-builder-DKvkzU_M.d.cts} +2 -0
- package/{schema-builder-Cvdq7Kz_.d.ts → schema-builder-DKvkzU_M.d.ts} +2 -0
- package/server/index.cjs +88 -47
- package/server/index.cjs.map +1 -1
- package/server/index.d.cts +5 -3
- package/server/index.d.ts +5 -3
- package/server/index.js +91 -50
- package/server/index.js.map +1 -1
package/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/config.ts","../../src/server/graphiql.ts","../../src/server/complexity.ts","../../src/server/cache-control.ts","../../src/extensions.ts","../../src/server/router.ts","../../src/server/schema-builder-extensions.ts","../../src/server/ws-types.ts","../../src/server/ws-adapter.ts","../../src/server/ws-utils.ts","../../src/server/sse-types.ts","../../src/server/sse-adapter.ts"],"names":["Config","Option","Effect","Kind","getRootType","analyzeSelectionSet","parse","getNamedType","GraphQLNonNull","GraphQLList","GraphQLObjectType","analyzeFragmentSpread","analyzeInlineFragment","GraphQLSchema","analyzeField","graphqlExecute","extensionData","Data","Runtime","Stream","Queue","Deferred","GraphQLError","validate","subscribe"],"mappings":"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","file":"index.js","sourcesContent":["import { Config, Option } from \"effect\"\nimport type { ComplexityConfig } from \"./complexity\"\nimport type { CacheControlConfig } from \"./cache-control\"\n\n/**\n * Configuration for the GraphiQL UI\n */\nexport interface GraphiQLConfig {\n /** Path where GraphiQL UI is served (default: \"/graphiql\") */\n readonly path: string\n /** URL where GraphiQL sends requests (default: same as graphql path) */\n readonly endpoint: string\n}\n\n/**\n * Configuration for the GraphQL router\n */\nexport interface GraphQLRouterConfig {\n /** Path for GraphQL endpoint (default: \"/graphql\") */\n readonly path: string\n /** GraphiQL configuration, or false to disable */\n readonly graphiql: false | GraphiQLConfig\n /** Query complexity limiting configuration */\n readonly complexity?: ComplexityConfig\n /** Enable introspection queries (default: true). Set to false in production. */\n readonly introspection: boolean\n /** Cache control configuration for HTTP Cache-Control headers */\n readonly cacheControl?: CacheControlConfig\n}\n\n/**\n * Default configuration values\n */\nexport const defaultConfig: GraphQLRouterConfig = {\n path: \"/graphql\",\n graphiql: false,\n complexity: undefined,\n introspection: true,\n cacheControl: undefined,\n}\n\n/**\n * Normalize user-provided config (which may use boolean shorthand for graphiql)\n * into the full GraphQLRouterConfig format\n */\nexport interface GraphQLRouterConfigInput {\n readonly path?: string\n readonly graphiql?: boolean | Partial<GraphiQLConfig>\n /** Query complexity limiting configuration */\n readonly complexity?: ComplexityConfig\n /** Enable introspection queries (default: true). Set to false in production. */\n readonly introspection?: boolean\n /** Cache control configuration for HTTP Cache-Control headers */\n readonly cacheControl?: CacheControlConfig\n}\n\nexport const normalizeConfig = (input: GraphQLRouterConfigInput = {}): GraphQLRouterConfig => {\n const path = input.path ?? defaultConfig.path\n\n let graphiql: false | GraphiQLConfig = false\n if (input.graphiql === true) {\n graphiql = { path: \"/graphiql\", endpoint: path }\n } else if (input.graphiql && typeof input.graphiql === \"object\") {\n graphiql = {\n path: input.graphiql.path ?? \"/graphiql\",\n endpoint: input.graphiql.endpoint ?? path,\n }\n }\n\n return {\n path,\n graphiql,\n complexity: input.complexity,\n introspection: input.introspection ?? true,\n cacheControl: input.cacheControl,\n }\n}\n\n/**\n * Effect Config for loading GraphQL router configuration from environment variables.\n *\n * Environment variables:\n * - GRAPHQL_PATH: Path for GraphQL endpoint (default: \"/graphql\")\n * - GRAPHQL_INTROSPECTION: Enable introspection queries (default: true)\n * - GRAPHIQL_ENABLED: Enable GraphiQL UI (default: false)\n * - GRAPHIQL_PATH: Path for GraphiQL UI (default: \"/graphiql\")\n * - GRAPHIQL_ENDPOINT: URL where GraphiQL sends requests (default: same as GRAPHQL_PATH)\n * - GRAPHQL_MAX_DEPTH: Maximum query depth (optional)\n * - GRAPHQL_MAX_COMPLEXITY: Maximum complexity score (optional)\n * - GRAPHQL_MAX_ALIASES: Maximum number of aliases (optional)\n * - GRAPHQL_MAX_FIELDS: Maximum number of fields (optional)\n * - GRAPHQL_DEFAULT_FIELD_COMPLEXITY: Default field complexity (default: 1)\n * - GRAPHQL_CACHE_CONTROL_ENABLED: Enable cache control headers (default: false)\n * - GRAPHQL_CACHE_CONTROL_DEFAULT_MAX_AGE: Default maxAge for root fields (default: 0)\n * - GRAPHQL_CACHE_CONTROL_DEFAULT_SCOPE: Default scope - PUBLIC or PRIVATE (default: PUBLIC)\n */\nexport const GraphQLRouterConfigFromEnv: Config.Config<GraphQLRouterConfig> = Config.all({\n path: Config.string(\"GRAPHQL_PATH\").pipe(Config.withDefault(\"/graphql\")),\n introspection: Config.boolean(\"GRAPHQL_INTROSPECTION\").pipe(Config.withDefault(true)),\n graphiqlEnabled: Config.boolean(\"GRAPHIQL_ENABLED\").pipe(Config.withDefault(false)),\n graphiqlPath: Config.string(\"GRAPHIQL_PATH\").pipe(Config.withDefault(\"/graphiql\")),\n graphiqlEndpoint: Config.string(\"GRAPHIQL_ENDPOINT\").pipe(Config.option),\n maxDepth: Config.number(\"GRAPHQL_MAX_DEPTH\").pipe(Config.option),\n maxComplexity: Config.number(\"GRAPHQL_MAX_COMPLEXITY\").pipe(Config.option),\n maxAliases: Config.number(\"GRAPHQL_MAX_ALIASES\").pipe(Config.option),\n maxFields: Config.number(\"GRAPHQL_MAX_FIELDS\").pipe(Config.option),\n defaultFieldComplexity: Config.number(\"GRAPHQL_DEFAULT_FIELD_COMPLEXITY\").pipe(\n Config.withDefault(1)\n ),\n cacheControlEnabled: Config.boolean(\"GRAPHQL_CACHE_CONTROL_ENABLED\").pipe(\n Config.withDefault(false)\n ),\n cacheControlDefaultMaxAge: Config.number(\"GRAPHQL_CACHE_CONTROL_DEFAULT_MAX_AGE\").pipe(\n Config.withDefault(0)\n ),\n cacheControlDefaultScope: Config.string(\"GRAPHQL_CACHE_CONTROL_DEFAULT_SCOPE\").pipe(\n Config.withDefault(\"PUBLIC\")\n ),\n}).pipe(\n Config.map(\n ({\n path,\n introspection,\n graphiqlEnabled,\n graphiqlPath,\n graphiqlEndpoint,\n maxDepth,\n maxComplexity,\n maxAliases,\n maxFields,\n defaultFieldComplexity,\n cacheControlEnabled,\n cacheControlDefaultMaxAge,\n cacheControlDefaultScope,\n }) => {\n // Check if any complexity option is set\n const hasComplexity =\n Option.isSome(maxDepth) ||\n Option.isSome(maxComplexity) ||\n Option.isSome(maxAliases) ||\n Option.isSome(maxFields)\n\n return {\n path,\n introspection,\n graphiql: graphiqlEnabled\n ? {\n path: graphiqlPath,\n endpoint: Option.isSome(graphiqlEndpoint) ? graphiqlEndpoint.value : path,\n }\n : (false as const),\n complexity: hasComplexity\n ? {\n maxDepth: Option.getOrUndefined(maxDepth),\n maxComplexity: Option.getOrUndefined(maxComplexity),\n maxAliases: Option.getOrUndefined(maxAliases),\n maxFields: Option.getOrUndefined(maxFields),\n defaultFieldComplexity,\n }\n : undefined,\n cacheControl: cacheControlEnabled\n ? {\n enabled: true,\n defaultMaxAge: cacheControlDefaultMaxAge,\n defaultScope: (cacheControlDefaultScope === \"PRIVATE\"\n ? \"PRIVATE\"\n : \"PUBLIC\") as import(\"../builder/types\").CacheControlScope,\n calculateHttpHeaders: true,\n }\n : undefined,\n }\n }\n )\n)\n","/**\n * Generate HTML for GraphiQL IDE, loading dependencies from CDN\n */\nexport const graphiqlHtml = (endpoint: string): string => `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>GraphiQL</title>\n <link\n rel=\"stylesheet\"\n href=\"https://unpkg.com/graphiql@3/graphiql.min.css\"\n />\n </head>\n <body style=\"margin: 0; overflow: hidden;\">\n <div id=\"graphiql\" style=\"height: 100vh;\"></div>\n <script\n crossorigin\n src=\"https://unpkg.com/react@18/umd/react.production.min.js\"\n ></script>\n <script\n crossorigin\n src=\"https://unpkg.com/react-dom@18/umd/react-dom.production.min.js\"\n ></script>\n <script\n crossorigin\n src=\"https://unpkg.com/graphiql@3/graphiql.min.js\"\n ></script>\n <script>\n const fetcher = GraphiQL.createFetcher({\n url: ${JSON.stringify(endpoint)},\n });\n ReactDOM.createRoot(document.getElementById('graphiql')).render(\n React.createElement(GraphiQL, { fetcher })\n );\n </script>\n </body>\n</html>`\n","import { Effect, Option, Config, Data } from \"effect\"\nimport {\n DocumentNode,\n OperationDefinitionNode,\n FieldNode,\n FragmentDefinitionNode,\n FragmentSpreadNode,\n InlineFragmentNode,\n SelectionSetNode,\n GraphQLSchema,\n GraphQLObjectType,\n GraphQLOutputType,\n GraphQLNonNull,\n GraphQLList,\n Kind,\n parse,\n} from \"graphql\"\n\n// ============================================================================\n// Errors\n// ============================================================================\n\n/**\n * Error thrown when query complexity exceeds configured limits\n */\nexport class ComplexityLimitExceededError extends Data.TaggedError(\"ComplexityLimitExceededError\")<{\n readonly message: string\n readonly limit: number\n readonly actual: number\n readonly limitType: \"depth\" | \"complexity\" | \"aliases\" | \"fields\"\n}> {}\n\n/**\n * Error thrown when complexity analysis fails\n */\nexport class ComplexityAnalysisError extends Data.TaggedError(\"ComplexityAnalysisError\")<{\n readonly message: string\n readonly cause?: unknown\n}> {}\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of complexity analysis for a GraphQL operation\n */\nexport interface ComplexityResult {\n /** Maximum depth of the query */\n readonly depth: number\n /** Total complexity score */\n readonly complexity: number\n /** Number of field selections (including nested) */\n readonly fieldCount: number\n /** Number of aliased fields */\n readonly aliasCount: number\n}\n\n/**\n * Information provided to complexity calculators\n */\nexport interface ComplexityAnalysisInfo {\n /** Parsed GraphQL document */\n readonly document: DocumentNode\n /** The operation being executed */\n readonly operation: OperationDefinitionNode\n /** Variables provided with the query */\n readonly variables?: Record<string, unknown>\n /** The GraphQL schema */\n readonly schema: GraphQLSchema\n /** Field complexity definitions from the builder */\n readonly fieldComplexities: FieldComplexityMap\n}\n\n/**\n * Information provided when complexity limit is exceeded\n */\nexport interface ComplexityExceededInfo {\n /** The computed complexity result */\n readonly result: ComplexityResult\n /** Which limit was exceeded */\n readonly exceededLimit: \"depth\" | \"complexity\" | \"aliases\" | \"fields\"\n /** The limit value */\n readonly limit: number\n /** The actual value */\n readonly actual: number\n /** The query that exceeded limits */\n readonly query: string\n /** Operation name if provided */\n readonly operationName?: string\n}\n\n/**\n * Complexity value for a field - can be static or dynamic based on arguments\n */\nexport type FieldComplexity = number | ((args: Record<string, unknown>) => number)\n\n/**\n * Map of type.field -> complexity\n */\nexport type FieldComplexityMap = Map<string, FieldComplexity>\n\n/**\n * Custom complexity calculator function.\n * Must be self-contained (no service requirements).\n */\nexport type ComplexityCalculator = (\n info: ComplexityAnalysisInfo\n) => Effect.Effect<ComplexityResult, ComplexityAnalysisError, never>\n\n/**\n * Configuration for query complexity limiting\n */\nexport interface ComplexityConfig {\n /**\n * Maximum allowed query depth.\n * Depth is the deepest nesting level in the query.\n * @example\n * // Depth 3:\n * // { user { posts { comments { text } } } }\n */\n readonly maxDepth?: number\n\n /**\n * Maximum allowed total complexity score.\n * Complexity is calculated by summing field costs.\n */\n readonly maxComplexity?: number\n\n /**\n * Maximum number of field aliases allowed.\n * Prevents response explosion attacks via aliases.\n */\n readonly maxAliases?: number\n\n /**\n * Maximum total number of fields in the query.\n * Includes all nested field selections.\n */\n readonly maxFields?: number\n\n /**\n * Default complexity cost for fields without explicit costs.\n * @default 1\n */\n readonly defaultFieldComplexity?: number\n\n /**\n * Custom complexity calculator.\n * If provided, this is used instead of the default calculator.\n * Can be used to implement custom cost algorithms.\n */\n readonly calculator?: ComplexityCalculator\n\n /**\n * Hook called when a limit is exceeded.\n * Useful for logging, metrics, or custom handling.\n * This is called BEFORE the error is thrown.\n * Must be self-contained (no service requirements).\n */\n readonly onExceeded?: (info: ComplexityExceededInfo) => Effect.Effect<void, never, never>\n}\n\n// ============================================================================\n// Default Calculator\n// ============================================================================\n\n/**\n * Default complexity calculator that walks the AST and computes:\n * - depth: Maximum nesting level\n * - complexity: Sum of field costs\n * - fieldCount: Total number of field selections\n * - aliasCount: Number of aliased fields\n */\nexport const defaultComplexityCalculator = (defaultCost: number = 1): ComplexityCalculator => {\n return (info: ComplexityAnalysisInfo) =>\n Effect.try({\n try: () => {\n const fragments = new Map<string, FragmentDefinitionNode>()\n\n // Collect fragment definitions\n for (const definition of info.document.definitions) {\n if (definition.kind === Kind.FRAGMENT_DEFINITION) {\n fragments.set(definition.name.value, definition)\n }\n }\n\n // Get the root type for the operation\n const rootType = getRootType(info.schema, info.operation.operation)\n if (!rootType) {\n throw new Error(`No root type found for operation: ${info.operation.operation}`)\n }\n\n // Analyze the selection set\n const result = analyzeSelectionSet(\n info.operation.selectionSet,\n rootType,\n info.schema,\n fragments,\n info.fieldComplexities,\n info.variables ?? {},\n defaultCost,\n 1, // Starting depth\n new Set() // Visited fragments to prevent infinite loops\n )\n\n return result\n },\n catch: (error) =>\n new ComplexityAnalysisError({\n message: `Failed to analyze query complexity: ${error}`,\n cause: error,\n }),\n })\n}\n\n/**\n * Get the root type for an operation\n */\nfunction getRootType(\n schema: GraphQLSchema,\n operation: \"query\" | \"mutation\" | \"subscription\"\n): GraphQLObjectType | null {\n switch (operation) {\n case \"query\":\n return schema.getQueryType() ?? null\n case \"mutation\":\n return schema.getMutationType() ?? null\n case \"subscription\":\n return schema.getSubscriptionType() ?? null\n }\n}\n\n/**\n * Get the named type from a potentially wrapped type\n */\nfunction getNamedType(type: GraphQLOutputType): GraphQLObjectType | null {\n if (type instanceof GraphQLNonNull || type instanceof GraphQLList) {\n return getNamedType(type.ofType as GraphQLOutputType)\n }\n if (type instanceof GraphQLObjectType) {\n return type\n }\n return null\n}\n\n/**\n * Merge a child result into an accumulator (mutates accumulator)\n */\nfunction accumulateResult(\n acc: { maxDepth: number; complexity: number; fieldCount: number; aliasCount: number },\n result: ComplexityResult\n): void {\n acc.maxDepth = Math.max(acc.maxDepth, result.depth)\n acc.complexity += result.complexity\n acc.fieldCount += result.fieldCount\n acc.aliasCount += result.aliasCount\n}\n\n/**\n * Analysis context passed through the recursive analysis functions\n */\ninterface AnalysisContext {\n readonly schema: GraphQLSchema\n readonly fragments: Map<string, FragmentDefinitionNode>\n readonly fieldComplexities: FieldComplexityMap\n readonly variables: Record<string, unknown>\n readonly defaultCost: number\n}\n\n/**\n * Analyze a selection set and return complexity metrics\n */\nfunction analyzeSelectionSet(\n selectionSet: SelectionSetNode,\n parentType: GraphQLObjectType,\n schema: GraphQLSchema,\n fragments: Map<string, FragmentDefinitionNode>,\n fieldComplexities: FieldComplexityMap,\n variables: Record<string, unknown>,\n defaultCost: number,\n currentDepth: number,\n visitedFragments: Set<string>\n): ComplexityResult {\n const ctx: AnalysisContext = { schema, fragments, fieldComplexities, variables, defaultCost }\n const acc = { maxDepth: currentDepth, complexity: 0, fieldCount: 0, aliasCount: 0 }\n\n for (const selection of selectionSet.selections) {\n const result = analyzeSelection(selection, parentType, ctx, currentDepth, visitedFragments)\n accumulateResult(acc, result)\n }\n\n return {\n depth: acc.maxDepth,\n complexity: acc.complexity,\n fieldCount: acc.fieldCount,\n aliasCount: acc.aliasCount,\n }\n}\n\n/**\n * Analyze a single selection node (field, fragment spread, or inline fragment)\n */\nfunction analyzeSelection(\n selection: FieldNode | FragmentSpreadNode | InlineFragmentNode,\n parentType: GraphQLObjectType,\n ctx: AnalysisContext,\n currentDepth: number,\n visitedFragments: Set<string>\n): ComplexityResult {\n switch (selection.kind) {\n case Kind.FIELD:\n return analyzeField(selection, parentType, ctx, currentDepth, visitedFragments)\n case Kind.FRAGMENT_SPREAD:\n return analyzeFragmentSpread(selection, ctx, currentDepth, visitedFragments)\n case Kind.INLINE_FRAGMENT:\n return analyzeInlineFragment(selection, parentType, ctx, currentDepth, visitedFragments)\n }\n}\n\n/**\n * Analyze a field node\n */\nfunction analyzeField(\n field: FieldNode,\n parentType: GraphQLObjectType,\n ctx: AnalysisContext,\n currentDepth: number,\n visitedFragments: Set<string>\n): ComplexityResult {\n const fieldName = field.name.value\n const aliasCount = field.alias ? 1 : 0\n\n // Introspection fields\n if (fieldName.startsWith(\"__\")) {\n return { depth: currentDepth, complexity: 0, fieldCount: 1, aliasCount }\n }\n\n // Get the field from the schema\n const schemaField = parentType.getFields()[fieldName]\n if (!schemaField) {\n // Field not found - skip (will be caught by validation)\n return { depth: currentDepth, complexity: ctx.defaultCost, fieldCount: 1, aliasCount }\n }\n\n // Calculate field arguments\n const args = resolveFieldArguments(field, ctx.variables)\n\n // Get field complexity\n const complexityKey = `${parentType.name}.${fieldName}`\n const fieldComplexity = ctx.fieldComplexities.get(complexityKey)\n const cost =\n fieldComplexity !== undefined\n ? typeof fieldComplexity === \"function\"\n ? fieldComplexity(args)\n : fieldComplexity\n : ctx.defaultCost\n\n // If the field has a selection set, analyze it\n if (field.selectionSet) {\n const fieldType = getNamedType(schemaField.type)\n if (fieldType) {\n const nestedResult = analyzeSelectionSet(\n field.selectionSet,\n fieldType,\n ctx.schema,\n ctx.fragments,\n ctx.fieldComplexities,\n ctx.variables,\n ctx.defaultCost,\n currentDepth + 1,\n visitedFragments\n )\n return {\n depth: nestedResult.depth,\n complexity: cost + nestedResult.complexity,\n fieldCount: 1 + nestedResult.fieldCount,\n aliasCount: aliasCount + nestedResult.aliasCount,\n }\n }\n }\n\n return { depth: currentDepth, complexity: cost, fieldCount: 1, aliasCount }\n}\n\n/**\n * Analyze a fragment spread\n */\nfunction analyzeFragmentSpread(\n spread: FragmentSpreadNode,\n ctx: AnalysisContext,\n currentDepth: number,\n visitedFragments: Set<string>\n): ComplexityResult {\n const fragmentName = spread.name.value\n\n // Prevent infinite loops with fragment cycles\n if (visitedFragments.has(fragmentName)) {\n return { depth: currentDepth, complexity: 0, fieldCount: 0, aliasCount: 0 }\n }\n\n const fragment = ctx.fragments.get(fragmentName)\n if (!fragment) {\n return { depth: currentDepth, complexity: 0, fieldCount: 0, aliasCount: 0 }\n }\n\n const fragmentType = ctx.schema.getType(fragment.typeCondition.name.value)\n if (!(fragmentType instanceof GraphQLObjectType)) {\n return { depth: currentDepth, complexity: 0, fieldCount: 0, aliasCount: 0 }\n }\n\n const newVisited = new Set(visitedFragments)\n newVisited.add(fragmentName)\n\n return analyzeSelectionSet(\n fragment.selectionSet,\n fragmentType,\n ctx.schema,\n ctx.fragments,\n ctx.fieldComplexities,\n ctx.variables,\n ctx.defaultCost,\n currentDepth,\n newVisited\n )\n}\n\n/**\n * Analyze an inline fragment\n */\nfunction analyzeInlineFragment(\n fragment: InlineFragmentNode,\n parentType: GraphQLObjectType,\n ctx: AnalysisContext,\n currentDepth: number,\n visitedFragments: Set<string>\n): ComplexityResult {\n let targetType = parentType\n\n if (fragment.typeCondition) {\n const conditionType = ctx.schema.getType(fragment.typeCondition.name.value)\n if (conditionType instanceof GraphQLObjectType) {\n targetType = conditionType\n }\n }\n\n return analyzeSelectionSet(\n fragment.selectionSet,\n targetType,\n ctx.schema,\n ctx.fragments,\n ctx.fieldComplexities,\n ctx.variables,\n ctx.defaultCost,\n currentDepth,\n visitedFragments\n )\n}\n\n/**\n * Resolve field arguments, substituting variables\n */\nfunction resolveFieldArguments(\n field: FieldNode,\n variables: Record<string, unknown>\n): Record<string, unknown> {\n const args: Record<string, unknown> = {}\n\n if (!field.arguments) {\n return args\n }\n\n for (const arg of field.arguments) {\n const value = arg.value\n switch (value.kind) {\n case Kind.VARIABLE:\n args[arg.name.value] = variables[value.name.value]\n break\n case Kind.INT:\n args[arg.name.value] = parseInt(value.value, 10)\n break\n case Kind.FLOAT:\n args[arg.name.value] = parseFloat(value.value)\n break\n case Kind.STRING:\n args[arg.name.value] = value.value\n break\n case Kind.BOOLEAN:\n args[arg.name.value] = value.value\n break\n case Kind.NULL:\n args[arg.name.value] = null\n break\n case Kind.ENUM:\n args[arg.name.value] = value.value\n break\n case Kind.LIST:\n // Simplified - just use empty array for complexity calculation\n args[arg.name.value] = []\n break\n case Kind.OBJECT:\n // Simplified - just use empty object for complexity calculation\n args[arg.name.value] = {}\n break\n }\n }\n\n return args\n}\n\n// ============================================================================\n// Validation\n// ============================================================================\n\n/**\n * Validate query complexity against configured limits.\n * Returns the complexity result if within limits, or fails with ComplexityLimitExceededError.\n */\nexport const validateComplexity = (\n query: string,\n operationName: string | undefined,\n variables: Record<string, unknown> | undefined,\n schema: GraphQLSchema,\n fieldComplexities: FieldComplexityMap,\n config: ComplexityConfig\n): Effect.Effect<ComplexityResult, ComplexityLimitExceededError | ComplexityAnalysisError, never> =>\n Effect.gen(function* () {\n // Parse the query\n const document = yield* Effect.try({\n try: () => parse(query),\n catch: (error) =>\n new ComplexityAnalysisError({\n message: `Failed to parse query: ${error}`,\n cause: error,\n }),\n })\n\n // Find the operation\n const operation = yield* Effect.try({\n try: () => {\n const operations = document.definitions.filter(\n (d): d is OperationDefinitionNode => d.kind === Kind.OPERATION_DEFINITION\n )\n\n if (operations.length === 0) {\n throw new Error(\"No operation found in query\")\n }\n\n if (operationName) {\n const op = operations.find((o) => o.name?.value === operationName)\n if (!op) {\n throw new Error(`Operation \"${operationName}\" not found`)\n }\n return op\n }\n\n if (operations.length > 1) {\n throw new Error(\"Multiple operations found - operationName required\")\n }\n\n return operations[0]\n },\n catch: (error) =>\n new ComplexityAnalysisError({\n message: String(error),\n cause: error,\n }),\n })\n\n // Calculate complexity\n const calculator =\n config.calculator ?? defaultComplexityCalculator(config.defaultFieldComplexity ?? 1)\n\n const result = yield* calculator({\n document,\n operation,\n variables,\n schema,\n fieldComplexities,\n })\n\n // Check limits\n const checkLimit = (\n limitType: \"depth\" | \"complexity\" | \"aliases\" | \"fields\",\n limit: number | undefined,\n actual: number\n ) =>\n Effect.gen(function* () {\n if (limit !== undefined && actual > limit) {\n const exceededInfo: ComplexityExceededInfo = {\n result,\n exceededLimit: limitType,\n limit,\n actual,\n query,\n operationName,\n }\n\n // Call onExceeded hook if provided\n if (config.onExceeded) {\n yield* config.onExceeded(exceededInfo)\n }\n\n yield* Effect.fail(\n new ComplexityLimitExceededError({\n message: `Query ${limitType} of ${actual} exceeds maximum allowed ${limitType} of ${limit}`,\n limit,\n actual,\n limitType,\n })\n )\n }\n })\n\n yield* checkLimit(\"depth\", config.maxDepth, result.depth)\n yield* checkLimit(\"complexity\", config.maxComplexity, result.complexity)\n yield* checkLimit(\"aliases\", config.maxAliases, result.aliasCount)\n yield* checkLimit(\"fields\", config.maxFields, result.fieldCount)\n\n return result\n })\n\n// ============================================================================\n// Environment Configuration\n// ============================================================================\n\n/**\n * Effect Config for loading complexity configuration from environment variables.\n *\n * Environment variables:\n * - GRAPHQL_MAX_DEPTH: Maximum query depth\n * - GRAPHQL_MAX_COMPLEXITY: Maximum complexity score\n * - GRAPHQL_MAX_ALIASES: Maximum number of aliases\n * - GRAPHQL_MAX_FIELDS: Maximum number of fields\n * - GRAPHQL_DEFAULT_FIELD_COMPLEXITY: Default field complexity (default: 1)\n */\nexport const ComplexityConfigFromEnv: Config.Config<ComplexityConfig> = Config.all({\n maxDepth: Config.number(\"GRAPHQL_MAX_DEPTH\").pipe(Config.option),\n maxComplexity: Config.number(\"GRAPHQL_MAX_COMPLEXITY\").pipe(Config.option),\n maxAliases: Config.number(\"GRAPHQL_MAX_ALIASES\").pipe(Config.option),\n maxFields: Config.number(\"GRAPHQL_MAX_FIELDS\").pipe(Config.option),\n defaultFieldComplexity: Config.number(\"GRAPHQL_DEFAULT_FIELD_COMPLEXITY\").pipe(\n Config.withDefault(1)\n ),\n}).pipe(\n Config.map(({ maxDepth, maxComplexity, maxAliases, maxFields, defaultFieldComplexity }) => ({\n maxDepth: Option.getOrUndefined(maxDepth),\n maxComplexity: Option.getOrUndefined(maxComplexity),\n maxAliases: Option.getOrUndefined(maxAliases),\n maxFields: Option.getOrUndefined(maxFields),\n defaultFieldComplexity,\n }))\n)\n\n// ============================================================================\n// Utility Calculators\n// ============================================================================\n\n/**\n * A simple depth-only calculator that only tracks query depth.\n * Use this when you only care about depth limiting and want fast validation.\n */\nexport const depthOnlyCalculator: ComplexityCalculator = (info) =>\n Effect.try({\n try: () => {\n const fragments = new Map<string, FragmentDefinitionNode>()\n for (const definition of info.document.definitions) {\n if (definition.kind === Kind.FRAGMENT_DEFINITION) {\n fragments.set(definition.name.value, definition)\n }\n }\n\n const depth = calculateMaxDepth(info.operation.selectionSet, fragments, 1, new Set())\n\n return {\n depth,\n complexity: 0,\n fieldCount: 0,\n aliasCount: 0,\n }\n },\n catch: (error) =>\n new ComplexityAnalysisError({\n message: `Failed to analyze query depth: ${error}`,\n cause: error,\n }),\n })\n\nfunction calculateMaxDepth(\n selectionSet: SelectionSetNode,\n fragments: Map<string, FragmentDefinitionNode>,\n currentDepth: number,\n visitedFragments: Set<string>\n): number {\n let maxDepth = currentDepth\n\n for (const selection of selectionSet.selections) {\n switch (selection.kind) {\n case Kind.FIELD:\n if (selection.selectionSet) {\n const nestedDepth = calculateMaxDepth(\n selection.selectionSet,\n fragments,\n currentDepth + 1,\n visitedFragments\n )\n maxDepth = Math.max(maxDepth, nestedDepth)\n }\n break\n\n case Kind.FRAGMENT_SPREAD: {\n const fragmentName = selection.name.value\n if (!visitedFragments.has(fragmentName)) {\n const fragment = fragments.get(fragmentName)\n if (fragment) {\n const newVisited = new Set(visitedFragments)\n newVisited.add(fragmentName)\n const fragmentDepth = calculateMaxDepth(\n fragment.selectionSet,\n fragments,\n currentDepth,\n newVisited\n )\n maxDepth = Math.max(maxDepth, fragmentDepth)\n }\n }\n break\n }\n\n case Kind.INLINE_FRAGMENT: {\n const inlineDepth = calculateMaxDepth(\n selection.selectionSet,\n fragments,\n currentDepth,\n visitedFragments\n )\n maxDepth = Math.max(maxDepth, inlineDepth)\n break\n }\n }\n }\n\n return maxDepth\n}\n\n/**\n * Combine multiple calculators - returns the maximum values from all calculators.\n */\nexport const combineCalculators = (\n ...calculators: ComplexityCalculator[]\n): ComplexityCalculator => {\n return (info) =>\n Effect.gen(function* () {\n let maxDepth = 0\n let maxComplexity = 0\n let maxFieldCount = 0\n let maxAliasCount = 0\n\n for (const calculator of calculators) {\n const result = yield* calculator(info)\n maxDepth = Math.max(maxDepth, result.depth)\n maxComplexity = Math.max(maxComplexity, result.complexity)\n maxFieldCount = Math.max(maxFieldCount, result.fieldCount)\n maxAliasCount = Math.max(maxAliasCount, result.aliasCount)\n }\n\n return {\n depth: maxDepth,\n complexity: maxComplexity,\n fieldCount: maxFieldCount,\n aliasCount: maxAliasCount,\n }\n })\n}\n","import { Effect, Config } from \"effect\"\nimport {\n DocumentNode,\n OperationDefinitionNode,\n FieldNode,\n FragmentDefinitionNode,\n SelectionSetNode,\n GraphQLSchema,\n GraphQLObjectType,\n GraphQLOutputType,\n GraphQLNonNull,\n GraphQLList,\n GraphQLScalarType,\n GraphQLEnumType,\n Kind,\n parse,\n} from \"graphql\"\nimport type { CacheHint, CacheControlScope } from \"../builder/types\"\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Map of type.field -> cache hint, or type -> cache hint for type-level hints\n */\nexport type CacheHintMap = Map<string, CacheHint>\n\n/**\n * Computed cache policy for a GraphQL response\n */\nexport interface CachePolicy {\n /**\n * Maximum age in seconds the response can be cached.\n * This is the minimum maxAge of all resolved fields.\n * If 0, the response should not be cached.\n */\n readonly maxAge: number\n\n /**\n * Cache scope - PUBLIC means CDN-cacheable, PRIVATE means browser-only.\n * If any field is PRIVATE, the entire response is PRIVATE.\n */\n readonly scope: CacheControlScope\n}\n\n/**\n * Configuration for cache control\n */\nexport interface CacheControlConfig {\n /**\n * Enable cache control header calculation.\n * @default true\n */\n readonly enabled?: boolean\n\n /**\n * Default maxAge for root fields (Query, Mutation).\n * @default 0 (no caching)\n */\n readonly defaultMaxAge?: number\n\n /**\n * Default scope for fields without explicit scope.\n * @default \"PUBLIC\"\n */\n readonly defaultScope?: CacheControlScope\n\n /**\n * Whether to set HTTP Cache-Control headers on responses.\n * @default true\n */\n readonly calculateHttpHeaders?: boolean\n}\n\n/**\n * Information provided to cache policy calculation\n */\nexport interface CachePolicyAnalysisInfo {\n /** Parsed GraphQL document */\n readonly document: DocumentNode\n /** The operation being executed */\n readonly operation: OperationDefinitionNode\n /** The GraphQL schema */\n readonly schema: GraphQLSchema\n /** Cache hints from the builder (type.field -> hint or type -> hint) */\n readonly cacheHints: CacheHintMap\n /** Configuration options */\n readonly config: CacheControlConfig\n}\n\n// ============================================================================\n// Cache Policy Computation\n// ============================================================================\n\n/**\n * Compute the cache policy for a GraphQL response based on the fields resolved.\n *\n * The policy is computed by walking the selection set and aggregating hints:\n * - maxAge: Use the minimum maxAge of all resolved fields\n * - scope: If any field is PRIVATE, the entire response is PRIVATE\n *\n * Default behaviors (matching Apollo):\n * - Root fields default to maxAge: 0 (unless configured otherwise)\n * - Object-returning fields default to maxAge: 0\n * - Scalar fields inherit their parent's maxAge\n * - Fields with inheritMaxAge: true inherit from parent\n */\nexport const computeCachePolicy = (\n info: CachePolicyAnalysisInfo\n): Effect.Effect<CachePolicy, never, never> =>\n Effect.sync(() => {\n const fragments = new Map<string, FragmentDefinitionNode>()\n\n // Collect fragment definitions\n for (const definition of info.document.definitions) {\n if (definition.kind === Kind.FRAGMENT_DEFINITION) {\n fragments.set(definition.name.value, definition)\n }\n }\n\n // Get the root type for the operation\n const rootType = getRootType(info.schema, info.operation.operation)\n if (!rootType) {\n // No root type - return no-cache\n return { maxAge: 0, scope: \"PUBLIC\" as const }\n }\n\n const defaultMaxAge = info.config.defaultMaxAge ?? 0\n const defaultScope = info.config.defaultScope ?? \"PUBLIC\"\n\n // Analyze the selection set\n const result = analyzeSelectionSet(\n info.operation.selectionSet,\n rootType,\n info.schema,\n fragments,\n info.cacheHints,\n defaultMaxAge,\n defaultScope,\n undefined, // No parent maxAge for root\n new Set()\n )\n\n return result\n })\n\n/**\n * Compute cache policy from a query string\n */\nexport const computeCachePolicyFromQuery = (\n query: string,\n operationName: string | undefined,\n schema: GraphQLSchema,\n cacheHints: CacheHintMap,\n config: CacheControlConfig = {}\n): Effect.Effect<CachePolicy, Error, never> =>\n Effect.gen(function* () {\n // Parse the query\n const document = yield* Effect.try({\n try: () => parse(query),\n catch: (error) => new Error(`Failed to parse query: ${error}`),\n })\n\n // Find the operation\n const operation = yield* Effect.try({\n try: () => {\n const operations = document.definitions.filter(\n (d): d is OperationDefinitionNode => d.kind === Kind.OPERATION_DEFINITION\n )\n\n if (operations.length === 0) {\n throw new Error(\"No operation found in query\")\n }\n\n if (operationName) {\n const op = operations.find((o) => o.name?.value === operationName)\n if (!op) {\n throw new Error(`Operation \"${operationName}\" not found`)\n }\n return op\n }\n\n if (operations.length > 1) {\n throw new Error(\"Multiple operations found - operationName required\")\n }\n\n return operations[0]\n },\n catch: (error) => error as Error,\n })\n\n return yield* computeCachePolicy({\n document,\n operation,\n schema,\n cacheHints,\n config,\n })\n })\n\n/**\n * Convert a cache policy to an HTTP Cache-Control header value\n */\nexport const toCacheControlHeader = (policy: CachePolicy): string => {\n if (policy.maxAge === 0) {\n return \"no-store\"\n }\n\n const directives: string[] = []\n directives.push(policy.scope === \"PRIVATE\" ? \"private\" : \"public\")\n directives.push(`max-age=${policy.maxAge}`)\n\n return directives.join(\", \")\n}\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\n/**\n * Get the root type for an operation\n */\nfunction getRootType(\n schema: GraphQLSchema,\n operation: \"query\" | \"mutation\" | \"subscription\"\n): GraphQLObjectType | null {\n switch (operation) {\n case \"query\":\n return schema.getQueryType() ?? null\n case \"mutation\":\n return schema.getMutationType() ?? null\n case \"subscription\":\n return schema.getSubscriptionType() ?? null\n }\n}\n\n/**\n * Get the named type from a potentially wrapped type\n */\nfunction getNamedType(\n type: GraphQLOutputType\n): GraphQLObjectType | GraphQLScalarType | GraphQLEnumType | null {\n if (type instanceof GraphQLNonNull || type instanceof GraphQLList) {\n return getNamedType(type.ofType as GraphQLOutputType)\n }\n if (\n type instanceof GraphQLObjectType ||\n type instanceof GraphQLScalarType ||\n type instanceof GraphQLEnumType\n ) {\n return type\n }\n return null\n}\n\n/**\n * Check if a type is a scalar or enum (leaf type)\n */\nfunction isLeafType(type: GraphQLOutputType): boolean {\n const namedType = getNamedType(type)\n return namedType instanceof GraphQLScalarType || namedType instanceof GraphQLEnumType\n}\n\n/**\n * Context passed through the analysis functions\n */\ninterface AnalysisContext {\n schema: GraphQLSchema\n fragments: Map<string, FragmentDefinitionNode>\n cacheHints: CacheHintMap\n defaultMaxAge: number\n defaultScope: CacheControlScope\n}\n\n/**\n * Mutable state for aggregating cache policies\n */\ninterface PolicyAccumulator {\n minMaxAge: number | undefined\n hasPrivate: boolean\n}\n\n/**\n * Aggregate a field policy into the accumulator\n */\nfunction aggregatePolicy(acc: PolicyAccumulator, policy: CachePolicy): void {\n if (acc.minMaxAge === undefined) {\n acc.minMaxAge = policy.maxAge\n } else {\n acc.minMaxAge = Math.min(acc.minMaxAge, policy.maxAge)\n }\n if (policy.scope === \"PRIVATE\") {\n acc.hasPrivate = true\n }\n}\n\n/**\n * Analyze a fragment spread and return its cache policy\n */\nfunction analyzeFragmentSpread(\n fragmentName: string,\n ctx: AnalysisContext,\n parentMaxAge: number | undefined,\n visitedFragments: Set<string>\n): CachePolicy | undefined {\n // Prevent infinite loops with fragment cycles\n if (visitedFragments.has(fragmentName)) {\n return undefined\n }\n\n const fragment = ctx.fragments.get(fragmentName)\n if (!fragment) {\n return undefined\n }\n\n const fragmentType = ctx.schema.getType(fragment.typeCondition.name.value)\n if (!(fragmentType instanceof GraphQLObjectType)) {\n return undefined\n }\n\n const newVisited = new Set(visitedFragments)\n newVisited.add(fragmentName)\n\n return analyzeSelectionSet(fragment.selectionSet, fragmentType, ctx, parentMaxAge, newVisited)\n}\n\n/**\n * Analyze an inline fragment and return its cache policy\n */\nfunction analyzeInlineFragment(\n selection: { typeCondition?: { name: { value: string } }; selectionSet: SelectionSetNode },\n parentType: GraphQLObjectType,\n ctx: AnalysisContext,\n parentMaxAge: number | undefined,\n visitedFragments: Set<string>\n): CachePolicy {\n let targetType = parentType\n\n if (selection.typeCondition) {\n const conditionType = ctx.schema.getType(selection.typeCondition.name.value)\n if (conditionType instanceof GraphQLObjectType) {\n targetType = conditionType\n }\n }\n\n return analyzeSelectionSet(\n selection.selectionSet,\n targetType,\n ctx,\n parentMaxAge,\n visitedFragments\n )\n}\n\n/**\n * Look up the effective cache hint for a field (field-level > type-level > undefined)\n */\nfunction lookupEffectiveCacheHint(\n parentTypeName: string,\n fieldName: string,\n returnType: GraphQLOutputType,\n cacheHints: CacheHintMap\n): CacheHint | undefined {\n // Priority: field-level hint > type-level hint\n const fieldKey = `${parentTypeName}.${fieldName}`\n const fieldHint = cacheHints.get(fieldKey)\n if (fieldHint) return fieldHint\n\n // Check type-level hint on return type\n const namedType = getNamedType(returnType)\n return namedType ? cacheHints.get(namedType.name) : undefined\n}\n\n/**\n * Compute the maxAge for a field based on hint, inheritance, and field type\n */\nfunction computeFieldMaxAge(\n hint: CacheHint | undefined,\n fieldType: GraphQLOutputType,\n parentMaxAge: number | undefined,\n defaultMaxAge: number\n): number {\n if (hint) {\n // Use explicit hint\n if (hint.inheritMaxAge && parentMaxAge !== undefined) {\n return parentMaxAge\n }\n if (hint.maxAge !== undefined) {\n return hint.maxAge\n }\n // Fall through to default logic\n }\n\n // Scalar/enum fields inherit parent maxAge by default\n if (isLeafType(fieldType) && parentMaxAge !== undefined) {\n return parentMaxAge\n }\n\n // Root and object fields default to defaultMaxAge (typically 0)\n return defaultMaxAge\n}\n\n/**\n * Analyze a selection set and return the aggregated cache policy.\n * Overload with AnalysisContext for internal use.\n */\nfunction analyzeSelectionSet(\n selectionSet: SelectionSetNode,\n parentType: GraphQLObjectType,\n ctx: AnalysisContext,\n parentMaxAge: number | undefined,\n visitedFragments: Set<string>\n): CachePolicy\nfunction analyzeSelectionSet(\n selectionSet: SelectionSetNode,\n parentType: GraphQLObjectType,\n schema: GraphQLSchema,\n fragments: Map<string, FragmentDefinitionNode>,\n cacheHints: CacheHintMap,\n defaultMaxAge: number,\n defaultScope: CacheControlScope,\n parentMaxAge: number | undefined,\n visitedFragments: Set<string>\n): CachePolicy\nfunction analyzeSelectionSet(\n selectionSet: SelectionSetNode,\n parentType: GraphQLObjectType,\n schemaOrCtx: GraphQLSchema | AnalysisContext,\n fragmentsOrParentMaxAge: Map<string, FragmentDefinitionNode> | number | undefined,\n cacheHintsOrVisited?: CacheHintMap | Set<string>,\n defaultMaxAge?: number,\n defaultScope?: CacheControlScope,\n parentMaxAge?: number | undefined,\n visitedFragments?: Set<string>\n): CachePolicy {\n // Normalize arguments - support both old and new signatures\n let ctx: AnalysisContext\n let actualParentMaxAge: number | undefined\n let actualVisitedFragments: Set<string>\n\n if (schemaOrCtx instanceof GraphQLSchema) {\n // Old signature\n ctx = {\n schema: schemaOrCtx,\n fragments: fragmentsOrParentMaxAge as Map<string, FragmentDefinitionNode>,\n cacheHints: cacheHintsOrVisited as CacheHintMap,\n defaultMaxAge: defaultMaxAge!,\n defaultScope: defaultScope!,\n }\n actualParentMaxAge = parentMaxAge\n actualVisitedFragments = visitedFragments!\n } else {\n // New signature with AnalysisContext\n ctx = schemaOrCtx\n actualParentMaxAge = fragmentsOrParentMaxAge as number | undefined\n actualVisitedFragments = cacheHintsOrVisited as Set<string>\n }\n\n const acc: PolicyAccumulator = { minMaxAge: undefined, hasPrivate: false }\n\n for (const selection of selectionSet.selections) {\n let fieldPolicy: CachePolicy | undefined\n\n switch (selection.kind) {\n case Kind.FIELD:\n fieldPolicy = analyzeField(\n selection,\n parentType,\n ctx,\n actualParentMaxAge,\n actualVisitedFragments\n )\n break\n\n case Kind.FRAGMENT_SPREAD:\n fieldPolicy = analyzeFragmentSpread(\n selection.name.value,\n ctx,\n actualParentMaxAge,\n actualVisitedFragments\n )\n break\n\n case Kind.INLINE_FRAGMENT:\n fieldPolicy = analyzeInlineFragment(\n selection,\n parentType,\n ctx,\n actualParentMaxAge,\n actualVisitedFragments\n )\n break\n }\n\n if (fieldPolicy) {\n aggregatePolicy(acc, fieldPolicy)\n }\n }\n\n return {\n maxAge: acc.minMaxAge ?? ctx.defaultMaxAge,\n scope: acc.hasPrivate ? \"PRIVATE\" : ctx.defaultScope,\n }\n}\n\n/**\n * Analyze a field node and return its cache policy\n */\nfunction analyzeField(\n field: FieldNode,\n parentType: GraphQLObjectType,\n ctx: AnalysisContext,\n parentMaxAge: number | undefined,\n visitedFragments: Set<string>\n): CachePolicy {\n const fieldName = field.name.value\n\n // Introspection fields - don't affect caching\n if (fieldName.startsWith(\"__\")) {\n return { maxAge: Infinity, scope: \"PUBLIC\" }\n }\n\n // Get the field from the schema\n const schemaField = parentType.getFields()[fieldName]\n if (!schemaField) {\n return { maxAge: ctx.defaultMaxAge, scope: ctx.defaultScope }\n }\n\n // Look up effective cache hint\n const effectiveHint = lookupEffectiveCacheHint(\n parentType.name,\n fieldName,\n schemaField.type,\n ctx.cacheHints\n )\n\n // Compute field maxAge\n const fieldMaxAge = computeFieldMaxAge(\n effectiveHint,\n schemaField.type,\n parentMaxAge,\n ctx.defaultMaxAge\n )\n const fieldScope: CacheControlScope = effectiveHint?.scope ?? ctx.defaultScope\n\n // If the field has a selection set, analyze it\n const namedType = getNamedType(schemaField.type)\n if (field.selectionSet && namedType instanceof GraphQLObjectType) {\n const nestedPolicy = analyzeSelectionSet(\n field.selectionSet,\n namedType,\n ctx,\n fieldMaxAge,\n visitedFragments\n )\n\n return {\n maxAge: Math.min(fieldMaxAge, nestedPolicy.maxAge),\n scope: fieldScope === \"PRIVATE\" || nestedPolicy.scope === \"PRIVATE\" ? \"PRIVATE\" : \"PUBLIC\",\n }\n }\n\n return { maxAge: fieldMaxAge, scope: fieldScope }\n}\n\n// ============================================================================\n// Environment Configuration\n// ============================================================================\n\n/**\n * Effect Config for loading cache control configuration from environment variables.\n *\n * Environment variables:\n * - GRAPHQL_CACHE_CONTROL_ENABLED: Enable cache control (default: true)\n * - GRAPHQL_CACHE_CONTROL_DEFAULT_MAX_AGE: Default maxAge for root fields (default: 0)\n * - GRAPHQL_CACHE_CONTROL_DEFAULT_SCOPE: Default scope (PUBLIC or PRIVATE, default: PUBLIC)\n * - GRAPHQL_CACHE_CONTROL_HTTP_HEADERS: Set HTTP headers (default: true)\n */\nexport const CacheControlConfigFromEnv: Config.Config<CacheControlConfig> = Config.all({\n enabled: Config.boolean(\"GRAPHQL_CACHE_CONTROL_ENABLED\").pipe(Config.withDefault(true)),\n defaultMaxAge: Config.number(\"GRAPHQL_CACHE_CONTROL_DEFAULT_MAX_AGE\").pipe(Config.withDefault(0)),\n defaultScope: Config.string(\"GRAPHQL_CACHE_CONTROL_DEFAULT_SCOPE\").pipe(\n Config.withDefault(\"PUBLIC\"),\n Config.map((s) => (s === \"PRIVATE\" ? \"PRIVATE\" : \"PUBLIC\") as CacheControlScope)\n ),\n calculateHttpHeaders: Config.boolean(\"GRAPHQL_CACHE_CONTROL_HTTP_HEADERS\").pipe(\n Config.withDefault(true)\n ),\n})\n","import { Context, Effect, Ref } from \"effect\"\nimport type { DocumentNode, ExecutionResult, GraphQLError, GraphQLSchema } from \"graphql\"\nimport type { FieldComplexityMap } from \"./server/complexity\"\n\n/**\n * Execution arguments passed to onExecuteStart hook\n */\nexport interface ExecutionArgs {\n readonly source: string\n readonly document: DocumentNode\n readonly variableValues?: Record<string, unknown>\n readonly operationName?: string\n /** The GraphQL schema being executed against */\n readonly schema: GraphQLSchema\n /** Field complexity definitions from the schema builder */\n readonly fieldComplexities: FieldComplexityMap\n}\n\n/**\n * Configuration for a GraphQL extension\n *\n * Extensions provide lifecycle hooks that run at each phase of request processing,\n * and can contribute data to the response's `extensions` field.\n *\n * @example\n * ```typescript\n * // Tracing extension\n * extension({\n * name: \"tracing\",\n * onExecuteStart: () => Effect.gen(function*() {\n * const ext = yield* ExtensionsService\n * yield* ext.set(\"tracing\", { startTime: Date.now() })\n * }),\n * onExecuteEnd: () => Effect.gen(function*() {\n * const ext = yield* ExtensionsService\n * yield* ext.merge(\"tracing\", { endTime: Date.now() })\n * }),\n * })\n * ```\n */\nexport interface GraphQLExtension<R = never> {\n readonly name: string\n readonly description?: string\n\n /**\n * Called after the query source is parsed into a DocumentNode.\n * Useful for query analysis, caching parsed documents, etc.\n */\n readonly onParse?: (source: string, document: DocumentNode) => Effect.Effect<void, never, R>\n\n /**\n * Called after validation completes.\n * Receives the document and any validation errors.\n * Useful for complexity analysis, query whitelisting, etc.\n */\n readonly onValidate?: (\n document: DocumentNode,\n errors: readonly GraphQLError[]\n ) => Effect.Effect<void, never, R>\n\n /**\n * Called before execution begins.\n * Receives the full execution arguments.\n * Useful for setting up tracing, logging, etc.\n */\n readonly onExecuteStart?: (args: ExecutionArgs) => Effect.Effect<void, never, R>\n\n /**\n * Called after execution completes.\n * Receives the execution result (including data and errors).\n * Useful for recording metrics, finalizing traces, etc.\n */\n readonly onExecuteEnd?: (result: ExecutionResult) => Effect.Effect<void, never, R>\n}\n\n/**\n * Service for accumulating extension data during request processing.\n *\n * This service is automatically provided for each request and allows\n * extensions, middleware, and resolvers to contribute to the response\n * extensions field.\n *\n * @example\n * ```typescript\n * Effect.gen(function*() {\n * const ext = yield* ExtensionsService\n *\n * // Set a value (overwrites existing)\n * yield* ext.set(\"complexity\", { score: 42 })\n *\n * // Merge into existing value\n * yield* ext.merge(\"tracing\", { endTime: Date.now() })\n *\n * // Get all accumulated extensions\n * const all = yield* ext.get()\n * })\n * ```\n */\nexport interface ExtensionsService {\n /**\n * Set a key-value pair in the extensions.\n * Overwrites any existing value for this key.\n */\n readonly set: (key: string, value: unknown) => Effect.Effect<void>\n\n /**\n * Deep merge an object into an existing key's value.\n * If the key doesn't exist, sets the value.\n * If the existing value is not an object, overwrites it.\n */\n readonly merge: (key: string, value: Record<string, unknown>) => Effect.Effect<void>\n\n /**\n * Get all accumulated extensions as a record.\n */\n readonly get: () => Effect.Effect<Record<string, unknown>>\n}\n\n/**\n * Tag for the ExtensionsService\n */\nexport const ExtensionsService = Context.GenericTag<ExtensionsService>(\n \"@effect-gql/ExtensionsService\"\n)\n\n/**\n * Deep merge two objects\n */\nfunction deepMerge(\n target: Record<string, unknown>,\n source: Record<string, unknown>\n): Record<string, unknown> {\n const result = { ...target }\n for (const key of Object.keys(source)) {\n const sourceValue = source[key]\n const targetValue = result[key]\n\n if (\n typeof sourceValue === \"object\" &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof targetValue === \"object\" &&\n targetValue !== null &&\n !Array.isArray(targetValue)\n ) {\n result[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n )\n } else {\n result[key] = sourceValue\n }\n }\n return result\n}\n\n/**\n * Create a new ExtensionsService backed by a Ref\n */\nexport const makeExtensionsService = (): Effect.Effect<ExtensionsService, never, never> =>\n Effect.gen(function* () {\n const ref = yield* Ref.make<Record<string, unknown>>({})\n\n return ExtensionsService.of({\n set: (key, value) => Ref.update(ref, (current) => ({ ...current, [key]: value })),\n\n merge: (key, value) =>\n Ref.update(ref, (current) => {\n const existing = current[key]\n if (typeof existing === \"object\" && existing !== null && !Array.isArray(existing)) {\n return {\n ...current,\n [key]: deepMerge(existing as Record<string, unknown>, value),\n }\n }\n return { ...current, [key]: value }\n }),\n\n get: () => Ref.get(ref),\n })\n })\n\n/**\n * Generic helper to run extension hooks with error handling.\n * Filters extensions that have the specified hook, runs them,\n * and logs warnings if any hook fails.\n */\nconst runExtensionHooks = <R, K extends keyof GraphQLExtension<R>>(\n extensions: readonly GraphQLExtension<R>[],\n hookName: K,\n getHookEffect: (ext: GraphQLExtension<R>) => Effect.Effect<void, never, R>\n): Effect.Effect<void, never, R> =>\n Effect.forEach(\n extensions.filter((ext) => ext[hookName] !== undefined),\n (ext) =>\n getHookEffect(ext).pipe(\n Effect.catchAllCause((cause) =>\n Effect.logWarning(`Extension \"${ext.name}\" ${String(hookName)} hook failed`, cause)\n )\n ),\n { discard: true }\n ) as Effect.Effect<void, never, R>\n\n/**\n * Run all onParse hooks for registered extensions\n */\nexport const runParseHooks = <R>(\n extensions: readonly GraphQLExtension<R>[],\n source: string,\n document: DocumentNode\n): Effect.Effect<void, never, R> =>\n runExtensionHooks(extensions, \"onParse\", (ext) => ext.onParse!(source, document))\n\n/**\n * Run all onValidate hooks for registered extensions\n */\nexport const runValidateHooks = <R>(\n extensions: readonly GraphQLExtension<R>[],\n document: DocumentNode,\n errors: readonly GraphQLError[]\n): Effect.Effect<void, never, R> =>\n runExtensionHooks(extensions, \"onValidate\", (ext) => ext.onValidate!(document, errors))\n\n/**\n * Run all onExecuteStart hooks for registered extensions\n */\nexport const runExecuteStartHooks = <R>(\n extensions: readonly GraphQLExtension<R>[],\n args: ExecutionArgs\n): Effect.Effect<void, never, R> =>\n runExtensionHooks(extensions, \"onExecuteStart\", (ext) => ext.onExecuteStart!(args))\n\n/**\n * Run all onExecuteEnd hooks for registered extensions\n */\nexport const runExecuteEndHooks = <R>(\n extensions: readonly GraphQLExtension<R>[],\n result: ExecutionResult\n): Effect.Effect<void, never, R> =>\n runExtensionHooks(extensions, \"onExecuteEnd\", (ext) => ext.onExecuteEnd!(result))\n","import { HttpRouter, HttpServerRequest, HttpServerResponse } from \"@effect/platform\"\nimport { Cause, Context, Effect, Layer } from \"effect\"\nimport {\n GraphQLSchema,\n parse,\n validate,\n specifiedRules,\n NoSchemaIntrospectionCustomRule,\n execute as graphqlExecute,\n Kind,\n type DocumentNode,\n type OperationDefinitionNode,\n} from \"graphql\"\nimport type { GraphQLEffectContext } from \"../builder/types\"\nimport { graphiqlHtml } from \"./graphiql\"\nimport { normalizeConfig, type GraphQLRouterConfigInput } from \"./config\"\nimport {\n validateComplexity,\n ComplexityLimitExceededError,\n type FieldComplexityMap,\n} from \"./complexity\"\nimport { computeCachePolicy, toCacheControlHeader, type CacheHintMap } from \"./cache-control\"\nimport {\n type GraphQLExtension,\n ExtensionsService,\n makeExtensionsService,\n runParseHooks,\n runValidateHooks,\n runExecuteStartHooks,\n runExecuteEndHooks,\n} from \"../extensions\"\n\n/**\n * Error handler function type for handling uncaught errors during GraphQL execution.\n * Receives the error cause and should return an HTTP response.\n */\nexport type ErrorHandler = (\n cause: Cause.Cause<unknown>\n) => Effect.Effect<HttpServerResponse.HttpServerResponse, never, never>\n\n/**\n * Default error handler that returns a 500 Internal Server Error.\n * In non-production environments, it logs the full error for debugging.\n */\nexport const defaultErrorHandler: ErrorHandler = (cause) =>\n (process.env.NODE_ENV !== \"production\"\n ? Effect.logError(\"GraphQL error\", cause)\n : Effect.void\n ).pipe(\n Effect.andThen(\n HttpServerResponse.json(\n {\n errors: [\n {\n message: \"An error occurred processing your request\",\n },\n ],\n },\n { status: 500 }\n ).pipe(Effect.orDie)\n )\n )\n\n/**\n * Request body for GraphQL queries.\n */\ninterface GraphQLRequestBody {\n query: string\n variables?: Record<string, unknown>\n operationName?: string\n}\n\n/**\n * Parse a GraphQL query string into a DocumentNode.\n * Returns the document or an error response if parsing fails.\n */\nconst parseGraphQLQuery = (\n query: string,\n extensionsService: Context.Tag.Service<typeof ExtensionsService>\n): Effect.Effect<\n | { ok: true; document: DocumentNode }\n | { ok: false; response: HttpServerResponse.HttpServerResponse },\n never,\n never\n> =>\n Effect.gen(function* () {\n try {\n const document = parse(query)\n return { ok: true as const, document }\n } catch (parseError) {\n const extensionData = yield* extensionsService.get()\n const response = yield* HttpServerResponse.json({\n errors: [{ message: String(parseError) }],\n extensions: Object.keys(extensionData).length > 0 ? extensionData : undefined,\n }).pipe(Effect.orDie)\n return { ok: false as const, response }\n }\n })\n\n/**\n * Run complexity validation if configured.\n * Logs warnings for analysis errors but doesn't block execution.\n */\nconst runComplexityValidation = (\n body: GraphQLRequestBody,\n schema: GraphQLSchema,\n fieldComplexities: FieldComplexityMap,\n complexityConfig: { maxDepth?: number; maxComplexity?: number } | undefined\n): Effect.Effect<void, ComplexityLimitExceededError, never> => {\n if (!complexityConfig) {\n return Effect.void\n }\n\n return validateComplexity(\n body.query,\n body.operationName,\n body.variables,\n schema,\n fieldComplexities,\n complexityConfig\n ).pipe(\n Effect.catchTag(\"ComplexityLimitExceededError\", (error) => Effect.fail(error)),\n Effect.catchTag(\"ComplexityAnalysisError\", (error) =>\n Effect.logWarning(\"Complexity analysis failed\", error)\n )\n )\n}\n\n/**\n * Execute a GraphQL query and handle async results.\n */\nconst executeGraphQLQuery = <R>(\n schema: GraphQLSchema,\n document: DocumentNode,\n variables: Record<string, unknown> | undefined,\n operationName: string | undefined,\n runtime: import(\"effect\").Runtime.Runtime<R>\n): Effect.Effect<import(\"graphql\").ExecutionResult, Error, never> =>\n Effect.gen(function* () {\n const executeResult = yield* Effect.try({\n try: () =>\n graphqlExecute({\n schema,\n document,\n variableValues: variables,\n operationName,\n contextValue: { runtime } satisfies GraphQLEffectContext<R>,\n }),\n catch: (error) => new Error(String(error)),\n })\n\n // Await result if it's a promise\n if (executeResult && typeof executeResult === \"object\" && \"then\" in executeResult) {\n return yield* Effect.promise(\n () => executeResult as Promise<import(\"graphql\").ExecutionResult>\n )\n }\n return executeResult as import(\"graphql\").ExecutionResult\n })\n\n/**\n * Compute cache control header for the response if applicable.\n */\nconst computeCacheControlHeader = (\n document: DocumentNode,\n operationName: string | undefined,\n schema: GraphQLSchema,\n cacheHints: CacheHintMap,\n cacheControlConfig:\n | { enabled?: boolean; calculateHttpHeaders?: boolean; defaultMaxAge?: number }\n | undefined\n): Effect.Effect<string | undefined, never, never> =>\n Effect.gen(function* () {\n if (\n cacheControlConfig?.enabled === false ||\n cacheControlConfig?.calculateHttpHeaders === false\n ) {\n return undefined\n }\n\n // Find the operation from the document\n const operations = document.definitions.filter(\n (d): d is OperationDefinitionNode => d.kind === Kind.OPERATION_DEFINITION\n )\n const operation = operationName\n ? operations.find((o) => o.name?.value === operationName)\n : operations[0]\n\n if (!operation || operation.operation === \"mutation\") {\n // Mutations should not be cached\n return undefined\n }\n\n const cachePolicy = yield* computeCachePolicy({\n document,\n operation,\n schema,\n cacheHints,\n config: cacheControlConfig ?? {},\n })\n\n return toCacheControlHeader(cachePolicy)\n })\n\n/**\n * Build the final GraphQL response with extensions merged in.\n */\nconst buildGraphQLResponse = (\n result: import(\"graphql\").ExecutionResult,\n extensionData: Record<string, unknown>,\n cacheControlHeader: string | undefined\n): Effect.Effect<HttpServerResponse.HttpServerResponse, never, never> => {\n const finalResult =\n Object.keys(extensionData).length > 0\n ? {\n ...result,\n extensions: {\n ...result.extensions,\n ...extensionData,\n },\n }\n : result\n\n const responseHeaders = cacheControlHeader ? { \"cache-control\": cacheControlHeader } : undefined\n\n return HttpServerResponse.json(finalResult, { headers: responseHeaders }).pipe(Effect.orDie)\n}\n\n/**\n * Handle complexity limit exceeded error, returning appropriate response.\n */\nconst handleComplexityError = (\n error: ComplexityLimitExceededError\n): Effect.Effect<HttpServerResponse.HttpServerResponse, never, never> =>\n HttpServerResponse.json(\n {\n errors: [\n {\n message: error.message,\n extensions: {\n code: \"COMPLEXITY_LIMIT_EXCEEDED\",\n limitType: error.limitType,\n limit: error.limit,\n actual: error.actual,\n },\n },\n ],\n },\n { status: 400 }\n ).pipe(Effect.orDie)\n\n/**\n * Options for makeGraphQLRouter\n */\nexport interface MakeGraphQLRouterOptions extends GraphQLRouterConfigInput {\n /**\n * Field complexity definitions from the schema builder.\n * If using toRouter(), this is automatically extracted from the builder.\n * If using makeGraphQLRouter() directly, call builder.getFieldComplexities().\n */\n readonly fieldComplexities?: FieldComplexityMap\n\n /**\n * Cache hint definitions from the schema builder.\n * If using toRouter(), this is automatically extracted from the builder.\n * If using makeGraphQLRouter() directly, call builder.getCacheHints().\n */\n readonly cacheHints?: CacheHintMap\n\n /**\n * GraphQL extensions for lifecycle hooks.\n * If using toRouter(), this is automatically extracted from the builder.\n * If using makeGraphQLRouter() directly, call builder.getExtensions().\n */\n readonly extensions?: readonly GraphQLExtension<any>[]\n\n /**\n * Custom error handler for uncaught errors during GraphQL execution.\n * Receives the error cause and should return an HTTP response.\n * Defaults to returning a 500 Internal Server Error with a generic message.\n */\n readonly errorHandler?: ErrorHandler\n}\n\n/**\n * Create an HttpRouter configured for GraphQL\n *\n * The router handles:\n * - POST requests to the GraphQL endpoint\n * - GET requests to the GraphiQL UI (if enabled)\n * - Query complexity validation (if configured)\n * - Extension lifecycle hooks (onParse, onValidate, onExecuteStart, onExecuteEnd)\n *\n * @param schema - The GraphQL schema\n * @param layer - Effect layer providing services required by resolvers\n * @param options - Optional configuration for paths, GraphiQL, complexity, and extensions\n * @returns An HttpRouter that can be composed with other routes\n *\n * @example\n * ```typescript\n * const router = makeGraphQLRouter(schema, Layer.empty, {\n * path: \"/graphql\",\n * graphiql: { path: \"/graphiql\" },\n * complexity: { maxDepth: 10, maxComplexity: 1000 },\n * fieldComplexities: builder.getFieldComplexities(),\n * extensions: builder.getExtensions()\n * })\n *\n * // Compose with other routes\n * const app = HttpRouter.empty.pipe(\n * HttpRouter.get(\"/health\", HttpServerResponse.json({ status: \"ok\" })),\n * HttpRouter.concat(router)\n * )\n * ```\n */\nexport const makeGraphQLRouter = <R>(\n schema: GraphQLSchema,\n layer: Layer.Layer<R>,\n options: MakeGraphQLRouterOptions = {}\n): HttpRouter.HttpRouter<never, never> => {\n const resolvedConfig = normalizeConfig(options)\n const fieldComplexities = options.fieldComplexities ?? new Map()\n const cacheHints = options.cacheHints ?? new Map()\n const extensions = options.extensions ?? []\n const errorHandler = options.errorHandler ?? defaultErrorHandler\n\n // GraphQL POST handler\n const graphqlHandler = Effect.gen(function* () {\n const extensionsService = yield* makeExtensionsService()\n const runtime = yield* Effect.runtime<R>()\n\n // Parse request body\n const request = yield* HttpServerRequest.HttpServerRequest\n const body = yield* request.json as Effect.Effect<GraphQLRequestBody>\n\n // Phase 1: Parse\n const parseResult = yield* parseGraphQLQuery(body.query, extensionsService)\n if (!parseResult.ok) {\n return parseResult.response\n }\n const document = parseResult.document\n\n yield* runParseHooks(extensions, body.query, document).pipe(\n Effect.provideService(ExtensionsService, extensionsService)\n )\n\n // Phase 2: Validate\n const validationRules = resolvedConfig.introspection\n ? undefined\n : [...specifiedRules, NoSchemaIntrospectionCustomRule]\n const validationErrors = validate(schema, document, validationRules)\n\n yield* runValidateHooks(extensions, document, validationErrors).pipe(\n Effect.provideService(ExtensionsService, extensionsService)\n )\n\n if (validationErrors.length > 0) {\n const extensionData = yield* extensionsService.get()\n return yield* HttpServerResponse.json(\n {\n errors: validationErrors.map((e) => ({\n message: e.message,\n locations: e.locations,\n path: e.path,\n })),\n extensions: Object.keys(extensionData).length > 0 ? extensionData : undefined,\n },\n { status: 400 }\n )\n }\n\n // Complexity validation\n yield* runComplexityValidation(body, schema, fieldComplexities, resolvedConfig.complexity)\n\n // Phase 3: Execute\n yield* runExecuteStartHooks(extensions, {\n source: body.query,\n document,\n variableValues: body.variables,\n operationName: body.operationName,\n schema,\n fieldComplexities,\n }).pipe(Effect.provideService(ExtensionsService, extensionsService))\n\n const result = yield* executeGraphQLQuery(\n schema,\n document,\n body.variables,\n body.operationName,\n runtime\n )\n\n yield* runExecuteEndHooks(extensions, result).pipe(\n Effect.provideService(ExtensionsService, extensionsService)\n )\n\n // Build response\n const extensionData = yield* extensionsService.get()\n const cacheControlHeader = yield* computeCacheControlHeader(\n document,\n body.operationName,\n schema,\n cacheHints,\n resolvedConfig.cacheControl\n )\n\n return yield* buildGraphQLResponse(result, extensionData, cacheControlHeader)\n }).pipe(\n Effect.provide(layer),\n Effect.catchAll((error) => {\n if (error instanceof ComplexityLimitExceededError) {\n return handleComplexityError(error)\n }\n return Effect.fail(error)\n }),\n Effect.catchAllCause(errorHandler)\n )\n\n // Build router\n let router = HttpRouter.empty.pipe(\n HttpRouter.post(resolvedConfig.path as HttpRouter.PathInput, graphqlHandler)\n )\n\n if (resolvedConfig.graphiql) {\n const { path, endpoint } = resolvedConfig.graphiql\n router = router.pipe(\n HttpRouter.get(path as HttpRouter.PathInput, HttpServerResponse.html(graphiqlHtml(endpoint)))\n )\n }\n\n return router\n}\n","import { Layer } from \"effect\"\nimport { HttpRouter } from \"@effect/platform\"\nimport { GraphQLSchemaBuilder } from \"../builder/schema-builder\"\nimport { makeGraphQLRouter, type MakeGraphQLRouterOptions } from \"./router\"\n\n/**\n * Convert a GraphQLSchemaBuilder to an HttpRouter.\n *\n * This bridges the GraphQL schema builder with the @effect/platform HTTP server.\n * Field complexities and cache hints are automatically extracted from the builder.\n *\n * @param builder - The GraphQL schema builder\n * @param layer - Effect layer providing services required by resolvers\n * @param options - Optional configuration for paths, GraphiQL, complexity, and caching\n * @returns An HttpRouter that can be composed with other routes\n *\n * @example\n * ```typescript\n * import { GraphQLSchemaBuilder, query, toRouter } from \"@effect-gql/core\"\n * import { Layer, Effect } from \"effect\"\n * import * as S from \"effect/Schema\"\n *\n * const builder = GraphQLSchemaBuilder.empty.pipe(\n * query(\"hello\", { type: S.String, resolve: () => Effect.succeed(\"world\") })\n * )\n *\n * // Basic usage\n * const router = toRouter(builder, Layer.empty, { graphiql: true })\n *\n * // With complexity limiting\n * const routerWithLimits = toRouter(builder, Layer.empty, {\n * graphiql: true,\n * complexity: { maxDepth: 10, maxComplexity: 1000 }\n * })\n *\n * // With cache control\n * const routerWithCaching = toRouter(builder, Layer.empty, {\n * cacheControl: { enabled: true, defaultMaxAge: 0 }\n * })\n * ```\n */\nexport const toRouter = <R, R2>(\n builder: GraphQLSchemaBuilder<R>,\n layer: Layer.Layer<R2>,\n options?: Omit<MakeGraphQLRouterOptions, \"fieldComplexities\" | \"cacheHints\">\n): HttpRouter.HttpRouter<never, never> => {\n const schema = builder.buildSchema()\n const fieldComplexities = builder.getFieldComplexities()\n const cacheHints = builder.getCacheHints()\n return makeGraphQLRouter(schema, layer, { ...options, fieldComplexities, cacheHints })\n}\n","import { Data, Effect, Runtime, Stream } from \"effect\"\nimport type { ComplexityConfig, FieldComplexityMap } from \"./complexity\"\n\n/**\n * Error type for WebSocket operations\n */\nexport class WebSocketError extends Data.TaggedError(\"WebSocketError\")<{\n readonly cause: unknown\n}> {}\n\n/**\n * WebSocket close event information\n */\nexport interface CloseEvent {\n readonly code: number\n readonly reason: string\n}\n\n/**\n * Platform-neutral WebSocket interface using Effect types.\n *\n * This interface abstracts WebSocket operations across different platforms\n * (Node.js ws, Bun built-in, browser WebSocket). Platform packages implement\n * this interface to bridge their specific WebSocket implementations.\n */\nexport interface EffectWebSocket {\n /**\n * Send a message to the client.\n * Returns an Effect that completes when the message is sent.\n */\n readonly send: (data: string) => Effect.Effect<void, WebSocketError>\n\n /**\n * Close the WebSocket connection.\n * @param code - Optional close code (default: 1000)\n * @param reason - Optional close reason\n */\n readonly close: (code?: number, reason?: string) => Effect.Effect<void, WebSocketError>\n\n /**\n * Stream of incoming messages from the client.\n * The stream completes when the connection closes.\n */\n readonly messages: Stream.Stream<string, WebSocketError>\n\n /**\n * Effect that completes with CloseEvent when the connection closes.\n * Use this to detect client disconnection.\n */\n readonly closed: Effect.Effect<CloseEvent, WebSocketError>\n\n /**\n * The WebSocket subprotocol negotiated during handshake.\n * For GraphQL subscriptions, this should be \"graphql-transport-ws\".\n */\n readonly protocol: string\n}\n\n/**\n * Context available during a WebSocket connection.\n * This is passed to lifecycle hooks.\n */\nexport interface ConnectionContext<R> {\n /**\n * The Effect runtime for this connection.\n * Use this to run Effects within the connection scope.\n */\n readonly runtime: Runtime.Runtime<R>\n\n /**\n * Connection parameters sent by the client during CONNECTION_INIT.\n * Often used for authentication tokens.\n */\n readonly connectionParams: Record<string, unknown>\n\n /**\n * The underlying WebSocket for this connection.\n */\n readonly socket: EffectWebSocket\n}\n\n/**\n * Options for configuring the GraphQL WebSocket handler.\n *\n * @template R - Service requirements for lifecycle hooks\n */\nexport interface GraphQLWSOptions<R> {\n /**\n * Query complexity limiting configuration.\n * When provided, subscriptions are validated against complexity limits\n * before execution begins.\n */\n readonly complexity?: ComplexityConfig\n\n /**\n * Field complexity definitions from the schema builder.\n * If using the platform serve() functions with subscriptions config,\n * this is typically passed automatically.\n */\n readonly fieldComplexities?: FieldComplexityMap\n\n /**\n * Called when a client initiates a connection (CONNECTION_INIT message).\n *\n * Use this for authentication. Return:\n * - `true` to accept the connection\n * - `false` to reject the connection\n * - An object to accept and provide additional context\n *\n * The returned object (or true) is merged into the GraphQL context.\n *\n * @example\n * ```typescript\n * onConnect: (params) => Effect.gen(function* () {\n * const token = params.authToken as string\n * const user = yield* AuthService.validateToken(token)\n * return { user } // Available in GraphQL context\n * })\n * ```\n */\n readonly onConnect?: (\n params: Record<string, unknown>\n ) => Effect.Effect<boolean | Record<string, unknown>, unknown, R>\n\n /**\n * Called when a client disconnects.\n * Use this for cleanup (e.g., removing user from active connections).\n */\n readonly onDisconnect?: (ctx: ConnectionContext<R>) => Effect.Effect<void, never, R>\n\n /**\n * Called when a client starts a subscription (SUBSCRIBE message).\n * Use this for per-subscription authorization or logging.\n *\n * Note: If complexity validation is enabled, it runs before this hook.\n * Throw an error to reject the subscription.\n */\n readonly onSubscribe?: (\n ctx: ConnectionContext<R>,\n message: SubscribeMessage\n ) => Effect.Effect<void, unknown, R>\n\n /**\n * Called when a subscription completes or is stopped.\n */\n readonly onComplete?: (\n ctx: ConnectionContext<R>,\n message: CompleteMessage\n ) => Effect.Effect<void, never, R>\n\n /**\n * Called when an error occurs during subscription execution.\n */\n readonly onError?: (ctx: ConnectionContext<R>, error: unknown) => Effect.Effect<void, never, R>\n}\n\n/**\n * GraphQL WebSocket SUBSCRIBE message payload\n */\nexport interface SubscribeMessage {\n readonly id: string\n readonly payload: {\n readonly query: string\n readonly variables?: Record<string, unknown>\n readonly operationName?: string\n readonly extensions?: Record<string, unknown>\n }\n}\n\n/**\n * GraphQL WebSocket COMPLETE message payload\n */\nexport interface CompleteMessage {\n readonly id: string\n}\n\n/**\n * Configuration for the WebSocket endpoint\n */\nexport interface GraphQLWSConfig {\n /**\n * Path for WebSocket connections.\n * @default \"/graphql\"\n */\n readonly path?: string\n\n /**\n * How long to wait for CONNECTION_INIT message before closing.\n * @default 5000 (5 seconds)\n */\n readonly connectionInitWaitTimeout?: number\n}\n","import { Effect, Layer, Runtime, Stream, Queue, Fiber, Deferred } from \"effect\"\nimport { GraphQLSchema, subscribe, GraphQLError } from \"graphql\"\nimport { makeServer, type ServerOptions } from \"graphql-ws\"\nimport type { GraphQLEffectContext } from \"../builder/types\"\nimport type {\n EffectWebSocket,\n GraphQLWSOptions,\n ConnectionContext,\n CloseEvent,\n WebSocketError,\n} from \"./ws-types\"\nimport { validateComplexity, type FieldComplexityMap } from \"./complexity\"\n\n/**\n * Extra context passed through graphql-ws.\n * This is the `extra` field in graphql-ws Context.\n */\ninterface WSExtra<R> {\n socket: EffectWebSocket\n runtime: Runtime.Runtime<R>\n connectionParams: Record<string, unknown>\n}\n\n/**\n * Create a ConnectionContext from WSExtra for use in lifecycle hooks.\n */\nconst createConnectionContext = <R>(extra: WSExtra<R>): ConnectionContext<R> => ({\n runtime: extra.runtime,\n connectionParams: extra.connectionParams,\n socket: extra.socket,\n})\n\n/**\n * Create the onConnect handler for graphql-ws.\n */\nconst makeOnConnectHandler = <R>(\n options: GraphQLWSOptions<R> | undefined\n): ServerOptions<Record<string, unknown>, WSExtra<R>>[\"onConnect\"] => {\n if (!options?.onConnect) return undefined\n\n return async (ctx) => {\n const extra = ctx.extra as WSExtra<R>\n try {\n const result = await Runtime.runPromise(extra.runtime)(\n options.onConnect!(ctx.connectionParams ?? {})\n )\n if (typeof result === \"object\" && result !== null) {\n Object.assign(extra.connectionParams, result)\n }\n return result !== false\n } catch {\n return false\n }\n }\n}\n\n/**\n * Create the onDisconnect handler for graphql-ws.\n */\nconst makeOnDisconnectHandler = <R>(\n options: GraphQLWSOptions<R> | undefined\n): ServerOptions<Record<string, unknown>, WSExtra<R>>[\"onDisconnect\"] => {\n if (!options?.onDisconnect) return undefined\n\n return async (ctx) => {\n const extra = ctx.extra as WSExtra<R>\n await Runtime.runPromise(extra.runtime)(\n options.onDisconnect!(createConnectionContext(extra))\n ).catch(() => {\n // Ignore cleanup errors\n })\n }\n}\n\n/**\n * Create the onSubscribe handler for graphql-ws with complexity validation.\n */\nconst makeOnSubscribeHandler = <R>(\n options: GraphQLWSOptions<R> | undefined,\n schema: GraphQLSchema,\n complexityConfig: GraphQLWSOptions<R>[\"complexity\"],\n fieldComplexities: FieldComplexityMap\n): ServerOptions<Record<string, unknown>, WSExtra<R>>[\"onSubscribe\"] => {\n // graphql-ws 6.0: signature changed from (ctx, msg) to (ctx, id, payload)\n return async (ctx, id, payload) => {\n const extra = ctx.extra as WSExtra<R>\n const connectionCtx = createConnectionContext(extra)\n\n // Validate complexity if configured\n if (complexityConfig) {\n const validationEffect = validateComplexity(\n payload.query,\n payload.operationName ?? undefined,\n payload.variables ?? undefined,\n schema,\n fieldComplexities,\n complexityConfig\n ).pipe(\n Effect.catchAll((error) => {\n if (error._tag === \"ComplexityLimitExceededError\") {\n throw new GraphQLError(error.message, {\n extensions: {\n code: \"COMPLEXITY_LIMIT_EXCEEDED\",\n limitType: error.limitType,\n limit: error.limit,\n actual: error.actual,\n },\n })\n }\n return Effect.logWarning(\"Complexity analysis failed for subscription\", error)\n })\n )\n\n await Effect.runPromise(validationEffect)\n }\n\n // Call user's onSubscribe hook if provided\n if (options?.onSubscribe) {\n await Runtime.runPromise(extra.runtime)(\n options.onSubscribe(connectionCtx, {\n id,\n payload: {\n query: payload.query,\n variables: payload.variables ?? undefined,\n operationName: payload.operationName ?? undefined,\n extensions: payload.extensions ?? undefined,\n },\n })\n )\n }\n }\n}\n\n/**\n * Create the onComplete handler for graphql-ws.\n */\nconst makeOnCompleteHandler = <R>(\n options: GraphQLWSOptions<R> | undefined\n): ServerOptions<Record<string, unknown>, WSExtra<R>>[\"onComplete\"] => {\n if (!options?.onComplete) return undefined\n\n // graphql-ws 6.0: signature changed from (ctx, msg) to (ctx, id, payload)\n return async (ctx, id, _payload) => {\n const extra = ctx.extra as WSExtra<R>\n await Runtime.runPromise(extra.runtime)(\n options.onComplete!(createConnectionContext(extra), { id })\n ).catch(() => {\n // Ignore cleanup errors\n })\n }\n}\n\n/**\n * Create the onError handler for graphql-ws.\n */\nconst makeOnErrorHandler = <R>(\n options: GraphQLWSOptions<R> | undefined\n): ServerOptions<Record<string, unknown>, WSExtra<R>>[\"onError\"] => {\n if (!options?.onError) return undefined\n\n // graphql-ws 6.0: signature changed from (ctx, msg, errors) to (ctx, id, payload, errors)\n return async (ctx, _id, _payload, errors) => {\n const extra = ctx.extra as WSExtra<R>\n await Runtime.runPromise(extra.runtime)(\n options.onError!(createConnectionContext(extra), errors)\n ).catch(() => {\n // Ignore error handler errors\n })\n }\n}\n\n/**\n * Create a graphql-ws compatible socket adapter from an EffectWebSocket.\n */\nconst createGraphqlWsSocketAdapter = <R>(socket: EffectWebSocket, runtime: Runtime.Runtime<R>) => {\n let messageCallback: ((message: string) => Promise<void>) | null = null\n\n return {\n adapter: {\n protocol: socket.protocol,\n\n send: (data: string) =>\n Runtime.runPromise(runtime)(\n socket\n .send(data)\n .pipe(Effect.catchAll((error) => Effect.logError(\"WebSocket send error\", error)))\n ),\n\n close: (code?: number, reason?: string) => {\n Runtime.runPromise(runtime)(socket.close(code, reason)).catch(() => {\n // Ignore close errors\n })\n },\n\n onMessage: (cb: (message: string) => Promise<void>) => {\n messageCallback = cb\n },\n\n onPong: (_payload: Record<string, unknown> | undefined) => {\n // Pong handling - can be used for keepalive\n },\n },\n dispatchMessage: async (message: string) => {\n if (messageCallback) {\n await messageCallback(message)\n }\n },\n }\n}\n\n/**\n * Run the connection lifecycle - manages message queue, fibers, and cleanup.\n */\nconst runConnectionLifecycle = <R>(\n socket: EffectWebSocket,\n wsServer: ReturnType<typeof makeServer<Record<string, unknown>, WSExtra<R>>>,\n extra: WSExtra<R>\n): Effect.Effect<void, never, never> =>\n Effect.gen(function* () {\n // Create message queue for bridging Stream to callback\n const messageQueue = yield* Queue.unbounded<string>()\n const closedDeferred = yield* Deferred.make<CloseEvent, WebSocketError>()\n\n // Fork fiber to consume socket messages and push to queue\n const messageFiber = yield* Effect.fork(\n Stream.runForEach(socket.messages, (msg) => Queue.offer(messageQueue, msg)).pipe(\n Effect.catchAll((error) => Deferred.fail(closedDeferred, error))\n )\n )\n\n // Fork fiber to handle socket close\n const closeFiber = yield* Effect.fork(\n socket.closed.pipe(\n Effect.tap((event) => Deferred.succeed(closedDeferred, event)),\n Effect.catchAll((error) => Deferred.fail(closedDeferred, error))\n )\n )\n\n // Create the graphql-ws socket adapter\n const { adapter, dispatchMessage } = createGraphqlWsSocketAdapter(socket, extra.runtime)\n\n // Open the connection with graphql-ws\n const closedHandler = wsServer.opened(adapter, extra)\n\n // Fork fiber to process messages from queue\n const processMessagesFiber = yield* Effect.fork(\n Effect.gen(function* () {\n while (true) {\n const message = yield* Queue.take(messageQueue)\n yield* Effect.tryPromise({\n try: () => dispatchMessage(message),\n catch: (error) => error,\n }).pipe(Effect.catchAll(() => Effect.void))\n }\n })\n )\n\n // Wait for connection to close\n yield* Deferred.await(closedDeferred).pipe(\n Effect.catchAll(() => Effect.succeed({ code: 1000, reason: \"Error\" }))\n )\n\n // Cleanup\n closedHandler(1000, \"Connection closed\")\n yield* Fiber.interrupt(messageFiber)\n yield* Fiber.interrupt(closeFiber)\n yield* Fiber.interrupt(processMessagesFiber)\n yield* Queue.shutdown(messageQueue)\n }).pipe(\n Effect.catchAllCause(() => Effect.void),\n Effect.scoped\n )\n\n/**\n * Create a WebSocket handler for GraphQL subscriptions using the graphql-ws protocol.\n *\n * This function creates a handler that can be used with any WebSocket implementation\n * that conforms to the EffectWebSocket interface. Platform packages (node, bun, express)\n * provide adapters that convert their native WebSocket to EffectWebSocket.\n *\n * The handler:\n * - Uses the graphql-ws protocol for client communication\n * - Creates an Effect runtime from the provided layer for each connection\n * - Executes subscriptions using GraphQL's subscribe() function\n * - Properly cleans up resources when connections close\n *\n * @param schema - The GraphQL schema with subscription definitions\n * @param layer - Effect layer providing services required by resolvers\n * @param options - Optional lifecycle hooks for connection/subscription events\n * @returns A function that handles individual WebSocket connections\n *\n * @example\n * ```typescript\n * import { makeGraphQLWSHandler } from \"@effect-gql/core\"\n *\n * const handler = makeGraphQLWSHandler(schema, serviceLayer, {\n * onConnect: (params) => Effect.gen(function* () {\n * const user = yield* AuthService.validateToken(params.authToken)\n * return { user }\n * }),\n * })\n *\n * // In platform-specific code:\n * const effectSocket = toEffectWebSocket(rawWebSocket)\n * await Effect.runPromise(handler(effectSocket))\n * ```\n */\nexport const makeGraphQLWSHandler = <R>(\n schema: GraphQLSchema,\n layer: Layer.Layer<R>,\n options?: GraphQLWSOptions<R>\n): ((socket: EffectWebSocket) => Effect.Effect<void, never, never>) => {\n const complexityConfig = options?.complexity\n const fieldComplexities: FieldComplexityMap = options?.fieldComplexities ?? new Map()\n\n // Build server options using extracted handler factories\n const serverOptions: ServerOptions<Record<string, unknown>, WSExtra<R>> = {\n schema,\n\n context: async (ctx): Promise<GraphQLEffectContext<R> & Record<string, unknown>> => {\n const extra = ctx.extra as WSExtra<R>\n return {\n runtime: extra.runtime,\n ...extra.connectionParams,\n }\n },\n\n subscribe: async (args) => subscribe(args),\n\n onConnect: makeOnConnectHandler(options),\n onDisconnect: makeOnDisconnectHandler(options),\n onSubscribe: makeOnSubscribeHandler(options, schema, complexityConfig, fieldComplexities),\n onComplete: makeOnCompleteHandler(options),\n onError: makeOnErrorHandler(options),\n }\n\n const wsServer = makeServer(serverOptions)\n\n // Return the connection handler\n return (socket: EffectWebSocket): Effect.Effect<void, never, never> =>\n Effect.gen(function* () {\n const runtime = yield* Effect.provide(Effect.runtime<R>(), layer)\n\n const extra: WSExtra<R> = {\n socket,\n runtime,\n connectionParams: {},\n }\n\n yield* runConnectionLifecycle(socket, wsServer, extra)\n }).pipe(\n Effect.catchAllCause(() => Effect.void),\n Effect.scoped\n )\n}\n","import { Effect, Stream, Queue, Deferred } from \"effect\"\nimport type { EffectWebSocket, CloseEvent } from \"./ws-types\"\nimport { WebSocketError } from \"./ws-types\"\n\n/**\n * Interface for the 'ws' library WebSocket.\n * This allows type-safe usage without requiring core to depend on 'ws'.\n */\nexport interface WsWebSocket {\n readonly protocol: string\n readonly readyState: number\n send(data: string, callback?: (error?: Error) => void): void\n close(code?: number, reason?: string): void\n on(event: \"message\", listener: (data: Buffer | string) => void): void\n on(event: \"error\", listener: (error: Error) => void): void\n on(event: \"close\", listener: (code: number, reason: Buffer) => void): void\n removeListener(event: string, listener: (...args: any[]) => void): void\n}\n\n/** WebSocket.CLOSED constant from 'ws' library */\nexport const WS_CLOSED = 3\n\n/**\n * Convert a WebSocket from the 'ws' library to an EffectWebSocket.\n *\n * This creates an Effect-based wrapper around the ws WebSocket instance,\n * providing a Stream for incoming messages and Effect-based send/close operations.\n *\n * This utility is used by platform packages (node, express) that integrate\n * with the 'ws' library for WebSocket support.\n *\n * @param ws - The WebSocket instance from the 'ws' library\n * @returns An EffectWebSocket that can be used with makeGraphQLWSHandler\n *\n * @example\n * ```typescript\n * import { toEffectWebSocketFromWs } from \"@effect-gql/core\"\n * import { WebSocket } from \"ws\"\n *\n * wss.on(\"connection\", (ws: WebSocket) => {\n * const effectSocket = toEffectWebSocketFromWs(ws)\n * Effect.runPromise(handler(effectSocket))\n * })\n * ```\n */\nexport const toEffectWebSocketFromWs = (ws: WsWebSocket): EffectWebSocket => {\n // Create the message stream using a queue\n const messagesEffect = Effect.gen(function* () {\n const queue = yield* Queue.unbounded<string>()\n const closed = yield* Deferred.make<CloseEvent, WebSocketError>()\n\n // Set up message listener\n ws.on(\"message\", (data) => {\n const message = data.toString()\n Effect.runPromise(Queue.offer(queue, message)).catch(() => {\n // Queue might be shutdown\n })\n })\n\n // Set up error listener\n ws.on(\"error\", (error) => {\n Effect.runPromise(Deferred.fail(closed, new WebSocketError({ cause: error }))).catch(() => {\n // Already completed\n })\n })\n\n // Set up close listener\n ws.on(\"close\", (code, reason) => {\n Effect.runPromise(\n Queue.shutdown(queue).pipe(\n Effect.andThen(Deferred.succeed(closed, { code, reason: reason.toString() }))\n )\n ).catch(() => {\n // Already completed\n })\n })\n\n return { queue, closed }\n })\n\n // Create the message stream\n const messages: Stream.Stream<string, WebSocketError> = Stream.unwrap(\n messagesEffect.pipe(\n Effect.map(({ queue }) => Stream.fromQueue(queue).pipe(Stream.catchAll(() => Stream.empty)))\n )\n )\n\n return {\n protocol: ws.protocol || \"graphql-transport-ws\",\n\n send: (data: string) =>\n Effect.async<void, WebSocketError>((resume) => {\n ws.send(data, (error) => {\n if (error) {\n resume(Effect.fail(new WebSocketError({ cause: error })))\n } else {\n resume(Effect.succeed(undefined))\n }\n })\n }),\n\n close: (code?: number, reason?: string) =>\n Effect.sync(() => {\n ws.close(code ?? 1000, reason ?? \"\")\n }),\n\n messages,\n\n closed: Effect.async<CloseEvent, WebSocketError>((resume) => {\n if (ws.readyState === WS_CLOSED) {\n resume(Effect.succeed({ code: 1000, reason: \"\" }))\n return\n }\n\n const onClose = (code: number, reason: Buffer) => {\n cleanup()\n resume(Effect.succeed({ code, reason: reason.toString() }))\n }\n\n const onError = (error: Error) => {\n cleanup()\n resume(Effect.fail(new WebSocketError({ cause: error })))\n }\n\n const cleanup = () => {\n ws.removeListener(\"close\", onClose)\n ws.removeListener(\"error\", onError)\n }\n\n ws.on(\"close\", onClose)\n ws.on(\"error\", onError)\n\n return Effect.sync(cleanup)\n }),\n }\n}\n","import { Data, Effect, Runtime, Stream } from \"effect\"\nimport type { ExecutionResult } from \"graphql\"\nimport type { ComplexityConfig, FieldComplexityMap } from \"./complexity\"\n\n/**\n * Standard SSE response headers following the graphql-sse protocol.\n * Use these headers when writing SSE responses in platform adapters.\n */\nexport const SSE_HEADERS: Record<string, string> = {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"X-Accel-Buffering\": \"no\", // Disable nginx buffering\n} as const\n\n/**\n * Error type for SSE operations\n */\nexport class SSEError extends Data.TaggedError(\"SSEError\")<{\n readonly cause: unknown\n}> {}\n\n/**\n * SSE event types following the graphql-sse protocol (distinct connections mode).\n * @see https://github.com/enisdenjo/graphql-sse/blob/master/PROTOCOL.md\n */\nexport type SSEEventType = \"next\" | \"error\" | \"complete\"\n\n/**\n * An SSE event to be sent to the client.\n */\nexport interface SSEEvent {\n readonly event: SSEEventType\n readonly data: string\n}\n\n/**\n * Platform-neutral SSE response interface using Effect types.\n *\n * This interface abstracts SSE operations across different platforms\n * (Node.js, Bun, Deno, Workers). Platform packages implement this\n * interface to bridge their specific HTTP response implementations.\n *\n * Unlike WebSocket which is bidirectional, SSE is unidirectional\n * (server to client only). The subscription query is provided\n * upfront when creating the SSE connection.\n */\nexport interface EffectSSE {\n /**\n * Send an SSE event to the client.\n * The platform adapter formats this as proper SSE format:\n * ```\n * event: next\n * data: {\"data\":{\"field\":\"value\"}}\n *\n * ```\n */\n readonly sendEvent: (event: SSEEvent) => Effect.Effect<void, SSEError>\n\n /**\n * Effect that completes when the client disconnects.\n * Use this to detect client disconnection and cleanup.\n */\n readonly closed: Effect.Effect<void, SSEError>\n}\n\n/**\n * The GraphQL request payload for SSE subscriptions.\n * Same as a regular GraphQL HTTP request.\n */\nexport interface SSESubscriptionRequest {\n readonly query: string\n readonly variables?: Record<string, unknown>\n readonly operationName?: string\n readonly extensions?: Record<string, unknown>\n}\n\n/**\n * Context available during an SSE subscription.\n * This is passed to lifecycle hooks.\n */\nexport interface SSEConnectionContext<R> {\n /**\n * The Effect runtime for this connection.\n * Use this to run Effects within the connection scope.\n */\n readonly runtime: Runtime.Runtime<R>\n\n /**\n * The original subscription request.\n */\n readonly request: SSESubscriptionRequest\n\n /**\n * Optional authentication/authorization context.\n * Populated by the onConnect hook.\n */\n readonly connectionContext: Record<string, unknown>\n}\n\n/**\n * Options for configuring the GraphQL SSE handler.\n *\n * @template R - Service requirements for lifecycle hooks\n */\nexport interface GraphQLSSEOptions<R> {\n /**\n * Query complexity limiting configuration.\n * When provided, subscriptions are validated against complexity limits\n * before execution begins.\n */\n readonly complexity?: ComplexityConfig\n\n /**\n * Field complexity definitions from the schema builder.\n * If using the platform serve() functions, this is typically\n * passed automatically.\n */\n readonly fieldComplexities?: FieldComplexityMap\n\n /**\n * Called before a subscription starts.\n *\n * Use this for authentication/authorization. Return:\n * - A context object to accept the subscription\n * - Throw/fail to reject the subscription\n *\n * The returned object is available in the GraphQL context.\n *\n * @example\n * ```typescript\n * onConnect: (request, headers) => Effect.gen(function* () {\n * const token = headers.get(\"authorization\")\n * const user = yield* AuthService.validateToken(token)\n * return { user } // Available in GraphQL context\n * })\n * ```\n */\n readonly onConnect?: (\n request: SSESubscriptionRequest,\n headers: Headers\n ) => Effect.Effect<Record<string, unknown>, unknown, R>\n\n /**\n * Called when the subscription starts streaming.\n */\n readonly onSubscribe?: (ctx: SSEConnectionContext<R>) => Effect.Effect<void, never, R>\n\n /**\n * Called when the subscription completes (normally or due to error).\n */\n readonly onComplete?: (ctx: SSEConnectionContext<R>) => Effect.Effect<void, never, R>\n\n /**\n * Called when the client disconnects.\n */\n readonly onDisconnect?: (ctx: SSEConnectionContext<R>) => Effect.Effect<void, never, R>\n\n /**\n * Called when an error occurs during subscription execution.\n */\n readonly onError?: (ctx: SSEConnectionContext<R>, error: unknown) => Effect.Effect<void, never, R>\n}\n\n/**\n * Configuration for the SSE endpoint\n */\nexport interface GraphQLSSEConfig {\n /**\n * Path for SSE connections.\n * @default \"/graphql/stream\"\n */\n readonly path?: string\n}\n\n/**\n * Result of SSE subscription handler creation.\n * This is used by platform packages to implement their SSE response.\n */\nexport interface SSESubscriptionResult {\n /**\n * Stream of SSE events to send to the client.\n * The platform adapter should consume this stream and send events.\n */\n readonly events: Stream.Stream<SSEEvent, SSEError>\n\n /**\n * Effect that should be run when client disconnects.\n * This allows cleanup of resources.\n */\n readonly cleanup: Effect.Effect<void, never, never>\n}\n\n/**\n * Format an ExecutionResult as an SSE \"next\" event.\n */\nexport const formatNextEvent = (result: ExecutionResult): SSEEvent => ({\n event: \"next\",\n data: JSON.stringify(result),\n})\n\n/**\n * Format errors as an SSE \"error\" event.\n */\nexport const formatErrorEvent = (errors: readonly unknown[]): SSEEvent => ({\n event: \"error\",\n data: JSON.stringify({ errors }),\n})\n\n/**\n * Format a \"complete\" event.\n */\nexport const formatCompleteEvent = (): SSEEvent => ({\n event: \"complete\",\n data: \"\",\n})\n\n/**\n * Format an SSE event to the wire format.\n * Each event is formatted as:\n * ```\n * event: <type>\n * data: <json>\n *\n * ```\n */\nexport const formatSSEMessage = (event: SSEEvent): string => {\n const lines = [`event: ${event.event}`]\n if (event.data) {\n lines.push(`data: ${event.data}`)\n }\n lines.push(\"\", \"\") // Two newlines to end the event\n return lines.join(\"\\n\")\n}\n","import { Effect, Layer, Stream } from \"effect\"\nimport {\n GraphQLSchema,\n parse,\n validate,\n subscribe,\n GraphQLError,\n Kind,\n type ExecutionResult,\n type DocumentNode,\n type OperationDefinitionNode,\n} from \"graphql\"\nimport type { GraphQLEffectContext } from \"../builder/types\"\nimport {\n SSEError,\n type GraphQLSSEOptions,\n type SSEConnectionContext,\n type SSESubscriptionRequest,\n type SSEEvent,\n formatNextEvent,\n formatErrorEvent,\n formatCompleteEvent,\n} from \"./sse-types\"\nimport { validateComplexity, type FieldComplexityMap } from \"./complexity\"\n\n/**\n * Create a subscription event stream for SSE.\n *\n * This function handles the GraphQL subscription lifecycle:\n * 1. Parse and validate the query\n * 2. Check complexity limits if configured\n * 3. Execute the subscription\n * 4. Stream results as SSE events\n *\n * @param schema - The GraphQL schema with subscription definitions\n * @param layer - Effect layer providing services required by resolvers\n * @param request - The subscription request (query, variables, operationName)\n * @param headers - HTTP headers from the request (for auth)\n * @param options - Optional lifecycle hooks and configuration\n * @returns A Stream of SSE events to send to the client\n *\n * @example\n * ```typescript\n * const eventStream = makeSSESubscriptionStream(\n * schema,\n * serviceLayer,\n * { query: \"subscription { tick { count } }\" },\n * new Headers(),\n * { onConnect: (req, headers) => Effect.succeed({ user: \"alice\" }) }\n * )\n *\n * // In platform-specific code, consume and send events:\n * Stream.runForEach(eventStream, (event) =>\n * Effect.sync(() => res.write(formatSSEMessage(event)))\n * )\n * ```\n */\nexport const makeSSESubscriptionStream = <R>(\n schema: GraphQLSchema,\n layer: Layer.Layer<R>,\n request: SSESubscriptionRequest,\n headers: Headers,\n options?: GraphQLSSEOptions<R>\n): Stream.Stream<SSEEvent, SSEError> => {\n const complexityConfig = options?.complexity\n const fieldComplexities: FieldComplexityMap = options?.fieldComplexities ?? new Map()\n\n return Stream.unwrap(\n Effect.gen(function* () {\n // Create a runtime from the layer\n const runtime = yield* Effect.provide(Effect.runtime<R>(), layer)\n\n // Run onConnect hook if provided\n let connectionContext: Record<string, unknown> = {}\n if (options?.onConnect) {\n try {\n connectionContext = yield* Effect.provide(options.onConnect(request, headers), layer)\n } catch {\n // Connection rejected\n return Stream.make(\n formatErrorEvent([\n new GraphQLError(\"Subscription connection rejected\", {\n extensions: { code: \"CONNECTION_REJECTED\" },\n }),\n ]),\n formatCompleteEvent()\n )\n }\n }\n\n // Parse the query\n let document: DocumentNode\n try {\n document = parse(request.query)\n } catch (syntaxError) {\n return Stream.make(formatErrorEvent([syntaxError]), formatCompleteEvent())\n }\n\n // Validate the query\n const validationErrors = validate(schema, document)\n if (validationErrors.length > 0) {\n return Stream.make(formatErrorEvent(validationErrors), formatCompleteEvent())\n }\n\n // Find the subscription operation\n const operations = document.definitions.filter(\n (d): d is OperationDefinitionNode => d.kind === Kind.OPERATION_DEFINITION\n )\n\n const operation = request.operationName\n ? operations.find((o) => o.name?.value === request.operationName)\n : operations[0]\n\n if (!operation) {\n return Stream.make(\n formatErrorEvent([new GraphQLError(\"No operation found in query\")]),\n formatCompleteEvent()\n )\n }\n\n if (operation.operation !== \"subscription\") {\n return Stream.make(\n formatErrorEvent([\n new GraphQLError(\n `SSE endpoint only supports subscriptions, received: ${operation.operation}`,\n { extensions: { code: \"OPERATION_NOT_SUPPORTED\" } }\n ),\n ]),\n formatCompleteEvent()\n )\n }\n\n // Validate complexity if configured\n if (complexityConfig) {\n const complexityResult = yield* validateComplexity(\n request.query,\n request.operationName,\n request.variables,\n schema,\n fieldComplexities,\n complexityConfig\n ).pipe(\n Effect.map(() => null),\n Effect.catchAll((error) => {\n if (error._tag === \"ComplexityLimitExceededError\") {\n return Effect.succeed(\n new GraphQLError(error.message, {\n extensions: {\n code: \"COMPLEXITY_LIMIT_EXCEEDED\",\n limitType: error.limitType,\n limit: error.limit,\n actual: error.actual,\n },\n })\n )\n }\n // Log analysis errors but don't block (fail open)\n return Effect.logWarning(\"Complexity analysis failed for SSE subscription\", error).pipe(\n Effect.map(() => null)\n )\n })\n )\n\n if (complexityResult) {\n return Stream.make(formatErrorEvent([complexityResult]), formatCompleteEvent())\n }\n }\n\n // Build the context for the subscription\n const ctx: SSEConnectionContext<R> = {\n runtime,\n request,\n connectionContext,\n }\n\n // Call onSubscribe hook if provided\n if (options?.onSubscribe) {\n yield* Effect.provide(options.onSubscribe(ctx), layer).pipe(\n Effect.catchAll(() => Effect.void)\n )\n }\n\n // Execute the subscription\n const graphqlContext: GraphQLEffectContext<R> & Record<string, unknown> = {\n runtime,\n ...connectionContext,\n }\n\n const subscriptionResult = yield* Effect.tryPromise({\n try: () =>\n subscribe({\n schema,\n document,\n variableValues: request.variables,\n operationName: request.operationName ?? undefined,\n contextValue: graphqlContext,\n }),\n catch: (error) => new SSEError({ cause: error }),\n })\n\n // Check if subscribe returned an error result instead of async iterator\n if (!isAsyncIterable(subscriptionResult)) {\n // It's an ExecutionResult with errors\n const result = subscriptionResult as ExecutionResult\n if (result.errors) {\n return Stream.make(formatErrorEvent(result.errors), formatCompleteEvent())\n }\n // Shouldn't happen, but handle gracefully\n return Stream.make(formatNextEvent(result), formatCompleteEvent())\n }\n\n // Create a stream from the async iterator\n const asyncIterator = subscriptionResult[Symbol.asyncIterator]()\n\n const eventStream = Stream.async<SSEEvent, SSEError>((emit) => {\n let done = false\n\n const iterate = async () => {\n try {\n while (!done) {\n const result = await asyncIterator.next()\n if (result.done) {\n emit.end()\n break\n }\n emit.single(formatNextEvent(result.value))\n }\n } catch (error) {\n if (!done) {\n emit.single(\n formatErrorEvent([\n error instanceof GraphQLError\n ? error\n : new GraphQLError(\n error instanceof Error ? error.message : \"Subscription error\",\n { extensions: { code: \"SUBSCRIPTION_ERROR\" } }\n ),\n ])\n )\n emit.end()\n }\n }\n }\n\n iterate()\n\n // Return cleanup function\n return Effect.sync(() => {\n done = true\n asyncIterator.return?.()\n })\n })\n\n // Add complete event at the end and handle cleanup\n return eventStream.pipe(\n Stream.onDone(() =>\n Effect.gen(function* () {\n yield* Effect.sync(() => {})\n }).pipe(Effect.asVoid)\n ),\n Stream.concat(Stream.make(formatCompleteEvent())),\n Stream.onDone(() => {\n if (options?.onComplete) {\n return Effect.provide(options.onComplete(ctx), layer).pipe(\n Effect.catchAll(() => Effect.void)\n )\n }\n return Effect.void\n })\n )\n }).pipe(\n Effect.catchAll((error) =>\n Effect.succeed(\n Stream.make(\n formatErrorEvent([\n new GraphQLError(error instanceof Error ? error.message : \"Internal error\", {\n extensions: { code: \"INTERNAL_ERROR\" },\n }),\n ]),\n formatCompleteEvent()\n )\n )\n )\n )\n )\n}\n\n/**\n * Create an SSE subscription handler that can be used with platform-specific servers.\n *\n * This is a higher-level API that returns a handler function. The handler\n * takes a request and headers, and returns a Stream of SSE events.\n *\n * @param schema - The GraphQL schema with subscription definitions\n * @param layer - Effect layer providing services required by resolvers\n * @param options - Optional lifecycle hooks and configuration\n * @returns A handler function for SSE subscription requests\n *\n * @example\n * ```typescript\n * const handler = makeGraphQLSSEHandler(schema, serviceLayer, {\n * onConnect: (request, headers) => Effect.gen(function* () {\n * const token = headers.get(\"authorization\")\n * const user = yield* AuthService.validateToken(token)\n * return { user }\n * }),\n * })\n *\n * // In platform-specific code:\n * const events = handler(request, headers)\n * // Stream events to client...\n * ```\n */\nexport const makeGraphQLSSEHandler = <R>(\n schema: GraphQLSchema,\n layer: Layer.Layer<R>,\n options?: GraphQLSSEOptions<R>\n): ((request: SSESubscriptionRequest, headers: Headers) => Stream.Stream<SSEEvent, SSEError>) => {\n return (request, headers) => makeSSESubscriptionStream(schema, layer, request, headers, options)\n}\n\n/**\n * Type guard to check if a value is an AsyncIterable (subscription result)\n */\nfunction isAsyncIterable<T>(value: unknown): value is AsyncIterable<T> {\n return typeof value === \"object\" && value !== null && Symbol.asyncIterator in value\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/server/config.ts","../../src/server/graphiql.ts","../../src/server/complexity.ts","../../src/server/cache-control.ts","../../src/extensions.ts","../../src/server/router.ts","../../src/server/schema-builder-extensions.ts","../../src/server/ws-types.ts","../../src/server/ws-adapter.ts","../../src/server/ws-utils.ts","../../src/server/sse-types.ts","../../src/server/sse-adapter.ts"],"names":["Config","Option","Effect","Kind","getRootType","analyzeSelectionSet","parse","getNamedType","GraphQLNonNull","GraphQLList","GraphQLObjectType","analyzeFragmentSpread","analyzeInlineFragment","GraphQLSchema","analyzeField","graphqlExecute","extensionData","Data","Runtime","Stream","Queue","Deferred","GraphQLError","validate","subscribe"],"mappings":"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","file":"index.js","sourcesContent":["import { Config, Option } from \"effect\"\nimport type { ComplexityConfig } from \"./complexity\"\nimport type { CacheControlConfig } from \"./cache-control\"\n\n/**\n * Configuration for the GraphiQL UI\n */\nexport interface GraphiQLConfig {\n /** Path where GraphiQL UI is served (default: \"/graphiql\") */\n readonly path: string\n /** URL where GraphiQL sends requests (default: same as graphql path) */\n readonly endpoint: string\n /** WebSocket URL for subscriptions (default: same as endpoint) */\n readonly subscriptionEndpoint?: string\n}\n\n/**\n * Configuration for the GraphQL router\n */\nexport interface GraphQLRouterConfig {\n /** Path for GraphQL endpoint (default: \"/graphql\") */\n readonly path: string\n /** GraphiQL configuration, or false to disable */\n readonly graphiql: false | GraphiQLConfig\n /** Query complexity limiting configuration */\n readonly complexity?: ComplexityConfig\n /** Enable introspection queries (default: true). Set to false in production. */\n readonly introspection: boolean\n /** Cache control configuration for HTTP Cache-Control headers */\n readonly cacheControl?: CacheControlConfig\n}\n\n/**\n * Default configuration values\n */\nexport const defaultConfig: GraphQLRouterConfig = {\n path: \"/graphql\",\n graphiql: false,\n complexity: undefined,\n introspection: true,\n cacheControl: undefined,\n}\n\n/**\n * Normalize user-provided config (which may use boolean shorthand for graphiql)\n * into the full GraphQLRouterConfig format\n */\nexport interface GraphQLRouterConfigInput {\n readonly path?: string\n readonly graphiql?: boolean | Partial<GraphiQLConfig>\n /** Query complexity limiting configuration */\n readonly complexity?: ComplexityConfig\n /** Enable introspection queries (default: true). Set to false in production. */\n readonly introspection?: boolean\n /** Cache control configuration for HTTP Cache-Control headers */\n readonly cacheControl?: CacheControlConfig\n}\n\nexport const normalizeConfig = (input: GraphQLRouterConfigInput = {}): GraphQLRouterConfig => {\n const path = input.path ?? defaultConfig.path\n\n let graphiql: false | GraphiQLConfig = false\n if (input.graphiql === true) {\n graphiql = { path: \"/graphiql\", endpoint: path }\n } else if (input.graphiql && typeof input.graphiql === \"object\") {\n graphiql = {\n path: input.graphiql.path ?? \"/graphiql\",\n endpoint: input.graphiql.endpoint ?? path,\n }\n }\n\n return {\n path,\n graphiql,\n complexity: input.complexity,\n introspection: input.introspection ?? true,\n cacheControl: input.cacheControl,\n }\n}\n\n/**\n * Effect Config for loading GraphQL router configuration from environment variables.\n *\n * Environment variables:\n * - GRAPHQL_PATH: Path for GraphQL endpoint (default: \"/graphql\")\n * - GRAPHQL_INTROSPECTION: Enable introspection queries (default: true)\n * - GRAPHIQL_ENABLED: Enable GraphiQL UI (default: false)\n * - GRAPHIQL_PATH: Path for GraphiQL UI (default: \"/graphiql\")\n * - GRAPHIQL_ENDPOINT: URL where GraphiQL sends requests (default: same as GRAPHQL_PATH)\n * - GRAPHQL_MAX_DEPTH: Maximum query depth (optional)\n * - GRAPHQL_MAX_COMPLEXITY: Maximum complexity score (optional)\n * - GRAPHQL_MAX_ALIASES: Maximum number of aliases (optional)\n * - GRAPHQL_MAX_FIELDS: Maximum number of fields (optional)\n * - GRAPHQL_DEFAULT_FIELD_COMPLEXITY: Default field complexity (default: 1)\n * - GRAPHQL_CACHE_CONTROL_ENABLED: Enable cache control headers (default: false)\n * - GRAPHQL_CACHE_CONTROL_DEFAULT_MAX_AGE: Default maxAge for root fields (default: 0)\n * - GRAPHQL_CACHE_CONTROL_DEFAULT_SCOPE: Default scope - PUBLIC or PRIVATE (default: PUBLIC)\n */\nexport const GraphQLRouterConfigFromEnv: Config.Config<GraphQLRouterConfig> = Config.all({\n path: Config.string(\"GRAPHQL_PATH\").pipe(Config.withDefault(\"/graphql\")),\n introspection: Config.boolean(\"GRAPHQL_INTROSPECTION\").pipe(Config.withDefault(true)),\n graphiqlEnabled: Config.boolean(\"GRAPHIQL_ENABLED\").pipe(Config.withDefault(false)),\n graphiqlPath: Config.string(\"GRAPHIQL_PATH\").pipe(Config.withDefault(\"/graphiql\")),\n graphiqlEndpoint: Config.string(\"GRAPHIQL_ENDPOINT\").pipe(Config.option),\n maxDepth: Config.number(\"GRAPHQL_MAX_DEPTH\").pipe(Config.option),\n maxComplexity: Config.number(\"GRAPHQL_MAX_COMPLEXITY\").pipe(Config.option),\n maxAliases: Config.number(\"GRAPHQL_MAX_ALIASES\").pipe(Config.option),\n maxFields: Config.number(\"GRAPHQL_MAX_FIELDS\").pipe(Config.option),\n defaultFieldComplexity: Config.number(\"GRAPHQL_DEFAULT_FIELD_COMPLEXITY\").pipe(\n Config.withDefault(1)\n ),\n cacheControlEnabled: Config.boolean(\"GRAPHQL_CACHE_CONTROL_ENABLED\").pipe(\n Config.withDefault(false)\n ),\n cacheControlDefaultMaxAge: Config.number(\"GRAPHQL_CACHE_CONTROL_DEFAULT_MAX_AGE\").pipe(\n Config.withDefault(0)\n ),\n cacheControlDefaultScope: Config.string(\"GRAPHQL_CACHE_CONTROL_DEFAULT_SCOPE\").pipe(\n Config.withDefault(\"PUBLIC\")\n ),\n}).pipe(\n Config.map(\n ({\n path,\n introspection,\n graphiqlEnabled,\n graphiqlPath,\n graphiqlEndpoint,\n maxDepth,\n maxComplexity,\n maxAliases,\n maxFields,\n defaultFieldComplexity,\n cacheControlEnabled,\n cacheControlDefaultMaxAge,\n cacheControlDefaultScope,\n }) => {\n // Check if any complexity option is set\n const hasComplexity =\n Option.isSome(maxDepth) ||\n Option.isSome(maxComplexity) ||\n Option.isSome(maxAliases) ||\n Option.isSome(maxFields)\n\n return {\n path,\n introspection,\n graphiql: graphiqlEnabled\n ? {\n path: graphiqlPath,\n endpoint: Option.isSome(graphiqlEndpoint) ? graphiqlEndpoint.value : path,\n }\n : (false as const),\n complexity: hasComplexity\n ? {\n maxDepth: Option.getOrUndefined(maxDepth),\n maxComplexity: Option.getOrUndefined(maxComplexity),\n maxAliases: Option.getOrUndefined(maxAliases),\n maxFields: Option.getOrUndefined(maxFields),\n defaultFieldComplexity,\n }\n : undefined,\n cacheControl: cacheControlEnabled\n ? {\n enabled: true,\n defaultMaxAge: cacheControlDefaultMaxAge,\n defaultScope: (cacheControlDefaultScope === \"PRIVATE\"\n ? \"PRIVATE\"\n : \"PUBLIC\") as import(\"../builder/types\").CacheControlScope,\n calculateHttpHeaders: true,\n }\n : undefined,\n }\n }\n )\n)\n","/**\n * Generate HTML for GraphiQL IDE, loading dependencies from CDN\n */\nexport const graphiqlHtml = (\n endpoint: string,\n subscriptionEndpoint?: string\n): string => `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>GraphiQL</title>\n <link\n rel=\"stylesheet\"\n href=\"https://unpkg.com/graphiql@3/graphiql.min.css\"\n />\n </head>\n <body style=\"margin: 0; overflow: hidden;\">\n <div id=\"graphiql\" style=\"height: 100vh;\"></div>\n <script\n crossorigin\n src=\"https://unpkg.com/react@18/umd/react.production.min.js\"\n ></script>\n <script\n crossorigin\n src=\"https://unpkg.com/react-dom@18/umd/react-dom.production.min.js\"\n ></script>\n <script\n crossorigin\n src=\"https://unpkg.com/graphiql@3/graphiql.min.js\"\n ></script>\n <script>\n const fetcher = GraphiQL.createFetcher({\n url: ${JSON.stringify(endpoint)},\n subscriptionUrl: ${JSON.stringify(subscriptionEndpoint ?? endpoint)},\n });\n ReactDOM.createRoot(document.getElementById('graphiql')).render(\n React.createElement(GraphiQL, { fetcher })\n );\n </script>\n </body>\n</html>`\n","import { Effect, Option, Config, Data } from \"effect\"\nimport {\n DocumentNode,\n OperationDefinitionNode,\n FieldNode,\n FragmentDefinitionNode,\n FragmentSpreadNode,\n InlineFragmentNode,\n SelectionSetNode,\n GraphQLSchema,\n GraphQLObjectType,\n GraphQLOutputType,\n GraphQLNonNull,\n GraphQLList,\n Kind,\n parse,\n} from \"graphql\"\n\n// ============================================================================\n// Errors\n// ============================================================================\n\n/**\n * Error thrown when query complexity exceeds configured limits\n */\nexport class ComplexityLimitExceededError extends Data.TaggedError(\"ComplexityLimitExceededError\")<{\n readonly message: string\n readonly limit: number\n readonly actual: number\n readonly limitType: \"depth\" | \"complexity\" | \"aliases\" | \"fields\"\n}> {}\n\n/**\n * Error thrown when complexity analysis fails\n */\nexport class ComplexityAnalysisError extends Data.TaggedError(\"ComplexityAnalysisError\")<{\n readonly message: string\n readonly cause?: unknown\n}> {}\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of complexity analysis for a GraphQL operation\n */\nexport interface ComplexityResult {\n /** Maximum depth of the query */\n readonly depth: number\n /** Total complexity score */\n readonly complexity: number\n /** Number of field selections (including nested) */\n readonly fieldCount: number\n /** Number of aliased fields */\n readonly aliasCount: number\n}\n\n/**\n * Information provided to complexity calculators\n */\nexport interface ComplexityAnalysisInfo {\n /** Parsed GraphQL document */\n readonly document: DocumentNode\n /** The operation being executed */\n readonly operation: OperationDefinitionNode\n /** Variables provided with the query */\n readonly variables?: Record<string, unknown>\n /** The GraphQL schema */\n readonly schema: GraphQLSchema\n /** Field complexity definitions from the builder */\n readonly fieldComplexities: FieldComplexityMap\n}\n\n/**\n * Information provided when complexity limit is exceeded\n */\nexport interface ComplexityExceededInfo {\n /** The computed complexity result */\n readonly result: ComplexityResult\n /** Which limit was exceeded */\n readonly exceededLimit: \"depth\" | \"complexity\" | \"aliases\" | \"fields\"\n /** The limit value */\n readonly limit: number\n /** The actual value */\n readonly actual: number\n /** The query that exceeded limits */\n readonly query: string\n /** Operation name if provided */\n readonly operationName?: string\n}\n\n/**\n * Complexity value for a field - can be static or dynamic based on arguments\n */\nexport type FieldComplexity = number | ((args: Record<string, unknown>) => number)\n\n/**\n * Map of type.field -> complexity\n */\nexport type FieldComplexityMap = Map<string, FieldComplexity>\n\n/**\n * Custom complexity calculator function.\n * Must be self-contained (no service requirements).\n */\nexport type ComplexityCalculator = (\n info: ComplexityAnalysisInfo\n) => Effect.Effect<ComplexityResult, ComplexityAnalysisError, never>\n\n/**\n * Configuration for query complexity limiting\n */\nexport interface ComplexityConfig {\n /**\n * Maximum allowed query depth.\n * Depth is the deepest nesting level in the query.\n * @example\n * // Depth 3:\n * // { user { posts { comments { text } } } }\n */\n readonly maxDepth?: number\n\n /**\n * Maximum allowed total complexity score.\n * Complexity is calculated by summing field costs.\n */\n readonly maxComplexity?: number\n\n /**\n * Maximum number of field aliases allowed.\n * Prevents response explosion attacks via aliases.\n */\n readonly maxAliases?: number\n\n /**\n * Maximum total number of fields in the query.\n * Includes all nested field selections.\n */\n readonly maxFields?: number\n\n /**\n * Default complexity cost for fields without explicit costs.\n * @default 1\n */\n readonly defaultFieldComplexity?: number\n\n /**\n * Custom complexity calculator.\n * If provided, this is used instead of the default calculator.\n * Can be used to implement custom cost algorithms.\n */\n readonly calculator?: ComplexityCalculator\n\n /**\n * Hook called when a limit is exceeded.\n * Useful for logging, metrics, or custom handling.\n * This is called BEFORE the error is thrown.\n * Must be self-contained (no service requirements).\n */\n readonly onExceeded?: (info: ComplexityExceededInfo) => Effect.Effect<void, never, never>\n}\n\n// ============================================================================\n// Default Calculator\n// ============================================================================\n\n/**\n * Default complexity calculator that walks the AST and computes:\n * - depth: Maximum nesting level\n * - complexity: Sum of field costs\n * - fieldCount: Total number of field selections\n * - aliasCount: Number of aliased fields\n */\nexport const defaultComplexityCalculator = (defaultCost: number = 1): ComplexityCalculator => {\n return (info: ComplexityAnalysisInfo) =>\n Effect.try({\n try: () => {\n const fragments = new Map<string, FragmentDefinitionNode>()\n\n // Collect fragment definitions\n for (const definition of info.document.definitions) {\n if (definition.kind === Kind.FRAGMENT_DEFINITION) {\n fragments.set(definition.name.value, definition)\n }\n }\n\n // Get the root type for the operation\n const rootType = getRootType(info.schema, info.operation.operation)\n if (!rootType) {\n throw new Error(`No root type found for operation: ${info.operation.operation}`)\n }\n\n // Analyze the selection set\n const result = analyzeSelectionSet(\n info.operation.selectionSet,\n rootType,\n info.schema,\n fragments,\n info.fieldComplexities,\n info.variables ?? {},\n defaultCost,\n 1, // Starting depth\n new Set() // Visited fragments to prevent infinite loops\n )\n\n return result\n },\n catch: (error) =>\n new ComplexityAnalysisError({\n message: `Failed to analyze query complexity: ${error}`,\n cause: error,\n }),\n })\n}\n\n/**\n * Get the root type for an operation\n */\nfunction getRootType(\n schema: GraphQLSchema,\n operation: \"query\" | \"mutation\" | \"subscription\"\n): GraphQLObjectType | null {\n switch (operation) {\n case \"query\":\n return schema.getQueryType() ?? null\n case \"mutation\":\n return schema.getMutationType() ?? null\n case \"subscription\":\n return schema.getSubscriptionType() ?? null\n }\n}\n\n/**\n * Get the named type from a potentially wrapped type\n */\nfunction getNamedType(type: GraphQLOutputType): GraphQLObjectType | null {\n if (type instanceof GraphQLNonNull || type instanceof GraphQLList) {\n return getNamedType(type.ofType as GraphQLOutputType)\n }\n if (type instanceof GraphQLObjectType) {\n return type\n }\n return null\n}\n\n/**\n * Merge a child result into an accumulator (mutates accumulator)\n */\nfunction accumulateResult(\n acc: { maxDepth: number; complexity: number; fieldCount: number; aliasCount: number },\n result: ComplexityResult\n): void {\n acc.maxDepth = Math.max(acc.maxDepth, result.depth)\n acc.complexity += result.complexity\n acc.fieldCount += result.fieldCount\n acc.aliasCount += result.aliasCount\n}\n\n/**\n * Analysis context passed through the recursive analysis functions\n */\ninterface AnalysisContext {\n readonly schema: GraphQLSchema\n readonly fragments: Map<string, FragmentDefinitionNode>\n readonly fieldComplexities: FieldComplexityMap\n readonly variables: Record<string, unknown>\n readonly defaultCost: number\n}\n\n/**\n * Analyze a selection set and return complexity metrics\n */\nfunction analyzeSelectionSet(\n selectionSet: SelectionSetNode,\n parentType: GraphQLObjectType,\n schema: GraphQLSchema,\n fragments: Map<string, FragmentDefinitionNode>,\n fieldComplexities: FieldComplexityMap,\n variables: Record<string, unknown>,\n defaultCost: number,\n currentDepth: number,\n visitedFragments: Set<string>\n): ComplexityResult {\n const ctx: AnalysisContext = { schema, fragments, fieldComplexities, variables, defaultCost }\n const acc = { maxDepth: currentDepth, complexity: 0, fieldCount: 0, aliasCount: 0 }\n\n for (const selection of selectionSet.selections) {\n const result = analyzeSelection(selection, parentType, ctx, currentDepth, visitedFragments)\n accumulateResult(acc, result)\n }\n\n return {\n depth: acc.maxDepth,\n complexity: acc.complexity,\n fieldCount: acc.fieldCount,\n aliasCount: acc.aliasCount,\n }\n}\n\n/**\n * Analyze a single selection node (field, fragment spread, or inline fragment)\n */\nfunction analyzeSelection(\n selection: FieldNode | FragmentSpreadNode | InlineFragmentNode,\n parentType: GraphQLObjectType,\n ctx: AnalysisContext,\n currentDepth: number,\n visitedFragments: Set<string>\n): ComplexityResult {\n switch (selection.kind) {\n case Kind.FIELD:\n return analyzeField(selection, parentType, ctx, currentDepth, visitedFragments)\n case Kind.FRAGMENT_SPREAD:\n return analyzeFragmentSpread(selection, ctx, currentDepth, visitedFragments)\n case Kind.INLINE_FRAGMENT:\n return analyzeInlineFragment(selection, parentType, ctx, currentDepth, visitedFragments)\n }\n}\n\n/**\n * Analyze a field node\n */\nfunction analyzeField(\n field: FieldNode,\n parentType: GraphQLObjectType,\n ctx: AnalysisContext,\n currentDepth: number,\n visitedFragments: Set<string>\n): ComplexityResult {\n const fieldName = field.name.value\n const aliasCount = field.alias ? 1 : 0\n\n // Introspection fields\n if (fieldName.startsWith(\"__\")) {\n return { depth: currentDepth, complexity: 0, fieldCount: 1, aliasCount }\n }\n\n // Get the field from the schema\n const schemaField = parentType.getFields()[fieldName]\n if (!schemaField) {\n // Field not found - skip (will be caught by validation)\n return { depth: currentDepth, complexity: ctx.defaultCost, fieldCount: 1, aliasCount }\n }\n\n // Calculate field arguments\n const args = resolveFieldArguments(field, ctx.variables)\n\n // Get field complexity\n const complexityKey = `${parentType.name}.${fieldName}`\n const fieldComplexity = ctx.fieldComplexities.get(complexityKey)\n const cost =\n fieldComplexity !== undefined\n ? typeof fieldComplexity === \"function\"\n ? fieldComplexity(args)\n : fieldComplexity\n : ctx.defaultCost\n\n // If the field has a selection set, analyze it\n if (field.selectionSet) {\n const fieldType = getNamedType(schemaField.type)\n if (fieldType) {\n const nestedResult = analyzeSelectionSet(\n field.selectionSet,\n fieldType,\n ctx.schema,\n ctx.fragments,\n ctx.fieldComplexities,\n ctx.variables,\n ctx.defaultCost,\n currentDepth + 1,\n visitedFragments\n )\n return {\n depth: nestedResult.depth,\n complexity: cost + nestedResult.complexity,\n fieldCount: 1 + nestedResult.fieldCount,\n aliasCount: aliasCount + nestedResult.aliasCount,\n }\n }\n }\n\n return { depth: currentDepth, complexity: cost, fieldCount: 1, aliasCount }\n}\n\n/**\n * Analyze a fragment spread\n */\nfunction analyzeFragmentSpread(\n spread: FragmentSpreadNode,\n ctx: AnalysisContext,\n currentDepth: number,\n visitedFragments: Set<string>\n): ComplexityResult {\n const fragmentName = spread.name.value\n\n // Prevent infinite loops with fragment cycles\n if (visitedFragments.has(fragmentName)) {\n return { depth: currentDepth, complexity: 0, fieldCount: 0, aliasCount: 0 }\n }\n\n const fragment = ctx.fragments.get(fragmentName)\n if (!fragment) {\n return { depth: currentDepth, complexity: 0, fieldCount: 0, aliasCount: 0 }\n }\n\n const fragmentType = ctx.schema.getType(fragment.typeCondition.name.value)\n if (!(fragmentType instanceof GraphQLObjectType)) {\n return { depth: currentDepth, complexity: 0, fieldCount: 0, aliasCount: 0 }\n }\n\n const newVisited = new Set(visitedFragments)\n newVisited.add(fragmentName)\n\n return analyzeSelectionSet(\n fragment.selectionSet,\n fragmentType,\n ctx.schema,\n ctx.fragments,\n ctx.fieldComplexities,\n ctx.variables,\n ctx.defaultCost,\n currentDepth,\n newVisited\n )\n}\n\n/**\n * Analyze an inline fragment\n */\nfunction analyzeInlineFragment(\n fragment: InlineFragmentNode,\n parentType: GraphQLObjectType,\n ctx: AnalysisContext,\n currentDepth: number,\n visitedFragments: Set<string>\n): ComplexityResult {\n let targetType = parentType\n\n if (fragment.typeCondition) {\n const conditionType = ctx.schema.getType(fragment.typeCondition.name.value)\n if (conditionType instanceof GraphQLObjectType) {\n targetType = conditionType\n }\n }\n\n return analyzeSelectionSet(\n fragment.selectionSet,\n targetType,\n ctx.schema,\n ctx.fragments,\n ctx.fieldComplexities,\n ctx.variables,\n ctx.defaultCost,\n currentDepth,\n visitedFragments\n )\n}\n\n/**\n * Resolve field arguments, substituting variables\n */\nfunction resolveFieldArguments(\n field: FieldNode,\n variables: Record<string, unknown>\n): Record<string, unknown> {\n const args: Record<string, unknown> = {}\n\n if (!field.arguments) {\n return args\n }\n\n for (const arg of field.arguments) {\n const value = arg.value\n switch (value.kind) {\n case Kind.VARIABLE:\n args[arg.name.value] = variables[value.name.value]\n break\n case Kind.INT:\n args[arg.name.value] = parseInt(value.value, 10)\n break\n case Kind.FLOAT:\n args[arg.name.value] = parseFloat(value.value)\n break\n case Kind.STRING:\n args[arg.name.value] = value.value\n break\n case Kind.BOOLEAN:\n args[arg.name.value] = value.value\n break\n case Kind.NULL:\n args[arg.name.value] = null\n break\n case Kind.ENUM:\n args[arg.name.value] = value.value\n break\n case Kind.LIST:\n // Simplified - just use empty array for complexity calculation\n args[arg.name.value] = []\n break\n case Kind.OBJECT:\n // Simplified - just use empty object for complexity calculation\n args[arg.name.value] = {}\n break\n }\n }\n\n return args\n}\n\n// ============================================================================\n// Validation\n// ============================================================================\n\n/**\n * Validate query complexity against configured limits.\n * Returns the complexity result if within limits, or fails with ComplexityLimitExceededError.\n */\nexport const validateComplexity = (\n query: string,\n operationName: string | undefined,\n variables: Record<string, unknown> | undefined,\n schema: GraphQLSchema,\n fieldComplexities: FieldComplexityMap,\n config: ComplexityConfig\n): Effect.Effect<ComplexityResult, ComplexityLimitExceededError | ComplexityAnalysisError, never> =>\n Effect.gen(function* () {\n // Parse the query\n const document = yield* Effect.try({\n try: () => parse(query),\n catch: (error) =>\n new ComplexityAnalysisError({\n message: `Failed to parse query: ${error}`,\n cause: error,\n }),\n })\n\n // Find the operation\n const operation = yield* Effect.try({\n try: () => {\n const operations = document.definitions.filter(\n (d): d is OperationDefinitionNode => d.kind === Kind.OPERATION_DEFINITION\n )\n\n if (operations.length === 0) {\n throw new Error(\"No operation found in query\")\n }\n\n if (operationName) {\n const op = operations.find((o) => o.name?.value === operationName)\n if (!op) {\n throw new Error(`Operation \"${operationName}\" not found`)\n }\n return op\n }\n\n if (operations.length > 1) {\n throw new Error(\"Multiple operations found - operationName required\")\n }\n\n return operations[0]\n },\n catch: (error) =>\n new ComplexityAnalysisError({\n message: String(error),\n cause: error,\n }),\n })\n\n // Calculate complexity\n const calculator =\n config.calculator ?? defaultComplexityCalculator(config.defaultFieldComplexity ?? 1)\n\n const result = yield* calculator({\n document,\n operation,\n variables,\n schema,\n fieldComplexities,\n })\n\n // Check limits\n const checkLimit = (\n limitType: \"depth\" | \"complexity\" | \"aliases\" | \"fields\",\n limit: number | undefined,\n actual: number\n ) =>\n Effect.gen(function* () {\n if (limit !== undefined && actual > limit) {\n const exceededInfo: ComplexityExceededInfo = {\n result,\n exceededLimit: limitType,\n limit,\n actual,\n query,\n operationName,\n }\n\n // Call onExceeded hook if provided\n if (config.onExceeded) {\n yield* config.onExceeded(exceededInfo)\n }\n\n yield* Effect.fail(\n new ComplexityLimitExceededError({\n message: `Query ${limitType} of ${actual} exceeds maximum allowed ${limitType} of ${limit}`,\n limit,\n actual,\n limitType,\n })\n )\n }\n })\n\n yield* checkLimit(\"depth\", config.maxDepth, result.depth)\n yield* checkLimit(\"complexity\", config.maxComplexity, result.complexity)\n yield* checkLimit(\"aliases\", config.maxAliases, result.aliasCount)\n yield* checkLimit(\"fields\", config.maxFields, result.fieldCount)\n\n return result\n })\n\n// ============================================================================\n// Environment Configuration\n// ============================================================================\n\n/**\n * Effect Config for loading complexity configuration from environment variables.\n *\n * Environment variables:\n * - GRAPHQL_MAX_DEPTH: Maximum query depth\n * - GRAPHQL_MAX_COMPLEXITY: Maximum complexity score\n * - GRAPHQL_MAX_ALIASES: Maximum number of aliases\n * - GRAPHQL_MAX_FIELDS: Maximum number of fields\n * - GRAPHQL_DEFAULT_FIELD_COMPLEXITY: Default field complexity (default: 1)\n */\nexport const ComplexityConfigFromEnv: Config.Config<ComplexityConfig> = Config.all({\n maxDepth: Config.number(\"GRAPHQL_MAX_DEPTH\").pipe(Config.option),\n maxComplexity: Config.number(\"GRAPHQL_MAX_COMPLEXITY\").pipe(Config.option),\n maxAliases: Config.number(\"GRAPHQL_MAX_ALIASES\").pipe(Config.option),\n maxFields: Config.number(\"GRAPHQL_MAX_FIELDS\").pipe(Config.option),\n defaultFieldComplexity: Config.number(\"GRAPHQL_DEFAULT_FIELD_COMPLEXITY\").pipe(\n Config.withDefault(1)\n ),\n}).pipe(\n Config.map(({ maxDepth, maxComplexity, maxAliases, maxFields, defaultFieldComplexity }) => ({\n maxDepth: Option.getOrUndefined(maxDepth),\n maxComplexity: Option.getOrUndefined(maxComplexity),\n maxAliases: Option.getOrUndefined(maxAliases),\n maxFields: Option.getOrUndefined(maxFields),\n defaultFieldComplexity,\n }))\n)\n\n// ============================================================================\n// Utility Calculators\n// ============================================================================\n\n/**\n * A simple depth-only calculator that only tracks query depth.\n * Use this when you only care about depth limiting and want fast validation.\n */\nexport const depthOnlyCalculator: ComplexityCalculator = (info) =>\n Effect.try({\n try: () => {\n const fragments = new Map<string, FragmentDefinitionNode>()\n for (const definition of info.document.definitions) {\n if (definition.kind === Kind.FRAGMENT_DEFINITION) {\n fragments.set(definition.name.value, definition)\n }\n }\n\n const depth = calculateMaxDepth(info.operation.selectionSet, fragments, 1, new Set())\n\n return {\n depth,\n complexity: 0,\n fieldCount: 0,\n aliasCount: 0,\n }\n },\n catch: (error) =>\n new ComplexityAnalysisError({\n message: `Failed to analyze query depth: ${error}`,\n cause: error,\n }),\n })\n\nfunction calculateMaxDepth(\n selectionSet: SelectionSetNode,\n fragments: Map<string, FragmentDefinitionNode>,\n currentDepth: number,\n visitedFragments: Set<string>\n): number {\n let maxDepth = currentDepth\n\n for (const selection of selectionSet.selections) {\n switch (selection.kind) {\n case Kind.FIELD:\n if (selection.selectionSet) {\n const nestedDepth = calculateMaxDepth(\n selection.selectionSet,\n fragments,\n currentDepth + 1,\n visitedFragments\n )\n maxDepth = Math.max(maxDepth, nestedDepth)\n }\n break\n\n case Kind.FRAGMENT_SPREAD: {\n const fragmentName = selection.name.value\n if (!visitedFragments.has(fragmentName)) {\n const fragment = fragments.get(fragmentName)\n if (fragment) {\n const newVisited = new Set(visitedFragments)\n newVisited.add(fragmentName)\n const fragmentDepth = calculateMaxDepth(\n fragment.selectionSet,\n fragments,\n currentDepth,\n newVisited\n )\n maxDepth = Math.max(maxDepth, fragmentDepth)\n }\n }\n break\n }\n\n case Kind.INLINE_FRAGMENT: {\n const inlineDepth = calculateMaxDepth(\n selection.selectionSet,\n fragments,\n currentDepth,\n visitedFragments\n )\n maxDepth = Math.max(maxDepth, inlineDepth)\n break\n }\n }\n }\n\n return maxDepth\n}\n\n/**\n * Combine multiple calculators - returns the maximum values from all calculators.\n */\nexport const combineCalculators = (\n ...calculators: ComplexityCalculator[]\n): ComplexityCalculator => {\n return (info) =>\n Effect.gen(function* () {\n let maxDepth = 0\n let maxComplexity = 0\n let maxFieldCount = 0\n let maxAliasCount = 0\n\n for (const calculator of calculators) {\n const result = yield* calculator(info)\n maxDepth = Math.max(maxDepth, result.depth)\n maxComplexity = Math.max(maxComplexity, result.complexity)\n maxFieldCount = Math.max(maxFieldCount, result.fieldCount)\n maxAliasCount = Math.max(maxAliasCount, result.aliasCount)\n }\n\n return {\n depth: maxDepth,\n complexity: maxComplexity,\n fieldCount: maxFieldCount,\n aliasCount: maxAliasCount,\n }\n })\n}\n","import { Effect, Config } from \"effect\"\nimport {\n DocumentNode,\n OperationDefinitionNode,\n FieldNode,\n FragmentDefinitionNode,\n SelectionSetNode,\n GraphQLSchema,\n GraphQLObjectType,\n GraphQLOutputType,\n GraphQLNonNull,\n GraphQLList,\n GraphQLScalarType,\n GraphQLEnumType,\n Kind,\n parse,\n} from \"graphql\"\nimport type { CacheHint, CacheControlScope } from \"../builder/types\"\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Map of type.field -> cache hint, or type -> cache hint for type-level hints\n */\nexport type CacheHintMap = Map<string, CacheHint>\n\n/**\n * Computed cache policy for a GraphQL response\n */\nexport interface CachePolicy {\n /**\n * Maximum age in seconds the response can be cached.\n * This is the minimum maxAge of all resolved fields.\n * If 0, the response should not be cached.\n */\n readonly maxAge: number\n\n /**\n * Cache scope - PUBLIC means CDN-cacheable, PRIVATE means browser-only.\n * If any field is PRIVATE, the entire response is PRIVATE.\n */\n readonly scope: CacheControlScope\n}\n\n/**\n * Configuration for cache control\n */\nexport interface CacheControlConfig {\n /**\n * Enable cache control header calculation.\n * @default true\n */\n readonly enabled?: boolean\n\n /**\n * Default maxAge for root fields (Query, Mutation).\n * @default 0 (no caching)\n */\n readonly defaultMaxAge?: number\n\n /**\n * Default scope for fields without explicit scope.\n * @default \"PUBLIC\"\n */\n readonly defaultScope?: CacheControlScope\n\n /**\n * Whether to set HTTP Cache-Control headers on responses.\n * @default true\n */\n readonly calculateHttpHeaders?: boolean\n}\n\n/**\n * Information provided to cache policy calculation\n */\nexport interface CachePolicyAnalysisInfo {\n /** Parsed GraphQL document */\n readonly document: DocumentNode\n /** The operation being executed */\n readonly operation: OperationDefinitionNode\n /** The GraphQL schema */\n readonly schema: GraphQLSchema\n /** Cache hints from the builder (type.field -> hint or type -> hint) */\n readonly cacheHints: CacheHintMap\n /** Configuration options */\n readonly config: CacheControlConfig\n}\n\n// ============================================================================\n// Cache Policy Computation\n// ============================================================================\n\n/**\n * Compute the cache policy for a GraphQL response based on the fields resolved.\n *\n * The policy is computed by walking the selection set and aggregating hints:\n * - maxAge: Use the minimum maxAge of all resolved fields\n * - scope: If any field is PRIVATE, the entire response is PRIVATE\n *\n * Default behaviors (matching Apollo):\n * - Root fields default to maxAge: 0 (unless configured otherwise)\n * - Object-returning fields default to maxAge: 0\n * - Scalar fields inherit their parent's maxAge\n * - Fields with inheritMaxAge: true inherit from parent\n */\nexport const computeCachePolicy = (\n info: CachePolicyAnalysisInfo\n): Effect.Effect<CachePolicy, never, never> =>\n Effect.sync(() => {\n const fragments = new Map<string, FragmentDefinitionNode>()\n\n // Collect fragment definitions\n for (const definition of info.document.definitions) {\n if (definition.kind === Kind.FRAGMENT_DEFINITION) {\n fragments.set(definition.name.value, definition)\n }\n }\n\n // Get the root type for the operation\n const rootType = getRootType(info.schema, info.operation.operation)\n if (!rootType) {\n // No root type - return no-cache\n return { maxAge: 0, scope: \"PUBLIC\" as const }\n }\n\n const defaultMaxAge = info.config.defaultMaxAge ?? 0\n const defaultScope = info.config.defaultScope ?? \"PUBLIC\"\n\n // Analyze the selection set\n const result = analyzeSelectionSet(\n info.operation.selectionSet,\n rootType,\n info.schema,\n fragments,\n info.cacheHints,\n defaultMaxAge,\n defaultScope,\n undefined, // No parent maxAge for root\n new Set()\n )\n\n return result\n })\n\n/**\n * Compute cache policy from a query string\n */\nexport const computeCachePolicyFromQuery = (\n query: string,\n operationName: string | undefined,\n schema: GraphQLSchema,\n cacheHints: CacheHintMap,\n config: CacheControlConfig = {}\n): Effect.Effect<CachePolicy, Error, never> =>\n Effect.gen(function* () {\n // Parse the query\n const document = yield* Effect.try({\n try: () => parse(query),\n catch: (error) => new Error(`Failed to parse query: ${error}`),\n })\n\n // Find the operation\n const operation = yield* Effect.try({\n try: () => {\n const operations = document.definitions.filter(\n (d): d is OperationDefinitionNode => d.kind === Kind.OPERATION_DEFINITION\n )\n\n if (operations.length === 0) {\n throw new Error(\"No operation found in query\")\n }\n\n if (operationName) {\n const op = operations.find((o) => o.name?.value === operationName)\n if (!op) {\n throw new Error(`Operation \"${operationName}\" not found`)\n }\n return op\n }\n\n if (operations.length > 1) {\n throw new Error(\"Multiple operations found - operationName required\")\n }\n\n return operations[0]\n },\n catch: (error) => error as Error,\n })\n\n return yield* computeCachePolicy({\n document,\n operation,\n schema,\n cacheHints,\n config,\n })\n })\n\n/**\n * Convert a cache policy to an HTTP Cache-Control header value\n */\nexport const toCacheControlHeader = (policy: CachePolicy): string => {\n if (policy.maxAge === 0) {\n return \"no-store\"\n }\n\n const directives: string[] = []\n directives.push(policy.scope === \"PRIVATE\" ? \"private\" : \"public\")\n directives.push(`max-age=${policy.maxAge}`)\n\n return directives.join(\", \")\n}\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\n/**\n * Get the root type for an operation\n */\nfunction getRootType(\n schema: GraphQLSchema,\n operation: \"query\" | \"mutation\" | \"subscription\"\n): GraphQLObjectType | null {\n switch (operation) {\n case \"query\":\n return schema.getQueryType() ?? null\n case \"mutation\":\n return schema.getMutationType() ?? null\n case \"subscription\":\n return schema.getSubscriptionType() ?? null\n }\n}\n\n/**\n * Get the named type from a potentially wrapped type\n */\nfunction getNamedType(\n type: GraphQLOutputType\n): GraphQLObjectType | GraphQLScalarType | GraphQLEnumType | null {\n if (type instanceof GraphQLNonNull || type instanceof GraphQLList) {\n return getNamedType(type.ofType as GraphQLOutputType)\n }\n if (\n type instanceof GraphQLObjectType ||\n type instanceof GraphQLScalarType ||\n type instanceof GraphQLEnumType\n ) {\n return type\n }\n return null\n}\n\n/**\n * Check if a type is a scalar or enum (leaf type)\n */\nfunction isLeafType(type: GraphQLOutputType): boolean {\n const namedType = getNamedType(type)\n return namedType instanceof GraphQLScalarType || namedType instanceof GraphQLEnumType\n}\n\n/**\n * Context passed through the analysis functions\n */\ninterface AnalysisContext {\n schema: GraphQLSchema\n fragments: Map<string, FragmentDefinitionNode>\n cacheHints: CacheHintMap\n defaultMaxAge: number\n defaultScope: CacheControlScope\n}\n\n/**\n * Mutable state for aggregating cache policies\n */\ninterface PolicyAccumulator {\n minMaxAge: number | undefined\n hasPrivate: boolean\n}\n\n/**\n * Aggregate a field policy into the accumulator\n */\nfunction aggregatePolicy(acc: PolicyAccumulator, policy: CachePolicy): void {\n if (acc.minMaxAge === undefined) {\n acc.minMaxAge = policy.maxAge\n } else {\n acc.minMaxAge = Math.min(acc.minMaxAge, policy.maxAge)\n }\n if (policy.scope === \"PRIVATE\") {\n acc.hasPrivate = true\n }\n}\n\n/**\n * Analyze a fragment spread and return its cache policy\n */\nfunction analyzeFragmentSpread(\n fragmentName: string,\n ctx: AnalysisContext,\n parentMaxAge: number | undefined,\n visitedFragments: Set<string>\n): CachePolicy | undefined {\n // Prevent infinite loops with fragment cycles\n if (visitedFragments.has(fragmentName)) {\n return undefined\n }\n\n const fragment = ctx.fragments.get(fragmentName)\n if (!fragment) {\n return undefined\n }\n\n const fragmentType = ctx.schema.getType(fragment.typeCondition.name.value)\n if (!(fragmentType instanceof GraphQLObjectType)) {\n return undefined\n }\n\n const newVisited = new Set(visitedFragments)\n newVisited.add(fragmentName)\n\n return analyzeSelectionSet(fragment.selectionSet, fragmentType, ctx, parentMaxAge, newVisited)\n}\n\n/**\n * Analyze an inline fragment and return its cache policy\n */\nfunction analyzeInlineFragment(\n selection: { typeCondition?: { name: { value: string } }; selectionSet: SelectionSetNode },\n parentType: GraphQLObjectType,\n ctx: AnalysisContext,\n parentMaxAge: number | undefined,\n visitedFragments: Set<string>\n): CachePolicy {\n let targetType = parentType\n\n if (selection.typeCondition) {\n const conditionType = ctx.schema.getType(selection.typeCondition.name.value)\n if (conditionType instanceof GraphQLObjectType) {\n targetType = conditionType\n }\n }\n\n return analyzeSelectionSet(\n selection.selectionSet,\n targetType,\n ctx,\n parentMaxAge,\n visitedFragments\n )\n}\n\n/**\n * Look up the effective cache hint for a field (field-level > type-level > undefined)\n */\nfunction lookupEffectiveCacheHint(\n parentTypeName: string,\n fieldName: string,\n returnType: GraphQLOutputType,\n cacheHints: CacheHintMap\n): CacheHint | undefined {\n // Priority: field-level hint > type-level hint\n const fieldKey = `${parentTypeName}.${fieldName}`\n const fieldHint = cacheHints.get(fieldKey)\n if (fieldHint) return fieldHint\n\n // Check type-level hint on return type\n const namedType = getNamedType(returnType)\n return namedType ? cacheHints.get(namedType.name) : undefined\n}\n\n/**\n * Compute the maxAge for a field based on hint, inheritance, and field type\n */\nfunction computeFieldMaxAge(\n hint: CacheHint | undefined,\n fieldType: GraphQLOutputType,\n parentMaxAge: number | undefined,\n defaultMaxAge: number\n): number {\n if (hint) {\n // Use explicit hint\n if (hint.inheritMaxAge && parentMaxAge !== undefined) {\n return parentMaxAge\n }\n if (hint.maxAge !== undefined) {\n return hint.maxAge\n }\n // Fall through to default logic\n }\n\n // Scalar/enum fields inherit parent maxAge by default\n if (isLeafType(fieldType) && parentMaxAge !== undefined) {\n return parentMaxAge\n }\n\n // Root and object fields default to defaultMaxAge (typically 0)\n return defaultMaxAge\n}\n\n/**\n * Analyze a selection set and return the aggregated cache policy.\n * Overload with AnalysisContext for internal use.\n */\nfunction analyzeSelectionSet(\n selectionSet: SelectionSetNode,\n parentType: GraphQLObjectType,\n ctx: AnalysisContext,\n parentMaxAge: number | undefined,\n visitedFragments: Set<string>\n): CachePolicy\nfunction analyzeSelectionSet(\n selectionSet: SelectionSetNode,\n parentType: GraphQLObjectType,\n schema: GraphQLSchema,\n fragments: Map<string, FragmentDefinitionNode>,\n cacheHints: CacheHintMap,\n defaultMaxAge: number,\n defaultScope: CacheControlScope,\n parentMaxAge: number | undefined,\n visitedFragments: Set<string>\n): CachePolicy\nfunction analyzeSelectionSet(\n selectionSet: SelectionSetNode,\n parentType: GraphQLObjectType,\n schemaOrCtx: GraphQLSchema | AnalysisContext,\n fragmentsOrParentMaxAge: Map<string, FragmentDefinitionNode> | number | undefined,\n cacheHintsOrVisited?: CacheHintMap | Set<string>,\n defaultMaxAge?: number,\n defaultScope?: CacheControlScope,\n parentMaxAge?: number | undefined,\n visitedFragments?: Set<string>\n): CachePolicy {\n // Normalize arguments - support both old and new signatures\n let ctx: AnalysisContext\n let actualParentMaxAge: number | undefined\n let actualVisitedFragments: Set<string>\n\n if (schemaOrCtx instanceof GraphQLSchema) {\n // Old signature\n ctx = {\n schema: schemaOrCtx,\n fragments: fragmentsOrParentMaxAge as Map<string, FragmentDefinitionNode>,\n cacheHints: cacheHintsOrVisited as CacheHintMap,\n defaultMaxAge: defaultMaxAge!,\n defaultScope: defaultScope!,\n }\n actualParentMaxAge = parentMaxAge\n actualVisitedFragments = visitedFragments!\n } else {\n // New signature with AnalysisContext\n ctx = schemaOrCtx\n actualParentMaxAge = fragmentsOrParentMaxAge as number | undefined\n actualVisitedFragments = cacheHintsOrVisited as Set<string>\n }\n\n const acc: PolicyAccumulator = { minMaxAge: undefined, hasPrivate: false }\n\n for (const selection of selectionSet.selections) {\n let fieldPolicy: CachePolicy | undefined\n\n switch (selection.kind) {\n case Kind.FIELD:\n fieldPolicy = analyzeField(\n selection,\n parentType,\n ctx,\n actualParentMaxAge,\n actualVisitedFragments\n )\n break\n\n case Kind.FRAGMENT_SPREAD:\n fieldPolicy = analyzeFragmentSpread(\n selection.name.value,\n ctx,\n actualParentMaxAge,\n actualVisitedFragments\n )\n break\n\n case Kind.INLINE_FRAGMENT:\n fieldPolicy = analyzeInlineFragment(\n selection,\n parentType,\n ctx,\n actualParentMaxAge,\n actualVisitedFragments\n )\n break\n }\n\n if (fieldPolicy) {\n aggregatePolicy(acc, fieldPolicy)\n }\n }\n\n return {\n maxAge: acc.minMaxAge ?? ctx.defaultMaxAge,\n scope: acc.hasPrivate ? \"PRIVATE\" : ctx.defaultScope,\n }\n}\n\n/**\n * Analyze a field node and return its cache policy\n */\nfunction analyzeField(\n field: FieldNode,\n parentType: GraphQLObjectType,\n ctx: AnalysisContext,\n parentMaxAge: number | undefined,\n visitedFragments: Set<string>\n): CachePolicy {\n const fieldName = field.name.value\n\n // Introspection fields - don't affect caching\n if (fieldName.startsWith(\"__\")) {\n return { maxAge: Infinity, scope: \"PUBLIC\" }\n }\n\n // Get the field from the schema\n const schemaField = parentType.getFields()[fieldName]\n if (!schemaField) {\n return { maxAge: ctx.defaultMaxAge, scope: ctx.defaultScope }\n }\n\n // Look up effective cache hint\n const effectiveHint = lookupEffectiveCacheHint(\n parentType.name,\n fieldName,\n schemaField.type,\n ctx.cacheHints\n )\n\n // Compute field maxAge\n const fieldMaxAge = computeFieldMaxAge(\n effectiveHint,\n schemaField.type,\n parentMaxAge,\n ctx.defaultMaxAge\n )\n const fieldScope: CacheControlScope = effectiveHint?.scope ?? ctx.defaultScope\n\n // If the field has a selection set, analyze it\n const namedType = getNamedType(schemaField.type)\n if (field.selectionSet && namedType instanceof GraphQLObjectType) {\n const nestedPolicy = analyzeSelectionSet(\n field.selectionSet,\n namedType,\n ctx,\n fieldMaxAge,\n visitedFragments\n )\n\n return {\n maxAge: Math.min(fieldMaxAge, nestedPolicy.maxAge),\n scope: fieldScope === \"PRIVATE\" || nestedPolicy.scope === \"PRIVATE\" ? \"PRIVATE\" : \"PUBLIC\",\n }\n }\n\n return { maxAge: fieldMaxAge, scope: fieldScope }\n}\n\n// ============================================================================\n// Environment Configuration\n// ============================================================================\n\n/**\n * Effect Config for loading cache control configuration from environment variables.\n *\n * Environment variables:\n * - GRAPHQL_CACHE_CONTROL_ENABLED: Enable cache control (default: true)\n * - GRAPHQL_CACHE_CONTROL_DEFAULT_MAX_AGE: Default maxAge for root fields (default: 0)\n * - GRAPHQL_CACHE_CONTROL_DEFAULT_SCOPE: Default scope (PUBLIC or PRIVATE, default: PUBLIC)\n * - GRAPHQL_CACHE_CONTROL_HTTP_HEADERS: Set HTTP headers (default: true)\n */\nexport const CacheControlConfigFromEnv: Config.Config<CacheControlConfig> = Config.all({\n enabled: Config.boolean(\"GRAPHQL_CACHE_CONTROL_ENABLED\").pipe(Config.withDefault(true)),\n defaultMaxAge: Config.number(\"GRAPHQL_CACHE_CONTROL_DEFAULT_MAX_AGE\").pipe(Config.withDefault(0)),\n defaultScope: Config.string(\"GRAPHQL_CACHE_CONTROL_DEFAULT_SCOPE\").pipe(\n Config.withDefault(\"PUBLIC\"),\n Config.map((s) => (s === \"PRIVATE\" ? \"PRIVATE\" : \"PUBLIC\") as CacheControlScope)\n ),\n calculateHttpHeaders: Config.boolean(\"GRAPHQL_CACHE_CONTROL_HTTP_HEADERS\").pipe(\n Config.withDefault(true)\n ),\n})\n","import { Context, Effect, Ref } from \"effect\"\nimport type { DocumentNode, ExecutionResult, GraphQLError, GraphQLSchema } from \"graphql\"\nimport type { FieldComplexityMap } from \"./server/complexity\"\n\n/**\n * Execution arguments passed to onExecuteStart hook\n */\nexport interface ExecutionArgs {\n readonly source: string\n readonly document: DocumentNode\n readonly variableValues?: Record<string, unknown>\n readonly operationName?: string\n /** The GraphQL schema being executed against */\n readonly schema: GraphQLSchema\n /** Field complexity definitions from the schema builder */\n readonly fieldComplexities: FieldComplexityMap\n}\n\n/**\n * Configuration for a GraphQL extension\n *\n * Extensions provide lifecycle hooks that run at each phase of request processing,\n * and can contribute data to the response's `extensions` field.\n *\n * @example\n * ```typescript\n * // Tracing extension\n * extension({\n * name: \"tracing\",\n * onExecuteStart: () => Effect.gen(function*() {\n * const ext = yield* ExtensionsService\n * yield* ext.set(\"tracing\", { startTime: Date.now() })\n * }),\n * onExecuteEnd: () => Effect.gen(function*() {\n * const ext = yield* ExtensionsService\n * yield* ext.merge(\"tracing\", { endTime: Date.now() })\n * }),\n * })\n * ```\n */\nexport interface GraphQLExtension<R = never> {\n readonly name: string\n readonly description?: string\n\n /**\n * Called after the query source is parsed into a DocumentNode.\n * Useful for query analysis, caching parsed documents, etc.\n */\n readonly onParse?: (source: string, document: DocumentNode) => Effect.Effect<void, never, R>\n\n /**\n * Called after validation completes.\n * Receives the document and any validation errors.\n * Useful for complexity analysis, query whitelisting, etc.\n */\n readonly onValidate?: (\n document: DocumentNode,\n errors: readonly GraphQLError[]\n ) => Effect.Effect<void, never, R>\n\n /**\n * Called before execution begins.\n * Receives the full execution arguments.\n * Useful for setting up tracing, logging, etc.\n */\n readonly onExecuteStart?: (args: ExecutionArgs) => Effect.Effect<void, never, R>\n\n /**\n * Called after execution completes.\n * Receives the execution result (including data and errors).\n * Useful for recording metrics, finalizing traces, etc.\n */\n readonly onExecuteEnd?: (result: ExecutionResult) => Effect.Effect<void, never, R>\n}\n\n/**\n * Service for accumulating extension data during request processing.\n *\n * This service is automatically provided for each request and allows\n * extensions, middleware, and resolvers to contribute to the response\n * extensions field.\n *\n * @example\n * ```typescript\n * Effect.gen(function*() {\n * const ext = yield* ExtensionsService\n *\n * // Set a value (overwrites existing)\n * yield* ext.set(\"complexity\", { score: 42 })\n *\n * // Merge into existing value\n * yield* ext.merge(\"tracing\", { endTime: Date.now() })\n *\n * // Get all accumulated extensions\n * const all = yield* ext.get()\n * })\n * ```\n */\nexport interface ExtensionsService {\n /**\n * Set a key-value pair in the extensions.\n * Overwrites any existing value for this key.\n */\n readonly set: (key: string, value: unknown) => Effect.Effect<void>\n\n /**\n * Deep merge an object into an existing key's value.\n * If the key doesn't exist, sets the value.\n * If the existing value is not an object, overwrites it.\n */\n readonly merge: (key: string, value: Record<string, unknown>) => Effect.Effect<void>\n\n /**\n * Get all accumulated extensions as a record.\n */\n readonly get: () => Effect.Effect<Record<string, unknown>>\n}\n\n/**\n * Tag for the ExtensionsService\n */\nexport const ExtensionsService = Context.GenericTag<ExtensionsService>(\n \"@effect-gql/ExtensionsService\"\n)\n\n/**\n * Deep merge two objects\n */\nfunction deepMerge(\n target: Record<string, unknown>,\n source: Record<string, unknown>\n): Record<string, unknown> {\n const result = { ...target }\n for (const key of Object.keys(source)) {\n const sourceValue = source[key]\n const targetValue = result[key]\n\n if (\n typeof sourceValue === \"object\" &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof targetValue === \"object\" &&\n targetValue !== null &&\n !Array.isArray(targetValue)\n ) {\n result[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n )\n } else {\n result[key] = sourceValue\n }\n }\n return result\n}\n\n/**\n * Create a new ExtensionsService backed by a Ref\n */\nexport const makeExtensionsService = (): Effect.Effect<ExtensionsService, never, never> =>\n Effect.gen(function* () {\n const ref = yield* Ref.make<Record<string, unknown>>({})\n\n return ExtensionsService.of({\n set: (key, value) => Ref.update(ref, (current) => ({ ...current, [key]: value })),\n\n merge: (key, value) =>\n Ref.update(ref, (current) => {\n const existing = current[key]\n if (typeof existing === \"object\" && existing !== null && !Array.isArray(existing)) {\n return {\n ...current,\n [key]: deepMerge(existing as Record<string, unknown>, value),\n }\n }\n return { ...current, [key]: value }\n }),\n\n get: () => Ref.get(ref),\n })\n })\n\n/**\n * Generic helper to run extension hooks with error handling.\n * Filters extensions that have the specified hook, runs them,\n * and logs warnings if any hook fails.\n */\nconst runExtensionHooks = <R, K extends keyof GraphQLExtension<R>>(\n extensions: readonly GraphQLExtension<R>[],\n hookName: K,\n getHookEffect: (ext: GraphQLExtension<R>) => Effect.Effect<void, never, R>\n): Effect.Effect<void, never, R> =>\n Effect.forEach(\n extensions.filter((ext) => ext[hookName] !== undefined),\n (ext) =>\n getHookEffect(ext).pipe(\n Effect.catchAllCause((cause) =>\n Effect.logWarning(`Extension \"${ext.name}\" ${String(hookName)} hook failed`, cause)\n )\n ),\n { discard: true }\n ) as Effect.Effect<void, never, R>\n\n/**\n * Run all onParse hooks for registered extensions\n */\nexport const runParseHooks = <R>(\n extensions: readonly GraphQLExtension<R>[],\n source: string,\n document: DocumentNode\n): Effect.Effect<void, never, R> =>\n runExtensionHooks(extensions, \"onParse\", (ext) => ext.onParse!(source, document))\n\n/**\n * Run all onValidate hooks for registered extensions\n */\nexport const runValidateHooks = <R>(\n extensions: readonly GraphQLExtension<R>[],\n document: DocumentNode,\n errors: readonly GraphQLError[]\n): Effect.Effect<void, never, R> =>\n runExtensionHooks(extensions, \"onValidate\", (ext) => ext.onValidate!(document, errors))\n\n/**\n * Run all onExecuteStart hooks for registered extensions\n */\nexport const runExecuteStartHooks = <R>(\n extensions: readonly GraphQLExtension<R>[],\n args: ExecutionArgs\n): Effect.Effect<void, never, R> =>\n runExtensionHooks(extensions, \"onExecuteStart\", (ext) => ext.onExecuteStart!(args))\n\n/**\n * Run all onExecuteEnd hooks for registered extensions\n */\nexport const runExecuteEndHooks = <R>(\n extensions: readonly GraphQLExtension<R>[],\n result: ExecutionResult\n): Effect.Effect<void, never, R> =>\n runExtensionHooks(extensions, \"onExecuteEnd\", (ext) => ext.onExecuteEnd!(result))\n","import {\n HttpRouter,\n HttpServerRequest,\n HttpServerResponse,\n HttpIncomingMessage,\n HttpServerError,\n HttpBody,\n} from \"@effect/platform\"\nimport { Cause, Context, Effect, Layer, ParseResult, Schema } from \"effect\"\nimport {\n GraphQLSchema,\n parse,\n validate,\n specifiedRules,\n NoSchemaIntrospectionCustomRule,\n execute as graphqlExecute,\n Kind,\n type DocumentNode,\n type OperationDefinitionNode,\n} from \"graphql\"\nimport type { GraphQLEffectContext } from \"../builder/types\"\nimport { graphiqlHtml } from \"./graphiql\"\nimport { normalizeConfig, type GraphQLRouterConfigInput } from \"./config\"\nimport {\n validateComplexity,\n ComplexityLimitExceededError,\n type FieldComplexityMap,\n} from \"./complexity\"\nimport { computeCachePolicy, toCacheControlHeader, type CacheHintMap } from \"./cache-control\"\nimport {\n type GraphQLExtension,\n ExtensionsService,\n makeExtensionsService,\n runParseHooks,\n runValidateHooks,\n runExecuteStartHooks,\n runExecuteEndHooks,\n} from \"../extensions\"\n\n/**\n * Error handler function type for handling uncaught errors during GraphQL execution.\n * Receives the error cause and should return an HTTP response.\n */\nexport type ErrorHandler = (\n cause: Cause.Cause<unknown>\n) => Effect.Effect<HttpServerResponse.HttpServerResponse, never, never>\n\n/**\n * Default error handler that returns a 500 Internal Server Error.\n * In non-production environments, it logs the full error for debugging.\n */\nexport const defaultErrorHandler: ErrorHandler = (cause) =>\n (process.env.NODE_ENV !== \"production\"\n ? Effect.logError(\"GraphQL error\", cause)\n : Effect.void\n ).pipe(\n Effect.andThen(\n HttpServerResponse.json(\n {\n errors: [\n {\n message: \"An error occurred processing your request\",\n },\n ],\n },\n { status: 500 }\n ).pipe(Effect.orDie)\n )\n )\n\n/**\n * Schema for GraphQL request body.\n */\nconst GraphQLRequestBodySchema = Schema.Struct({\n query: Schema.String,\n variables: Schema.optionalWith(Schema.Record({ key: Schema.String, value: Schema.Unknown }), {\n as: \"Option\",\n }),\n operationName: Schema.optionalWith(Schema.String, { as: \"Option\" }),\n})\n\n/**\n * Request body for GraphQL queries.\n */\ninterface GraphQLRequestBody {\n readonly query: string\n readonly variables?: Record<string, unknown>\n readonly operationName?: string\n}\n\n/**\n * Decode the request body from JSON using the schema.\n */\nconst decodeRequestBody = HttpIncomingMessage.schemaBodyJson(GraphQLRequestBodySchema)\n\n/**\n * Union of all possible errors that can occur during GraphQL request handling.\n */\ntype GraphQLHandlerError =\n | HttpServerError.RequestError\n | HttpBody.HttpBodyError\n | ParseResult.ParseError\n | ComplexityLimitExceededError\n | Error\n\n/**\n * Result type for parseGraphQLQuery\n */\ntype ParseGraphQLQueryResult =\n | { ok: true; document: DocumentNode }\n | { ok: false; response: HttpServerResponse.HttpServerResponse }\n\n/**\n * Parse a GraphQL query string into a DocumentNode.\n * Returns the document or an error response if parsing fails.\n */\nconst parseGraphQLQuery = (\n query: string,\n extensionsService: Context.Tag.Service<typeof ExtensionsService>\n): Effect.Effect<ParseGraphQLQueryResult, never, never> => {\n try {\n const document = parse(query)\n return Effect.succeed({ ok: true as const, document })\n } catch (parseError) {\n return extensionsService.get().pipe(\n Effect.flatMap(\n (extensionData): Effect.Effect<ParseGraphQLQueryResult, never, never> =>\n HttpServerResponse.json({\n errors: [{ message: String(parseError) }],\n extensions: Object.keys(extensionData).length > 0 ? extensionData : undefined,\n }).pipe(\n Effect.orDie,\n Effect.map((response) => ({ ok: false as const, response }))\n )\n )\n )\n }\n}\n\n/**\n * Run complexity validation if configured.\n * Logs warnings for analysis errors but doesn't block execution.\n */\nconst runComplexityValidation = (\n body: GraphQLRequestBody,\n schema: GraphQLSchema,\n fieldComplexities: FieldComplexityMap,\n complexityConfig: { maxDepth?: number; maxComplexity?: number } | undefined\n): Effect.Effect<void, ComplexityLimitExceededError, never> => {\n if (!complexityConfig) {\n return Effect.void\n }\n\n return validateComplexity(\n body.query,\n body.operationName,\n body.variables,\n schema,\n fieldComplexities,\n complexityConfig\n ).pipe(\n Effect.catchTag(\"ComplexityLimitExceededError\", (error) => Effect.fail(error)),\n Effect.catchTag(\"ComplexityAnalysisError\", (error) =>\n Effect.logWarning(\"Complexity analysis failed\", error)\n )\n )\n}\n\n/**\n * Type guard to check if a value is a Promise-like object.\n */\nconst isPromiseLike = <T>(value: unknown): value is PromiseLike<T> =>\n value !== null && typeof value === \"object\" && \"then\" in value && typeof value.then === \"function\"\n\n/**\n * Execute a GraphQL query and handle async results.\n */\nconst executeGraphQLQuery = <R>(\n schema: GraphQLSchema,\n document: DocumentNode,\n variables: Record<string, unknown> | undefined,\n operationName: string | undefined,\n runtime: import(\"effect\").Runtime.Runtime<R>\n): Effect.Effect<import(\"graphql\").ExecutionResult, Error, never> => {\n type ExecutionResult = import(\"graphql\").ExecutionResult\n\n const tryExecute = Effect.try({\n try: () =>\n graphqlExecute({\n schema,\n document,\n variableValues: variables,\n operationName,\n contextValue: { runtime } satisfies GraphQLEffectContext<R>,\n }),\n catch: (error) => new Error(String(error)),\n })\n\n return tryExecute.pipe(\n Effect.flatMap((executeResult): Effect.Effect<ExecutionResult, never, never> => {\n if (isPromiseLike<ExecutionResult>(executeResult)) {\n return Effect.promise(() => executeResult)\n }\n return Effect.succeed(executeResult)\n })\n )\n}\n\n/**\n * Compute cache control header for the response if applicable.\n */\nconst computeCacheControlHeader = (\n document: DocumentNode,\n operationName: string | undefined,\n schema: GraphQLSchema,\n cacheHints: CacheHintMap,\n cacheControlConfig:\n | { enabled?: boolean; calculateHttpHeaders?: boolean; defaultMaxAge?: number }\n | undefined\n): Effect.Effect<string | undefined, never, never> => {\n if (cacheControlConfig?.enabled === false || cacheControlConfig?.calculateHttpHeaders === false) {\n return Effect.succeed(undefined)\n }\n\n // Find the operation from the document\n const operations = document.definitions.filter(\n (d): d is OperationDefinitionNode => d.kind === Kind.OPERATION_DEFINITION\n )\n const operation = operationName\n ? operations.find((o) => o.name?.value === operationName)\n : operations[0]\n\n if (!operation || operation.operation === \"mutation\") {\n // Mutations should not be cached\n return Effect.succeed(undefined)\n }\n\n return computeCachePolicy({\n document,\n operation,\n schema,\n cacheHints,\n config: cacheControlConfig ?? {},\n }).pipe(Effect.map(toCacheControlHeader))\n}\n\n/**\n * Build the final GraphQL response with extensions merged in.\n */\nconst buildGraphQLResponse = (\n result: import(\"graphql\").ExecutionResult,\n extensionData: Record<string, unknown>,\n cacheControlHeader: string | undefined\n): Effect.Effect<HttpServerResponse.HttpServerResponse, never, never> => {\n const finalResult =\n Object.keys(extensionData).length > 0\n ? {\n ...result,\n extensions: {\n ...result.extensions,\n ...extensionData,\n },\n }\n : result\n\n const responseHeaders = cacheControlHeader ? { \"cache-control\": cacheControlHeader } : undefined\n\n return HttpServerResponse.json(finalResult, { headers: responseHeaders }).pipe(Effect.orDie)\n}\n\n/**\n * Handle complexity limit exceeded error, returning appropriate response.\n */\nconst handleComplexityError = (\n error: ComplexityLimitExceededError\n): Effect.Effect<HttpServerResponse.HttpServerResponse, never, never> =>\n HttpServerResponse.json(\n {\n errors: [\n {\n message: error.message,\n extensions: {\n code: \"COMPLEXITY_LIMIT_EXCEEDED\",\n limitType: error.limitType,\n limit: error.limit,\n actual: error.actual,\n },\n },\n ],\n },\n { status: 400 }\n ).pipe(Effect.orDie)\n\n/**\n * Options for makeGraphQLRouter\n */\nexport interface MakeGraphQLRouterOptions extends GraphQLRouterConfigInput {\n /**\n * Field complexity definitions from the schema builder.\n * If using toRouter(), this is automatically extracted from the builder.\n * If using makeGraphQLRouter() directly, call builder.getFieldComplexities().\n */\n readonly fieldComplexities?: FieldComplexityMap\n\n /**\n * Cache hint definitions from the schema builder.\n * If using toRouter(), this is automatically extracted from the builder.\n * If using makeGraphQLRouter() directly, call builder.getCacheHints().\n */\n readonly cacheHints?: CacheHintMap\n\n /**\n * GraphQL extensions for lifecycle hooks.\n * If using toRouter(), this is automatically extracted from the builder.\n * If using makeGraphQLRouter() directly, call builder.getExtensions().\n */\n readonly extensions?: readonly GraphQLExtension<any>[]\n\n /**\n * Custom error handler for uncaught errors during GraphQL execution.\n * Receives the error cause and should return an HTTP response.\n * Defaults to returning a 500 Internal Server Error with a generic message.\n */\n readonly errorHandler?: ErrorHandler\n}\n\n/**\n * Create an HttpRouter configured for GraphQL\n *\n * The router handles:\n * - POST requests to the GraphQL endpoint\n * - GET requests to the GraphiQL UI (if enabled)\n * - Query complexity validation (if configured)\n * - Extension lifecycle hooks (onParse, onValidate, onExecuteStart, onExecuteEnd)\n *\n * @param schema - The GraphQL schema\n * @param layer - Effect layer providing services required by resolvers\n * @param options - Optional configuration for paths, GraphiQL, complexity, and extensions\n * @returns An HttpRouter that can be composed with other routes\n *\n * @example\n * ```typescript\n * const router = makeGraphQLRouter(schema, Layer.empty, {\n * path: \"/graphql\",\n * graphiql: { path: \"/graphiql\" },\n * complexity: { maxDepth: 10, maxComplexity: 1000 },\n * fieldComplexities: builder.getFieldComplexities(),\n * extensions: builder.getExtensions()\n * })\n *\n * // Compose with other routes\n * const app = HttpRouter.empty.pipe(\n * HttpRouter.get(\"/health\", HttpServerResponse.json({ status: \"ok\" })),\n * HttpRouter.concat(router)\n * )\n * ```\n */\nexport const makeGraphQLRouter = <R>(\n schema: GraphQLSchema,\n layer: Layer.Layer<R>,\n options: MakeGraphQLRouterOptions = {}\n): HttpRouter.HttpRouter<never, never> => {\n const resolvedConfig = normalizeConfig(options)\n const fieldComplexities = options.fieldComplexities ?? new Map()\n const cacheHints = options.cacheHints ?? new Map()\n const extensions = options.extensions ?? []\n const errorHandler = options.errorHandler ?? defaultErrorHandler\n\n // GraphQL POST handler - typed as returning HttpServerResponse with all errors handled\n const graphqlHandler = Effect.gen(function* () {\n const extensionsService = yield* makeExtensionsService()\n const runtime = yield* Effect.runtime<R>()\n\n // Parse request body\n const request = yield* HttpServerRequest.HttpServerRequest\n const parsedBody = yield* decodeRequestBody(request)\n const body: GraphQLRequestBody = {\n query: parsedBody.query,\n variables: parsedBody.variables._tag === \"Some\" ? parsedBody.variables.value : undefined,\n operationName:\n parsedBody.operationName._tag === \"Some\" ? parsedBody.operationName.value : undefined,\n }\n\n // Phase 1: Parse\n const parseResult = yield* parseGraphQLQuery(body.query, extensionsService)\n if (!parseResult.ok) {\n return parseResult.response\n }\n const document = parseResult.document\n\n yield* runParseHooks(extensions, body.query, document).pipe(\n Effect.provideService(ExtensionsService, extensionsService)\n )\n\n // Phase 2: Validate\n const validationRules = resolvedConfig.introspection\n ? undefined\n : specifiedRules.concat(NoSchemaIntrospectionCustomRule)\n const validationErrors = validate(schema, document, validationRules)\n\n yield* runValidateHooks(extensions, document, validationErrors).pipe(\n Effect.provideService(ExtensionsService, extensionsService)\n )\n\n if (validationErrors.length > 0) {\n const extensionData = yield* extensionsService.get()\n return yield* HttpServerResponse.json(\n {\n errors: validationErrors.map((e) => ({\n message: e.message,\n locations: e.locations,\n path: e.path,\n })),\n extensions: Object.keys(extensionData).length > 0 ? extensionData : undefined,\n },\n { status: 400 }\n )\n }\n\n // Complexity validation\n yield* runComplexityValidation(body, schema, fieldComplexities, resolvedConfig.complexity)\n\n // Phase 3: Execute\n yield* runExecuteStartHooks(extensions, {\n source: body.query,\n document,\n variableValues: body.variables,\n operationName: body.operationName,\n schema,\n fieldComplexities,\n }).pipe(Effect.provideService(ExtensionsService, extensionsService))\n\n const result = yield* executeGraphQLQuery(\n schema,\n document,\n body.variables,\n body.operationName,\n runtime\n )\n\n yield* runExecuteEndHooks(extensions, result).pipe(\n Effect.provideService(ExtensionsService, extensionsService)\n )\n\n // Build response\n const extensionData = yield* extensionsService.get()\n const cacheControlHeader = yield* computeCacheControlHeader(\n document,\n body.operationName,\n schema,\n cacheHints,\n resolvedConfig.cacheControl\n )\n\n return yield* buildGraphQLResponse(result, extensionData, cacheControlHeader)\n }).pipe(\n Effect.provide(layer),\n Effect.catchAll((error: GraphQLHandlerError) => {\n if (error instanceof ComplexityLimitExceededError) {\n return handleComplexityError(error)\n }\n return Effect.fail(error)\n }),\n Effect.catchAllCause(errorHandler)\n )\n\n // Build router\n let router = HttpRouter.empty.pipe(\n HttpRouter.post(resolvedConfig.path as HttpRouter.PathInput, graphqlHandler)\n )\n\n if (resolvedConfig.graphiql) {\n const { path, endpoint, subscriptionEndpoint } = resolvedConfig.graphiql\n router = router.pipe(\n HttpRouter.get(\n path as HttpRouter.PathInput,\n HttpServerResponse.html(graphiqlHtml(endpoint, subscriptionEndpoint))\n )\n )\n }\n\n return router\n}\n","import { Layer } from \"effect\"\nimport { HttpRouter } from \"@effect/platform\"\nimport { GraphQLSchemaBuilder } from \"../builder/schema-builder\"\nimport { makeGraphQLRouter, type MakeGraphQLRouterOptions } from \"./router\"\n\n/**\n * Convert a GraphQLSchemaBuilder to an HttpRouter.\n *\n * This bridges the GraphQL schema builder with the @effect/platform HTTP server.\n * Field complexities and cache hints are automatically extracted from the builder.\n *\n * @param builder - The GraphQL schema builder\n * @param layer - Effect layer providing services required by resolvers\n * @param options - Optional configuration for paths, GraphiQL, complexity, and caching\n * @returns An HttpRouter that can be composed with other routes\n *\n * @example\n * ```typescript\n * import { GraphQLSchemaBuilder, query, toRouter } from \"@effect-gql/core\"\n * import { Layer, Effect } from \"effect\"\n * import * as S from \"effect/Schema\"\n *\n * const builder = GraphQLSchemaBuilder.empty.pipe(\n * query(\"hello\", { type: S.String, resolve: () => Effect.succeed(\"world\") })\n * )\n *\n * // Basic usage\n * const router = toRouter(builder, Layer.empty, { graphiql: true })\n *\n * // With complexity limiting\n * const routerWithLimits = toRouter(builder, Layer.empty, {\n * graphiql: true,\n * complexity: { maxDepth: 10, maxComplexity: 1000 }\n * })\n *\n * // With cache control\n * const routerWithCaching = toRouter(builder, Layer.empty, {\n * cacheControl: { enabled: true, defaultMaxAge: 0 }\n * })\n * ```\n */\nexport const toRouter = <R, R2>(\n builder: GraphQLSchemaBuilder<R>,\n layer: Layer.Layer<R2>,\n options?: Omit<MakeGraphQLRouterOptions, \"fieldComplexities\" | \"cacheHints\">\n): HttpRouter.HttpRouter<never, never> => {\n const schema = builder.buildSchema()\n const fieldComplexities = builder.getFieldComplexities()\n const cacheHints = builder.getCacheHints()\n return makeGraphQLRouter(schema, layer, { ...options, fieldComplexities, cacheHints })\n}\n","import { Data, Effect, Runtime, Stream } from \"effect\"\nimport type { ComplexityConfig, FieldComplexityMap } from \"./complexity\"\n\n/**\n * Error type for WebSocket operations\n */\nexport class WebSocketError extends Data.TaggedError(\"WebSocketError\")<{\n readonly cause: unknown\n}> {}\n\n/**\n * WebSocket close event information\n */\nexport interface CloseEvent {\n readonly code: number\n readonly reason: string\n}\n\n/**\n * Platform-neutral WebSocket interface using Effect types.\n *\n * This interface abstracts WebSocket operations across different platforms\n * (Node.js ws, Bun built-in, browser WebSocket). Platform packages implement\n * this interface to bridge their specific WebSocket implementations.\n */\nexport interface EffectWebSocket {\n /**\n * Send a message to the client.\n * Returns an Effect that completes when the message is sent.\n */\n readonly send: (data: string) => Effect.Effect<void, WebSocketError>\n\n /**\n * Close the WebSocket connection.\n * @param code - Optional close code (default: 1000)\n * @param reason - Optional close reason\n */\n readonly close: (code?: number, reason?: string) => Effect.Effect<void, WebSocketError>\n\n /**\n * Stream of incoming messages from the client.\n * The stream completes when the connection closes.\n */\n readonly messages: Stream.Stream<string, WebSocketError>\n\n /**\n * Effect that completes with CloseEvent when the connection closes.\n * Use this to detect client disconnection.\n */\n readonly closed: Effect.Effect<CloseEvent, WebSocketError>\n\n /**\n * The WebSocket subprotocol negotiated during handshake.\n * For GraphQL subscriptions, this should be \"graphql-transport-ws\".\n */\n readonly protocol: string\n}\n\n/**\n * Context available during a WebSocket connection.\n * This is passed to lifecycle hooks.\n */\nexport interface ConnectionContext<R> {\n /**\n * The Effect runtime for this connection.\n * Use this to run Effects within the connection scope.\n */\n readonly runtime: Runtime.Runtime<R>\n\n /**\n * Connection parameters sent by the client during CONNECTION_INIT.\n * Often used for authentication tokens.\n */\n readonly connectionParams: Record<string, unknown>\n\n /**\n * The underlying WebSocket for this connection.\n */\n readonly socket: EffectWebSocket\n}\n\n/**\n * Options for configuring the GraphQL WebSocket handler.\n *\n * @template R - Service requirements for lifecycle hooks\n */\nexport interface GraphQLWSOptions<R> {\n /**\n * Query complexity limiting configuration.\n * When provided, subscriptions are validated against complexity limits\n * before execution begins.\n */\n readonly complexity?: ComplexityConfig\n\n /**\n * Field complexity definitions from the schema builder.\n * If using the platform serve() functions with subscriptions config,\n * this is typically passed automatically.\n */\n readonly fieldComplexities?: FieldComplexityMap\n\n /**\n * Called when a client initiates a connection (CONNECTION_INIT message).\n *\n * Use this for authentication. Return:\n * - `true` to accept the connection\n * - `false` to reject the connection\n * - An object to accept and provide additional context\n *\n * The returned object (or true) is merged into the GraphQL context.\n *\n * @example\n * ```typescript\n * onConnect: (params) => Effect.gen(function* () {\n * const token = params.authToken as string\n * const user = yield* AuthService.validateToken(token)\n * return { user } // Available in GraphQL context\n * })\n * ```\n */\n readonly onConnect?: (\n params: Record<string, unknown>\n ) => Effect.Effect<boolean | Record<string, unknown>, unknown, R>\n\n /**\n * Called when a client disconnects.\n * Use this for cleanup (e.g., removing user from active connections).\n */\n readonly onDisconnect?: (ctx: ConnectionContext<R>) => Effect.Effect<void, never, R>\n\n /**\n * Called when a client starts a subscription (SUBSCRIBE message).\n * Use this for per-subscription authorization or logging.\n *\n * Note: If complexity validation is enabled, it runs before this hook.\n * Throw an error to reject the subscription.\n */\n readonly onSubscribe?: (\n ctx: ConnectionContext<R>,\n message: SubscribeMessage\n ) => Effect.Effect<void, unknown, R>\n\n /**\n * Called when a subscription completes or is stopped.\n */\n readonly onComplete?: (\n ctx: ConnectionContext<R>,\n message: CompleteMessage\n ) => Effect.Effect<void, never, R>\n\n /**\n * Called when an error occurs during subscription execution.\n */\n readonly onError?: (ctx: ConnectionContext<R>, error: unknown) => Effect.Effect<void, never, R>\n}\n\n/**\n * GraphQL WebSocket SUBSCRIBE message payload\n */\nexport interface SubscribeMessage {\n readonly id: string\n readonly payload: {\n readonly query: string\n readonly variables?: Record<string, unknown>\n readonly operationName?: string\n readonly extensions?: Record<string, unknown>\n }\n}\n\n/**\n * GraphQL WebSocket COMPLETE message payload\n */\nexport interface CompleteMessage {\n readonly id: string\n}\n\n/**\n * Configuration for the WebSocket endpoint\n */\nexport interface GraphQLWSConfig {\n /**\n * Path for WebSocket connections.\n * @default \"/graphql\"\n */\n readonly path?: string\n\n /**\n * How long to wait for CONNECTION_INIT message before closing.\n * @default 5000 (5 seconds)\n */\n readonly connectionInitWaitTimeout?: number\n}\n","import { Effect, Layer, Runtime, Stream, Queue, Fiber, Deferred } from \"effect\"\nimport { GraphQLSchema, subscribe, GraphQLError } from \"graphql\"\nimport type { ServerOptions } from \"graphql-ws\"\nimport type { GraphQLEffectContext } from \"../builder/types\"\nimport type {\n EffectWebSocket,\n GraphQLWSOptions,\n ConnectionContext,\n CloseEvent,\n WebSocketError,\n} from \"./ws-types\"\nimport { validateComplexity, type FieldComplexityMap } from \"./complexity\"\n\n/**\n * Extra context passed through graphql-ws.\n * This is the `extra` field in graphql-ws Context.\n */\ninterface WSExtra<R> {\n socket: EffectWebSocket\n runtime: Runtime.Runtime<R>\n connectionParams: Record<string, unknown>\n}\n\n/**\n * Create a ConnectionContext from WSExtra for use in lifecycle hooks.\n */\nconst createConnectionContext = <R>(extra: WSExtra<R>): ConnectionContext<R> => ({\n runtime: extra.runtime,\n connectionParams: extra.connectionParams,\n socket: extra.socket,\n})\n\n/**\n * Create the onConnect handler for graphql-ws.\n */\nconst makeOnConnectHandler = <R>(\n options: GraphQLWSOptions<R> | undefined\n): ServerOptions<Record<string, unknown>, WSExtra<R>>[\"onConnect\"] => {\n if (!options?.onConnect) return undefined\n\n return async (ctx) => {\n const extra = ctx.extra as WSExtra<R>\n try {\n const result = await Runtime.runPromise(extra.runtime)(\n options.onConnect!(ctx.connectionParams ?? {})\n )\n if (typeof result === \"object\" && result !== null) {\n Object.assign(extra.connectionParams, result)\n }\n return result !== false\n } catch {\n return false\n }\n }\n}\n\n/**\n * Create the onDisconnect handler for graphql-ws.\n */\nconst makeOnDisconnectHandler = <R>(\n options: GraphQLWSOptions<R> | undefined\n): ServerOptions<Record<string, unknown>, WSExtra<R>>[\"onDisconnect\"] => {\n if (!options?.onDisconnect) return undefined\n\n return async (ctx) => {\n const extra = ctx.extra as WSExtra<R>\n await Runtime.runPromise(extra.runtime)(\n options.onDisconnect!(createConnectionContext(extra))\n ).catch(() => {\n // Ignore cleanup errors\n })\n }\n}\n\n/**\n * Create the onSubscribe handler for graphql-ws with complexity validation.\n */\nconst makeOnSubscribeHandler = <R>(\n options: GraphQLWSOptions<R> | undefined,\n schema: GraphQLSchema,\n complexityConfig: GraphQLWSOptions<R>[\"complexity\"],\n fieldComplexities: FieldComplexityMap\n): ServerOptions<Record<string, unknown>, WSExtra<R>>[\"onSubscribe\"] => {\n // graphql-ws 6.0: signature changed from (ctx, msg) to (ctx, id, payload)\n return async (ctx, id, payload) => {\n const extra = ctx.extra as WSExtra<R>\n const connectionCtx = createConnectionContext(extra)\n\n // Validate complexity if configured\n if (complexityConfig) {\n const validationEffect = validateComplexity(\n payload.query,\n payload.operationName ?? undefined,\n payload.variables ?? undefined,\n schema,\n fieldComplexities,\n complexityConfig\n ).pipe(\n Effect.catchAll((error) => {\n if (error._tag === \"ComplexityLimitExceededError\") {\n throw new GraphQLError(error.message, {\n extensions: {\n code: \"COMPLEXITY_LIMIT_EXCEEDED\",\n limitType: error.limitType,\n limit: error.limit,\n actual: error.actual,\n },\n })\n }\n return Effect.logWarning(\"Complexity analysis failed for subscription\", error)\n })\n )\n\n await Effect.runPromise(validationEffect)\n }\n\n // Call user's onSubscribe hook if provided\n if (options?.onSubscribe) {\n await Runtime.runPromise(extra.runtime)(\n options.onSubscribe(connectionCtx, {\n id,\n payload: {\n query: payload.query,\n variables: payload.variables ?? undefined,\n operationName: payload.operationName ?? undefined,\n extensions: payload.extensions ?? undefined,\n },\n })\n )\n }\n }\n}\n\n/**\n * Create the onComplete handler for graphql-ws.\n */\nconst makeOnCompleteHandler = <R>(\n options: GraphQLWSOptions<R> | undefined\n): ServerOptions<Record<string, unknown>, WSExtra<R>>[\"onComplete\"] => {\n if (!options?.onComplete) return undefined\n\n // graphql-ws 6.0: signature changed from (ctx, msg) to (ctx, id, payload)\n return async (ctx, id, _payload) => {\n const extra = ctx.extra as WSExtra<R>\n await Runtime.runPromise(extra.runtime)(\n options.onComplete!(createConnectionContext(extra), { id })\n ).catch(() => {\n // Ignore cleanup errors\n })\n }\n}\n\n/**\n * Create the onError handler for graphql-ws.\n */\nconst makeOnErrorHandler = <R>(\n options: GraphQLWSOptions<R> | undefined\n): ServerOptions<Record<string, unknown>, WSExtra<R>>[\"onError\"] => {\n if (!options?.onError) return undefined\n\n // graphql-ws 6.0: signature changed from (ctx, msg, errors) to (ctx, id, payload, errors)\n return async (ctx, _id, _payload, errors) => {\n const extra = ctx.extra as WSExtra<R>\n await Runtime.runPromise(extra.runtime)(\n options.onError!(createConnectionContext(extra), errors)\n ).catch(() => {\n // Ignore error handler errors\n })\n }\n}\n\n/**\n * Create a graphql-ws compatible socket adapter from an EffectWebSocket.\n */\nconst createGraphqlWsSocketAdapter = <R>(socket: EffectWebSocket, runtime: Runtime.Runtime<R>) => {\n let messageCallback: ((message: string) => Promise<void>) | null = null\n\n return {\n adapter: {\n protocol: socket.protocol,\n\n send: (data: string) =>\n Runtime.runPromise(runtime)(\n socket\n .send(data)\n .pipe(Effect.catchAll((error) => Effect.logError(\"WebSocket send error\", error)))\n ),\n\n close: (code?: number, reason?: string) => {\n Runtime.runPromise(runtime)(socket.close(code, reason)).catch(() => {\n // Ignore close errors\n })\n },\n\n onMessage: (cb: (message: string) => Promise<void>) => {\n messageCallback = cb\n },\n\n onPong: (_payload: Record<string, unknown> | undefined) => {\n // Pong handling - can be used for keepalive\n },\n },\n dispatchMessage: async (message: string) => {\n if (messageCallback) {\n await messageCallback(message)\n }\n },\n }\n}\n\n/**\n * Type alias for the graphql-ws server instance.\n */\ntype GraphQLWSServer<R> = ReturnType<\n typeof import(\"graphql-ws\").makeServer<Record<string, unknown>, WSExtra<R>>\n>\n\n/**\n * Run the connection lifecycle - manages message queue, fibers, and cleanup.\n */\nconst runConnectionLifecycle = <R>(\n socket: EffectWebSocket,\n wsServer: GraphQLWSServer<R>,\n extra: WSExtra<R>\n): Effect.Effect<void, never, never> =>\n Effect.gen(function* () {\n // Create message queue for bridging Stream to callback\n const messageQueue = yield* Queue.unbounded<string>()\n const closedDeferred = yield* Deferred.make<CloseEvent, WebSocketError>()\n\n // Fork fiber to consume socket messages and push to queue\n const messageFiber = yield* Effect.fork(\n Stream.runForEach(socket.messages, (msg) => Queue.offer(messageQueue, msg)).pipe(\n Effect.catchAll((error) => Deferred.fail(closedDeferred, error))\n )\n )\n\n // Fork fiber to handle socket close\n const closeFiber = yield* Effect.fork(\n socket.closed.pipe(\n Effect.tap((event) => Deferred.succeed(closedDeferred, event)),\n Effect.catchAll((error) => Deferred.fail(closedDeferred, error))\n )\n )\n\n // Create the graphql-ws socket adapter\n const { adapter, dispatchMessage } = createGraphqlWsSocketAdapter(socket, extra.runtime)\n\n // Open the connection with graphql-ws\n const closedHandler = wsServer.opened(adapter, extra)\n\n // Fork fiber to process messages from queue\n const processMessagesFiber = yield* Effect.fork(\n Effect.gen(function* () {\n while (true) {\n const message = yield* Queue.take(messageQueue)\n yield* Effect.tryPromise({\n try: () => dispatchMessage(message),\n catch: (error) => error,\n }).pipe(Effect.catchAll(() => Effect.void))\n }\n })\n )\n\n // Wait for connection to close\n yield* Deferred.await(closedDeferred).pipe(\n Effect.catchAll(() => Effect.succeed({ code: 1000, reason: \"Error\" }))\n )\n\n // Cleanup\n closedHandler(1000, \"Connection closed\")\n yield* Fiber.interrupt(messageFiber)\n yield* Fiber.interrupt(closeFiber)\n yield* Fiber.interrupt(processMessagesFiber)\n yield* Queue.shutdown(messageQueue)\n }).pipe(\n Effect.catchAllCause(() => Effect.void),\n Effect.scoped\n )\n\n/**\n * Dynamically import graphql-ws to avoid requiring it at module load time.\n * This allows @effect-gql/core to be used without graphql-ws installed\n * as long as WebSocket functionality isn't used.\n */\nconst importGraphqlWs = Effect.tryPromise({\n try: () => import(\"graphql-ws\"),\n catch: () =>\n new Error(\n \"graphql-ws is required for WebSocket subscriptions. Install it with: npm install graphql-ws\"\n ),\n})\n\n/**\n * Create a WebSocket handler for GraphQL subscriptions using the graphql-ws protocol.\n *\n * This function creates a handler that can be used with any WebSocket implementation\n * that conforms to the EffectWebSocket interface. Platform packages (node, bun, express)\n * provide adapters that convert their native WebSocket to EffectWebSocket.\n *\n * The handler:\n * - Uses the graphql-ws protocol for client communication\n * - Creates an Effect runtime from the provided layer for each connection\n * - Executes subscriptions using GraphQL's subscribe() function\n * - Properly cleans up resources when connections close\n *\n * @param schema - The GraphQL schema with subscription definitions\n * @param layer - Effect layer providing services required by resolvers\n * @param options - Optional lifecycle hooks for connection/subscription events\n * @returns A function that handles individual WebSocket connections\n *\n * @example\n * ```typescript\n * import { makeGraphQLWSHandler } from \"@effect-gql/core\"\n *\n * const handler = makeGraphQLWSHandler(schema, serviceLayer, {\n * onConnect: (params) => Effect.gen(function* () {\n * const user = yield* AuthService.validateToken(params.authToken)\n * return { user }\n * }),\n * })\n *\n * // In platform-specific code:\n * const effectSocket = toEffectWebSocket(rawWebSocket)\n * await Effect.runPromise(handler(effectSocket))\n * ```\n */\nexport const makeGraphQLWSHandler = <R>(\n schema: GraphQLSchema,\n layer: Layer.Layer<R>,\n options?: GraphQLWSOptions<R>\n): ((socket: EffectWebSocket) => Effect.Effect<void, never, never>) => {\n const complexityConfig = options?.complexity\n const fieldComplexities: FieldComplexityMap = options?.fieldComplexities ?? new Map()\n\n // Lazily create the server on first connection\n let wsServerPromise: Promise<GraphQLWSServer<R>> | null = null\n\n const getOrCreateServer = async () => {\n if (!wsServerPromise) {\n wsServerPromise = Effect.runPromise(importGraphqlWs).then(({ makeServer }) => {\n // Build server options using extracted handler factories\n const serverOptions: ServerOptions<Record<string, unknown>, WSExtra<R>> = {\n schema,\n\n context: async (ctx): Promise<GraphQLEffectContext<R> & Record<string, unknown>> => {\n const extra = ctx.extra as WSExtra<R>\n return {\n runtime: extra.runtime,\n ...extra.connectionParams,\n }\n },\n\n subscribe: async (args) => subscribe(args),\n\n onConnect: makeOnConnectHandler(options),\n onDisconnect: makeOnDisconnectHandler(options),\n onSubscribe: makeOnSubscribeHandler(options, schema, complexityConfig, fieldComplexities),\n onComplete: makeOnCompleteHandler(options),\n onError: makeOnErrorHandler(options),\n }\n\n return makeServer(serverOptions)\n })\n }\n return wsServerPromise\n }\n\n // Return the connection handler\n return (socket: EffectWebSocket): Effect.Effect<void, never, never> =>\n Effect.gen(function* () {\n const wsServer = yield* Effect.tryPromise({\n try: () => getOrCreateServer(),\n catch: (error) => error as Error,\n })\n\n const runtime = yield* Effect.provide(Effect.runtime<R>(), layer)\n\n const extra: WSExtra<R> = {\n socket,\n runtime,\n connectionParams: {},\n }\n\n yield* runConnectionLifecycle(socket, wsServer, extra)\n }).pipe(\n Effect.catchAllCause(() => Effect.void),\n Effect.scoped\n )\n}\n","import { Effect, Stream, Queue, Deferred } from \"effect\"\nimport type { EffectWebSocket, CloseEvent } from \"./ws-types\"\nimport { WebSocketError } from \"./ws-types\"\n\n/**\n * Interface for the 'ws' library WebSocket.\n * This allows type-safe usage without requiring core to depend on 'ws'.\n */\nexport interface WsWebSocket {\n readonly protocol: string\n readonly readyState: number\n send(data: string, callback?: (error?: Error) => void): void\n close(code?: number, reason?: string): void\n on(event: \"message\", listener: (data: Buffer | string) => void): void\n on(event: \"error\", listener: (error: Error) => void): void\n on(event: \"close\", listener: (code: number, reason: Buffer) => void): void\n removeListener(event: string, listener: (...args: any[]) => void): void\n}\n\n/** WebSocket.CLOSED constant from 'ws' library */\nexport const WS_CLOSED = 3\n\n/**\n * Convert a WebSocket from the 'ws' library to an EffectWebSocket.\n *\n * This creates an Effect-based wrapper around the ws WebSocket instance,\n * providing a Stream for incoming messages and Effect-based send/close operations.\n *\n * This utility is used by platform packages (node, express) that integrate\n * with the 'ws' library for WebSocket support.\n *\n * @param ws - The WebSocket instance from the 'ws' library\n * @returns An EffectWebSocket that can be used with makeGraphQLWSHandler\n *\n * @example\n * ```typescript\n * import { toEffectWebSocketFromWs } from \"@effect-gql/core\"\n * import { WebSocket } from \"ws\"\n *\n * wss.on(\"connection\", (ws: WebSocket) => {\n * const effectSocket = toEffectWebSocketFromWs(ws)\n * Effect.runPromise(handler(effectSocket))\n * })\n * ```\n */\nexport const toEffectWebSocketFromWs = (ws: WsWebSocket): EffectWebSocket => {\n // Create the message stream using a queue\n const messagesEffect = Effect.gen(function* () {\n const queue = yield* Queue.unbounded<string>()\n const closed = yield* Deferred.make<CloseEvent, WebSocketError>()\n\n // Set up message listener\n ws.on(\"message\", (data) => {\n const message = data.toString()\n Effect.runPromise(Queue.offer(queue, message)).catch(() => {\n // Queue might be shutdown\n })\n })\n\n // Set up error listener\n ws.on(\"error\", (error) => {\n Effect.runPromise(Deferred.fail(closed, new WebSocketError({ cause: error }))).catch(() => {\n // Already completed\n })\n })\n\n // Set up close listener\n ws.on(\"close\", (code, reason) => {\n Effect.runPromise(\n Queue.shutdown(queue).pipe(\n Effect.andThen(Deferred.succeed(closed, { code, reason: reason.toString() }))\n )\n ).catch(() => {\n // Already completed\n })\n })\n\n return { queue, closed }\n })\n\n // Create the message stream\n const messages: Stream.Stream<string, WebSocketError> = Stream.unwrap(\n messagesEffect.pipe(\n Effect.map(({ queue }) => Stream.fromQueue(queue).pipe(Stream.catchAll(() => Stream.empty)))\n )\n )\n\n return {\n protocol: ws.protocol || \"graphql-transport-ws\",\n\n send: (data: string) =>\n Effect.async<void, WebSocketError>((resume) => {\n ws.send(data, (error) => {\n if (error) {\n resume(Effect.fail(new WebSocketError({ cause: error })))\n } else {\n resume(Effect.succeed(undefined))\n }\n })\n }),\n\n close: (code?: number, reason?: string) =>\n Effect.sync(() => {\n ws.close(code ?? 1000, reason ?? \"\")\n }),\n\n messages,\n\n closed: Effect.async<CloseEvent, WebSocketError>((resume) => {\n if (ws.readyState === WS_CLOSED) {\n resume(Effect.succeed({ code: 1000, reason: \"\" }))\n return\n }\n\n const onClose = (code: number, reason: Buffer) => {\n cleanup()\n resume(Effect.succeed({ code, reason: reason.toString() }))\n }\n\n const onError = (error: Error) => {\n cleanup()\n resume(Effect.fail(new WebSocketError({ cause: error })))\n }\n\n const cleanup = () => {\n ws.removeListener(\"close\", onClose)\n ws.removeListener(\"error\", onError)\n }\n\n ws.on(\"close\", onClose)\n ws.on(\"error\", onError)\n\n return Effect.sync(cleanup)\n }),\n }\n}\n","import { Data, Effect, Runtime, Stream } from \"effect\"\nimport type { ExecutionResult } from \"graphql\"\nimport type { ComplexityConfig, FieldComplexityMap } from \"./complexity\"\n\n/**\n * Standard SSE response headers following the graphql-sse protocol.\n * Use these headers when writing SSE responses in platform adapters.\n */\nexport const SSE_HEADERS: Record<string, string> = {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"X-Accel-Buffering\": \"no\", // Disable nginx buffering\n} as const\n\n/**\n * Error type for SSE operations\n */\nexport class SSEError extends Data.TaggedError(\"SSEError\")<{\n readonly cause: unknown\n}> {}\n\n/**\n * SSE event types following the graphql-sse protocol (distinct connections mode).\n * @see https://github.com/enisdenjo/graphql-sse/blob/master/PROTOCOL.md\n */\nexport type SSEEventType = \"next\" | \"error\" | \"complete\"\n\n/**\n * An SSE event to be sent to the client.\n */\nexport interface SSEEvent {\n readonly event: SSEEventType\n readonly data: string\n}\n\n/**\n * Platform-neutral SSE response interface using Effect types.\n *\n * This interface abstracts SSE operations across different platforms\n * (Node.js, Bun, Deno, Workers). Platform packages implement this\n * interface to bridge their specific HTTP response implementations.\n *\n * Unlike WebSocket which is bidirectional, SSE is unidirectional\n * (server to client only). The subscription query is provided\n * upfront when creating the SSE connection.\n */\nexport interface EffectSSE {\n /**\n * Send an SSE event to the client.\n * The platform adapter formats this as proper SSE format:\n * ```\n * event: next\n * data: {\"data\":{\"field\":\"value\"}}\n *\n * ```\n */\n readonly sendEvent: (event: SSEEvent) => Effect.Effect<void, SSEError>\n\n /**\n * Effect that completes when the client disconnects.\n * Use this to detect client disconnection and cleanup.\n */\n readonly closed: Effect.Effect<void, SSEError>\n}\n\n/**\n * The GraphQL request payload for SSE subscriptions.\n * Same as a regular GraphQL HTTP request.\n */\nexport interface SSESubscriptionRequest {\n readonly query: string\n readonly variables?: Record<string, unknown>\n readonly operationName?: string\n readonly extensions?: Record<string, unknown>\n}\n\n/**\n * Context available during an SSE subscription.\n * This is passed to lifecycle hooks.\n */\nexport interface SSEConnectionContext<R> {\n /**\n * The Effect runtime for this connection.\n * Use this to run Effects within the connection scope.\n */\n readonly runtime: Runtime.Runtime<R>\n\n /**\n * The original subscription request.\n */\n readonly request: SSESubscriptionRequest\n\n /**\n * Optional authentication/authorization context.\n * Populated by the onConnect hook.\n */\n readonly connectionContext: Record<string, unknown>\n}\n\n/**\n * Options for configuring the GraphQL SSE handler.\n *\n * @template R - Service requirements for lifecycle hooks\n */\nexport interface GraphQLSSEOptions<R> {\n /**\n * Query complexity limiting configuration.\n * When provided, subscriptions are validated against complexity limits\n * before execution begins.\n */\n readonly complexity?: ComplexityConfig\n\n /**\n * Field complexity definitions from the schema builder.\n * If using the platform serve() functions, this is typically\n * passed automatically.\n */\n readonly fieldComplexities?: FieldComplexityMap\n\n /**\n * Called before a subscription starts.\n *\n * Use this for authentication/authorization. Return:\n * - A context object to accept the subscription\n * - Throw/fail to reject the subscription\n *\n * The returned object is available in the GraphQL context.\n *\n * @example\n * ```typescript\n * onConnect: (request, headers) => Effect.gen(function* () {\n * const token = headers.get(\"authorization\")\n * const user = yield* AuthService.validateToken(token)\n * return { user } // Available in GraphQL context\n * })\n * ```\n */\n readonly onConnect?: (\n request: SSESubscriptionRequest,\n headers: Headers\n ) => Effect.Effect<Record<string, unknown>, unknown, R>\n\n /**\n * Called when the subscription starts streaming.\n */\n readonly onSubscribe?: (ctx: SSEConnectionContext<R>) => Effect.Effect<void, never, R>\n\n /**\n * Called when the subscription completes (normally or due to error).\n */\n readonly onComplete?: (ctx: SSEConnectionContext<R>) => Effect.Effect<void, never, R>\n\n /**\n * Called when the client disconnects.\n */\n readonly onDisconnect?: (ctx: SSEConnectionContext<R>) => Effect.Effect<void, never, R>\n\n /**\n * Called when an error occurs during subscription execution.\n */\n readonly onError?: (ctx: SSEConnectionContext<R>, error: unknown) => Effect.Effect<void, never, R>\n}\n\n/**\n * Configuration for the SSE endpoint\n */\nexport interface GraphQLSSEConfig {\n /**\n * Path for SSE connections.\n * @default \"/graphql/stream\"\n */\n readonly path?: string\n}\n\n/**\n * Result of SSE subscription handler creation.\n * This is used by platform packages to implement their SSE response.\n */\nexport interface SSESubscriptionResult {\n /**\n * Stream of SSE events to send to the client.\n * The platform adapter should consume this stream and send events.\n */\n readonly events: Stream.Stream<SSEEvent, SSEError>\n\n /**\n * Effect that should be run when client disconnects.\n * This allows cleanup of resources.\n */\n readonly cleanup: Effect.Effect<void, never, never>\n}\n\n/**\n * Format an ExecutionResult as an SSE \"next\" event.\n */\nexport const formatNextEvent = (result: ExecutionResult): SSEEvent => ({\n event: \"next\",\n data: JSON.stringify(result),\n})\n\n/**\n * Format errors as an SSE \"error\" event.\n */\nexport const formatErrorEvent = (errors: readonly unknown[]): SSEEvent => ({\n event: \"error\",\n data: JSON.stringify({ errors }),\n})\n\n/**\n * Format a \"complete\" event.\n */\nexport const formatCompleteEvent = (): SSEEvent => ({\n event: \"complete\",\n data: \"\",\n})\n\n/**\n * Format an SSE event to the wire format.\n * Each event is formatted as:\n * ```\n * event: <type>\n * data: <json>\n *\n * ```\n */\nexport const formatSSEMessage = (event: SSEEvent): string => {\n const lines = [`event: ${event.event}`]\n if (event.data) {\n lines.push(`data: ${event.data}`)\n }\n lines.push(\"\", \"\") // Two newlines to end the event\n return lines.join(\"\\n\")\n}\n","import { Effect, Layer, Stream } from \"effect\"\nimport {\n GraphQLSchema,\n parse,\n validate,\n subscribe,\n GraphQLError,\n Kind,\n type ExecutionResult,\n type DocumentNode,\n type OperationDefinitionNode,\n} from \"graphql\"\nimport type { GraphQLEffectContext } from \"../builder/types\"\nimport {\n SSEError,\n type GraphQLSSEOptions,\n type SSEConnectionContext,\n type SSESubscriptionRequest,\n type SSEEvent,\n formatNextEvent,\n formatErrorEvent,\n formatCompleteEvent,\n} from \"./sse-types\"\nimport { validateComplexity, type FieldComplexityMap } from \"./complexity\"\n\n/**\n * Create a subscription event stream for SSE.\n *\n * This function handles the GraphQL subscription lifecycle:\n * 1. Parse and validate the query\n * 2. Check complexity limits if configured\n * 3. Execute the subscription\n * 4. Stream results as SSE events\n *\n * @param schema - The GraphQL schema with subscription definitions\n * @param layer - Effect layer providing services required by resolvers\n * @param request - The subscription request (query, variables, operationName)\n * @param headers - HTTP headers from the request (for auth)\n * @param options - Optional lifecycle hooks and configuration\n * @returns A Stream of SSE events to send to the client\n *\n * @example\n * ```typescript\n * const eventStream = makeSSESubscriptionStream(\n * schema,\n * serviceLayer,\n * { query: \"subscription { tick { count } }\" },\n * new Headers(),\n * { onConnect: (req, headers) => Effect.succeed({ user: \"alice\" }) }\n * )\n *\n * // In platform-specific code, consume and send events:\n * Stream.runForEach(eventStream, (event) =>\n * Effect.sync(() => res.write(formatSSEMessage(event)))\n * )\n * ```\n */\nexport const makeSSESubscriptionStream = <R>(\n schema: GraphQLSchema,\n layer: Layer.Layer<R>,\n request: SSESubscriptionRequest,\n headers: Headers,\n options?: GraphQLSSEOptions<R>\n): Stream.Stream<SSEEvent, SSEError> => {\n const complexityConfig = options?.complexity\n const fieldComplexities: FieldComplexityMap = options?.fieldComplexities ?? new Map()\n\n return Stream.unwrap(\n Effect.gen(function* () {\n // Create a runtime from the layer\n const runtime = yield* Effect.provide(Effect.runtime<R>(), layer)\n\n // Run onConnect hook if provided\n let connectionContext: Record<string, unknown> = {}\n if (options?.onConnect) {\n try {\n connectionContext = yield* Effect.provide(options.onConnect(request, headers), layer)\n } catch {\n // Connection rejected\n return Stream.make(\n formatErrorEvent([\n new GraphQLError(\"Subscription connection rejected\", {\n extensions: { code: \"CONNECTION_REJECTED\" },\n }),\n ]),\n formatCompleteEvent()\n )\n }\n }\n\n // Parse the query\n let document: DocumentNode\n try {\n document = parse(request.query)\n } catch (syntaxError) {\n return Stream.make(formatErrorEvent([syntaxError]), formatCompleteEvent())\n }\n\n // Validate the query\n const validationErrors = validate(schema, document)\n if (validationErrors.length > 0) {\n return Stream.make(formatErrorEvent(validationErrors), formatCompleteEvent())\n }\n\n // Find the subscription operation\n const operations = document.definitions.filter(\n (d): d is OperationDefinitionNode => d.kind === Kind.OPERATION_DEFINITION\n )\n\n const operation = request.operationName\n ? operations.find((o) => o.name?.value === request.operationName)\n : operations[0]\n\n if (!operation) {\n return Stream.make(\n formatErrorEvent([new GraphQLError(\"No operation found in query\")]),\n formatCompleteEvent()\n )\n }\n\n if (operation.operation !== \"subscription\") {\n return Stream.make(\n formatErrorEvent([\n new GraphQLError(\n `SSE endpoint only supports subscriptions, received: ${operation.operation}`,\n { extensions: { code: \"OPERATION_NOT_SUPPORTED\" } }\n ),\n ]),\n formatCompleteEvent()\n )\n }\n\n // Validate complexity if configured\n if (complexityConfig) {\n const complexityResult = yield* validateComplexity(\n request.query,\n request.operationName,\n request.variables,\n schema,\n fieldComplexities,\n complexityConfig\n ).pipe(\n Effect.map(() => null),\n Effect.catchAll((error) => {\n if (error._tag === \"ComplexityLimitExceededError\") {\n return Effect.succeed(\n new GraphQLError(error.message, {\n extensions: {\n code: \"COMPLEXITY_LIMIT_EXCEEDED\",\n limitType: error.limitType,\n limit: error.limit,\n actual: error.actual,\n },\n })\n )\n }\n // Log analysis errors but don't block (fail open)\n return Effect.logWarning(\"Complexity analysis failed for SSE subscription\", error).pipe(\n Effect.map(() => null)\n )\n })\n )\n\n if (complexityResult) {\n return Stream.make(formatErrorEvent([complexityResult]), formatCompleteEvent())\n }\n }\n\n // Build the context for the subscription\n const ctx: SSEConnectionContext<R> = {\n runtime,\n request,\n connectionContext,\n }\n\n // Call onSubscribe hook if provided\n if (options?.onSubscribe) {\n yield* Effect.provide(options.onSubscribe(ctx), layer).pipe(\n Effect.catchAll(() => Effect.void)\n )\n }\n\n // Execute the subscription\n const graphqlContext: GraphQLEffectContext<R> & Record<string, unknown> = {\n runtime,\n ...connectionContext,\n }\n\n const subscriptionResult = yield* Effect.tryPromise({\n try: () =>\n subscribe({\n schema,\n document,\n variableValues: request.variables,\n operationName: request.operationName ?? undefined,\n contextValue: graphqlContext,\n }),\n catch: (error) => new SSEError({ cause: error }),\n })\n\n // Check if subscribe returned an error result instead of async iterator\n if (!isAsyncIterable(subscriptionResult)) {\n // It's an ExecutionResult with errors\n const result = subscriptionResult as ExecutionResult\n if (result.errors) {\n return Stream.make(formatErrorEvent(result.errors), formatCompleteEvent())\n }\n // Shouldn't happen, but handle gracefully\n return Stream.make(formatNextEvent(result), formatCompleteEvent())\n }\n\n // Create a stream from the async iterator\n const asyncIterator = subscriptionResult[Symbol.asyncIterator]()\n\n const eventStream = Stream.async<SSEEvent, SSEError>((emit) => {\n let done = false\n\n const iterate = async () => {\n try {\n while (!done) {\n const result = await asyncIterator.next()\n if (result.done) {\n emit.end()\n break\n }\n emit.single(formatNextEvent(result.value))\n }\n } catch (error) {\n if (!done) {\n emit.single(\n formatErrorEvent([\n error instanceof GraphQLError\n ? error\n : new GraphQLError(\n error instanceof Error ? error.message : \"Subscription error\",\n { extensions: { code: \"SUBSCRIPTION_ERROR\" } }\n ),\n ])\n )\n emit.end()\n }\n }\n }\n\n iterate()\n\n // Return cleanup function\n return Effect.sync(() => {\n done = true\n asyncIterator.return?.()\n })\n })\n\n // Add complete event at the end and handle cleanup\n return eventStream.pipe(\n Stream.onDone(() =>\n Effect.gen(function* () {\n yield* Effect.sync(() => {})\n }).pipe(Effect.asVoid)\n ),\n Stream.concat(Stream.make(formatCompleteEvent())),\n Stream.onDone(() => {\n if (options?.onComplete) {\n return Effect.provide(options.onComplete(ctx), layer).pipe(\n Effect.catchAll(() => Effect.void)\n )\n }\n return Effect.void\n })\n )\n }).pipe(\n Effect.catchAll((error) =>\n Effect.succeed(\n Stream.make(\n formatErrorEvent([\n new GraphQLError(error instanceof Error ? error.message : \"Internal error\", {\n extensions: { code: \"INTERNAL_ERROR\" },\n }),\n ]),\n formatCompleteEvent()\n )\n )\n )\n )\n )\n}\n\n/**\n * Create an SSE subscription handler that can be used with platform-specific servers.\n *\n * This is a higher-level API that returns a handler function. The handler\n * takes a request and headers, and returns a Stream of SSE events.\n *\n * @param schema - The GraphQL schema with subscription definitions\n * @param layer - Effect layer providing services required by resolvers\n * @param options - Optional lifecycle hooks and configuration\n * @returns A handler function for SSE subscription requests\n *\n * @example\n * ```typescript\n * const handler = makeGraphQLSSEHandler(schema, serviceLayer, {\n * onConnect: (request, headers) => Effect.gen(function* () {\n * const token = headers.get(\"authorization\")\n * const user = yield* AuthService.validateToken(token)\n * return { user }\n * }),\n * })\n *\n * // In platform-specific code:\n * const events = handler(request, headers)\n * // Stream events to client...\n * ```\n */\nexport const makeGraphQLSSEHandler = <R>(\n schema: GraphQLSchema,\n layer: Layer.Layer<R>,\n options?: GraphQLSSEOptions<R>\n): ((request: SSESubscriptionRequest, headers: Headers) => Stream.Stream<SSEEvent, SSEError>) => {\n return (request, headers) => makeSSESubscriptionStream(schema, layer, request, headers, options)\n}\n\n/**\n * Type guard to check if a value is an AsyncIterable (subscription result)\n */\nfunction isAsyncIterable<T>(value: unknown): value is AsyncIterable<T> {\n return typeof value === \"object\" && value !== null && Symbol.asyncIterator in value\n}\n"]}
|