diff --git a/src/All.slnx b/src/All.slnx
index 35b9f5e35c7..219c0702dce 100644
--- a/src/All.slnx
+++ b/src/All.slnx
@@ -90,9 +90,7 @@
-
-
@@ -112,7 +110,6 @@
-
diff --git a/src/CookieCrumble/src/CookieCrumble.HotChocolate/CookieCrumble.HotChocolate.csproj b/src/CookieCrumble/src/CookieCrumble.HotChocolate/CookieCrumble.HotChocolate.csproj
index d177e47f486..a674bb77188 100644
--- a/src/CookieCrumble/src/CookieCrumble.HotChocolate/CookieCrumble.HotChocolate.csproj
+++ b/src/CookieCrumble/src/CookieCrumble.HotChocolate/CookieCrumble.HotChocolate.csproj
@@ -10,7 +10,6 @@
-
diff --git a/src/HotChocolate/Adapters/src/Adapters.Mcp/HotChocolate.Adapters.Mcp.csproj b/src/HotChocolate/Adapters/src/Adapters.Mcp/HotChocolate.Adapters.Mcp.csproj
index 119b51ea708..6d167c021a3 100644
--- a/src/HotChocolate/Adapters/src/Adapters.Mcp/HotChocolate.Adapters.Mcp.csproj
+++ b/src/HotChocolate/Adapters/src/Adapters.Mcp/HotChocolate.Adapters.Mcp.csproj
@@ -6,7 +6,6 @@
-
diff --git a/src/HotChocolate/AspNetCore/src/Transport.Http/GraphQLHttpResponse.cs b/src/HotChocolate/AspNetCore/src/Transport.Http/GraphQLHttpResponse.cs
index 4c57bac7179..2281101d5b2 100644
--- a/src/HotChocolate/AspNetCore/src/Transport.Http/GraphQLHttpResponse.cs
+++ b/src/HotChocolate/AspNetCore/src/Transport.Http/GraphQLHttpResponse.cs
@@ -1,3 +1,5 @@
+
+using HotChocolate.Buffers;
#if FUSION
using System.Buffers;
using System.Net;
@@ -160,7 +162,7 @@ private async ValueTask ReadAsResultInternalAsync(string? charS
#if FUSION
// we try and read the first chunk into a single chunk.
var reader = PipeReader.Create(stream, s_options);
- var currentChunk = JsonMemory.Rent();
+ var currentChunk = JsonMemory.Rent(JsonMemoryKind.Json);
var currentChunkPosition = 0;
var chunkIndex = 0;
var chunks = ArrayPool.Shared.Rent(64);
@@ -215,7 +217,7 @@ private async ValueTask ReadAsResultInternalAsync(string? charS
}
chunks[chunkIndex++] = currentChunk;
- currentChunk = JsonMemory.Rent();
+ currentChunk = JsonMemory.Rent(JsonMemoryKind.Json);
currentChunkPosition = 0;
}
}
@@ -253,7 +255,7 @@ private async ValueTask ReadAsResultInternalAsync(string? charS
}
chunks[chunkIndex++] = currentChunk;
- currentChunk = JsonMemory.Rent();
+ currentChunk = JsonMemory.Rent(JsonMemoryKind.Json);
currentChunkPosition = 0;
}
}
diff --git a/src/HotChocolate/AspNetCore/src/Transport.Http/JsonLines/JsonLinesReader.cs b/src/HotChocolate/AspNetCore/src/Transport.Http/JsonLines/JsonLinesReader.cs
index b8bfef41735..f9896ac4442 100644
--- a/src/HotChocolate/AspNetCore/src/Transport.Http/JsonLines/JsonLinesReader.cs
+++ b/src/HotChocolate/AspNetCore/src/Transport.Http/JsonLines/JsonLinesReader.cs
@@ -2,6 +2,7 @@
using System.Buffers;
using System.IO.Pipelines;
using System.Runtime.CompilerServices;
+using HotChocolate.Buffers;
using HotChocolate.Fusion.Text.Json;
#else
using System.Buffers;
@@ -103,7 +104,7 @@ private static SourceResultDocument ParseDocument(ReadOnlySequence lineBuf
// Ceiling division to make sure we end up with the right amount of chunks.
var chunksNeeded = (requiredSize + JsonMemory.BufferSize - 1) / JsonMemory.BufferSize;
- var chunks = JsonMemory.RentRange(chunksNeeded);
+ var chunks = JsonMemory.RentRange(JsonMemoryKind.Json, chunksNeeded);
var chunkIndex = 0;
var chunkPosition = 0;
diff --git a/src/HotChocolate/AspNetCore/src/Transport.Http/Sse/SseEventParser.cs b/src/HotChocolate/AspNetCore/src/Transport.Http/Sse/SseEventParser.cs
index 47d0ba8e6a3..2866a300500 100644
--- a/src/HotChocolate/AspNetCore/src/Transport.Http/Sse/SseEventParser.cs
+++ b/src/HotChocolate/AspNetCore/src/Transport.Http/Sse/SseEventParser.cs
@@ -2,7 +2,7 @@
using System.Buffers;
using System.Diagnostics;
using System.Runtime.CompilerServices;
-using HotChocolate.Fusion.Text.Json;
+using HotChocolate.Buffers;
#else
using System.Runtime.CompilerServices;
diff --git a/src/HotChocolate/AspNetCore/src/Transport.Http/Sse/SseReader.cs b/src/HotChocolate/AspNetCore/src/Transport.Http/Sse/SseReader.cs
index f7de7d41d38..3348a1e1100 100644
--- a/src/HotChocolate/AspNetCore/src/Transport.Http/Sse/SseReader.cs
+++ b/src/HotChocolate/AspNetCore/src/Transport.Http/Sse/SseReader.cs
@@ -2,6 +2,7 @@
using System.Buffers;
using System.IO.Pipelines;
using System.Runtime.CompilerServices;
+using HotChocolate.Buffers;
using HotChocolate.Fusion.Text.Json;
#else
using System.Buffers;
@@ -107,7 +108,7 @@ public async IAsyncEnumerator GetAsyncEnumerator(
case SseEventType.Complete:
reader.AdvanceTo(buffer.GetPosition(1, position.Value));
#if FUSION
- JsonMemory.Return(eventBuffers);
+ JsonMemory.Return(JsonMemoryKind.Json, eventBuffers);
eventBuffers.Clear();
#endif
yield break;
@@ -162,7 +163,7 @@ public async IAsyncEnumerator GetAsyncEnumerator(
await reader.CompleteAsync().ConfigureAwait(false);
#if FUSION
// we return whatever is in here.
- JsonMemory.Return(eventBuffers);
+ JsonMemory.Return(JsonMemoryKind.Json, eventBuffers);
#endif
}
}
@@ -232,7 +233,7 @@ private static void WriteBytesToChunks(List chunks, ref int currentPosit
if (chunks.Count == 0 || currentPosition >= JsonMemory.BufferSize)
{
currentPosition = 0;
- chunks.Add(JsonMemory.Rent());
+ chunks.Add(JsonMemory.Rent(JsonMemoryKind.Json));
}
var currentChunk = chunks[^1];
diff --git a/src/HotChocolate/Caching/src/Caching/CacheControlConstraintsOptimizer.cs b/src/HotChocolate/Caching/src/Caching/CacheControlConstraintsOptimizer.cs
index c23eefea748..a12a2c80b87 100644
--- a/src/HotChocolate/Caching/src/Caching/CacheControlConstraintsOptimizer.cs
+++ b/src/HotChocolate/Caching/src/Caching/CacheControlConstraintsOptimizer.cs
@@ -1,5 +1,4 @@
using System.Collections.Immutable;
-using System.Runtime.CompilerServices;
using HotChocolate.Execution.Processing;
using HotChocolate.Language;
using HotChocolate.Types;
@@ -15,15 +14,16 @@ internal sealed class CacheControlConstraintsOptimizer : IOperationOptimizer
{
public void OptimizeOperation(OperationOptimizerContext context)
{
- if (context.Definition.Operation is not OperationType.Query
- || context.HasIncrementalParts
+ // TODO : we need to include this again when defer is back.
+ if (context.Operation.Kind is not OperationType.Query
+ // || context.HasIncrementalParts
|| ContainsIntrospectionFields(context))
{
// if this is an introspection query, we will not cache it.
return;
}
- var constraints = ComputeCacheControlConstraints(context.CreateOperation());
+ var constraints = ComputeCacheControlConstraints(context.Operation);
if (constraints.MaxAge is not null || constraints.SharedMaxAge is not null)
{
@@ -38,25 +38,13 @@ public void OptimizeOperation(OperationOptimizerContext context)
: null
};
- context.ContextData.Add(
- ExecutionContextData.CacheControlConstraints,
- constraints);
-
- context.ContextData.Add(
- ExecutionContextData.CacheControlHeaderValue,
- headerValue);
- }
-
- if (constraints.Vary is { Length: > 0 })
- {
- context.ContextData.Add(
- ExecutionContextData.VaryHeaderValue,
- string.Join(", ", constraints.Vary));
+ context.Operation.Features.SetSafe(constraints);
+ context.Operation.Features.SetSafe(headerValue);
}
}
private static ImmutableCacheConstraints ComputeCacheControlConstraints(
- IOperation operation)
+ Operation operation)
{
var constraints = new CacheControlConstraints();
var rootSelections = operation.RootSelectionSet.Selections;
@@ -91,9 +79,9 @@ private static ImmutableCacheConstraints ComputeCacheControlConstraints(
}
private static void ProcessSelection(
- ISelection selection,
+ Selection selection,
CacheControlConstraints constraints,
- IOperation operation)
+ Operation operation)
{
var field = selection.Field;
var maxAgeSet = false;
@@ -117,19 +105,18 @@ private static void ProcessSelection(
}
}
- if (selection.SelectionSet is not null)
+ if (selection.HasSelections)
{
var possibleTypes = operation.GetPossibleTypes(selection);
foreach (var type in possibleTypes)
{
- var selectionSet = Unsafe.As(operation.GetSelectionSet(selection, type));
- var length = selectionSet.Selections.Count;
- ref var start = ref selectionSet.GetSelectionsReference();
+ var selectionSet = operation.GetSelectionSet(selection, type);
+ var selections = selectionSet.Selections;
- for (var i = 0; i < length; i++)
+ foreach (var childSelection in selections)
{
- ProcessSelection(Unsafe.Add(ref start, i), constraints, operation);
+ ProcessSelection(childSelection, constraints, operation);
}
}
}
@@ -223,13 +210,11 @@ void ExtractCacheControlDetailsFromDirectives(
private static bool ContainsIntrospectionFields(OperationOptimizerContext context)
{
- var length = context.RootSelectionSet.Selections.Count;
- ref var start = ref ((SelectionSet)context.RootSelectionSet).GetSelectionsReference();
+ var selections = context.Operation.RootSelectionSet.Selections;
- for (var i = 0; i < length; i++)
+ foreach (var selection in selections)
{
- var field = Unsafe.Add(ref start, i).Field;
-
+ var field = selection.Field;
if (field.IsIntrospectionField
&& !field.Name.EqualsOrdinal(IntrospectionFieldNames.TypeName))
{
diff --git a/src/HotChocolate/Caching/src/Caching/HotChocolate.Caching.csproj b/src/HotChocolate/Caching/src/Caching/HotChocolate.Caching.csproj
index 19568782fb1..76d0623f5d7 100644
--- a/src/HotChocolate/Caching/src/Caching/HotChocolate.Caching.csproj
+++ b/src/HotChocolate/Caching/src/Caching/HotChocolate.Caching.csproj
@@ -18,7 +18,6 @@
-
diff --git a/src/HotChocolate/Caching/src/Caching/ImmutableCacheConstraints.cs b/src/HotChocolate/Caching/src/Caching/ImmutableCacheConstraints.cs
index 97472f0697e..91a1f454ef5 100644
--- a/src/HotChocolate/Caching/src/Caching/ImmutableCacheConstraints.cs
+++ b/src/HotChocolate/Caching/src/Caching/ImmutableCacheConstraints.cs
@@ -16,4 +16,16 @@ internal sealed class ImmutableCacheConstraints(
public CacheControlScope Scope { get; } = scope;
public ImmutableArray Vary { get; } = vary;
+
+ public string VaryString
+ {
+ get
+ {
+ field ??= Vary.Length is 0
+ ? string.Empty
+ : string.Join(", ", Vary);
+
+ return field;
+ }
+ }
}
diff --git a/src/HotChocolate/Caching/src/Caching/QueryCacheMiddleware.cs b/src/HotChocolate/Caching/src/Caching/QueryCacheMiddleware.cs
index 266b4011184..889d3476e28 100644
--- a/src/HotChocolate/Caching/src/Caching/QueryCacheMiddleware.cs
+++ b/src/HotChocolate/Caching/src/Caching/QueryCacheMiddleware.cs
@@ -30,8 +30,8 @@ public async ValueTask InvokeAsync(RequestContext context)
}
if (!context.TryGetOperation(out var operation)
- || !operation.ContextData.TryGetValue(ExecutionContextData.CacheControlHeaderValue, out var value)
- || value is not CacheControlHeaderValue cacheControlHeaderValue)
+ || !operation.Features.TryGet(out var headerValue)
+ || !operation.Features.TryGet(out var constraints))
{
return;
}
@@ -46,13 +46,11 @@ operationResult.ContextData is not null
? new ExtensionData(operationResult.ContextData)
: [];
- contextData.Add(ExecutionContextData.CacheControlHeaderValue, cacheControlHeaderValue);
+ contextData.Add(ExecutionContextData.CacheControlHeaderValue, headerValue);
- if (operation.ContextData.TryGetValue(ExecutionContextData.VaryHeaderValue, out var varyValue)
- && varyValue is string varyHeaderValue
- && !string.IsNullOrEmpty(varyHeaderValue))
+ if (constraints.Vary.Length > 0)
{
- contextData.Add(ExecutionContextData.VaryHeaderValue, varyHeaderValue);
+ contextData.Add(ExecutionContextData.VaryHeaderValue, constraints.Vary);
}
context.Result = operationResult.WithContextData(contextData);
diff --git a/src/HotChocolate/Core/HotChocolate.Core.slnx b/src/HotChocolate/Core/HotChocolate.Core.slnx
index 874b0c44d4f..64c576bc86a 100644
--- a/src/HotChocolate/Core/HotChocolate.Core.slnx
+++ b/src/HotChocolate/Core/HotChocolate.Core.slnx
@@ -7,9 +7,7 @@
-
-
@@ -29,7 +27,6 @@
-
diff --git a/src/HotChocolate/Core/src/Authorization/AuthorizeMiddleware.cs b/src/HotChocolate/Core/src/Authorization/AuthorizeMiddleware.cs
index 0a5aa008ea1..62f998fee96 100644
--- a/src/HotChocolate/Core/src/Authorization/AuthorizeMiddleware.cs
+++ b/src/HotChocolate/Core/src/Authorization/AuthorizeMiddleware.cs
@@ -69,16 +69,16 @@ private void SetError(
.SetMessage(AuthorizeMiddleware_NoDefaultPolicy)
.SetCode(ErrorCodes.Authentication.NoDefaultPolicy)
.SetPath(context.Path)
- .AddLocation(context.Selection.SyntaxNode)
+ .AddLocations(context.Selection)
.Build(),
AuthorizeResult.PolicyNotFound
=> ErrorBuilder.New()
.SetMessage(
AuthorizeMiddleware_PolicyNotFound,
- _directive.Policy!)
+ _directive.Policy)
.SetCode(ErrorCodes.Authentication.PolicyNotFound)
.SetPath(context.Path)
- .AddLocation(context.Selection.SyntaxNode)
+ .AddLocations(context.Selection)
.Build(),
_
=> ErrorBuilder.New()
@@ -88,7 +88,7 @@ private void SetError(
? ErrorCodes.Authentication.NotAuthorized
: ErrorCodes.Authentication.NotAuthenticated)
.SetPath(context.Path)
- .AddLocation(context.Selection.SyntaxNode)
+ .AddLocations(context.Selection)
.Build()
};
}
diff --git a/src/HotChocolate/Core/src/Authorization/HotChocolate.Authorization.csproj b/src/HotChocolate/Core/src/Authorization/HotChocolate.Authorization.csproj
index 36369fa8d90..c4fea1db81e 100644
--- a/src/HotChocolate/Core/src/Authorization/HotChocolate.Authorization.csproj
+++ b/src/HotChocolate/Core/src/Authorization/HotChocolate.Authorization.csproj
@@ -14,7 +14,7 @@
-
+
diff --git a/src/HotChocolate/Core/src/Core/HotChocolate.Core.csproj b/src/HotChocolate/Core/src/Core/HotChocolate.Core.csproj
index 8c5f1883691..21d8f857b7b 100644
--- a/src/HotChocolate/Core/src/Core/HotChocolate.Core.csproj
+++ b/src/HotChocolate/Core/src/Core/HotChocolate.Core.csproj
@@ -18,8 +18,6 @@
-
-
diff --git a/src/HotChocolate/Core/src/Execution.Abstractions/ErrorBuilderExtensions.cs b/src/HotChocolate/Core/src/Execution.Abstractions/ErrorBuilderExtensions.cs
index 628a75e4eb4..c269b159a40 100644
--- a/src/HotChocolate/Core/src/Execution.Abstractions/ErrorBuilderExtensions.cs
+++ b/src/HotChocolate/Core/src/Execution.Abstractions/ErrorBuilderExtensions.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using HotChocolate.Language;
@@ -8,109 +9,197 @@ namespace HotChocolate;
///
public static class ErrorBuilderExtensions
{
- ///
- /// Sets the field coordinate of the error.
- ///
- /// The error builder.
- /// The field coordinate.
- /// The error builder.
- public static ErrorBuilder SetCoordinate(
- this ErrorBuilder builder,
- SchemaCoordinate coordinate)
+ extension(ErrorBuilder builder)
{
- ArgumentNullException.ThrowIfNull(builder);
+ ///
+ /// Sets the field coordinate of the error.
+ ///
+ /// The field coordinate.
+ /// The error builder.
+ public ErrorBuilder SetCoordinate(SchemaCoordinate coordinate)
+ {
+ ArgumentNullException.ThrowIfNull(builder);
- return builder.SetExtension(nameof(coordinate), coordinate.ToString());
- }
+ return builder.SetExtension(nameof(coordinate), coordinate.ToString());
+ }
- ///
- /// Sets the input path of the error.
- ///
- /// The error builder.
- /// The input path.
- /// The error builder.
- public static ErrorBuilder SetInputPath(
- this ErrorBuilder builder,
- Path inputPath)
- {
- ArgumentNullException.ThrowIfNull(builder);
+ ///
+ /// Sets the input path of the error.
+ ///
+ /// The input path.
+ /// The error builder.
+ public ErrorBuilder SetInputPath(Path inputPath)
+ {
+ ArgumentNullException.ThrowIfNull(builder);
- return builder.SetExtension(nameof(inputPath), inputPath);
- }
+ return builder.SetExtension(nameof(inputPath), inputPath);
+ }
- ///
- /// Sets the message of the error.
- ///
- /// The error builder.
- /// The format of the message.
- /// The arguments for the message.
- /// The error builder.
- public static ErrorBuilder SetMessage(this ErrorBuilder builder, string format, params object[] args)
- {
- ArgumentNullException.ThrowIfNull(builder);
- ArgumentException.ThrowIfNullOrEmpty(format);
- ArgumentNullException.ThrowIfNull(args);
+ ///
+ /// Sets the message of the error.
+ ///
+ /// The format of the message.
+ /// The argument for the message.
+ /// The error builder.
+ public ErrorBuilder SetMessage([StringSyntax("CompositeFormat")] string format, object? arg1)
+ {
+ ArgumentNullException.ThrowIfNull(builder);
+ ArgumentException.ThrowIfNullOrEmpty(format);
- return builder.SetMessage(string.Format(CultureInfo.InvariantCulture, format, args));
- }
+ return builder.SetMessage(string.Format(CultureInfo.InvariantCulture, format, arg1));
+ }
- ///
- /// Adds a location to the error.
- ///
- /// The error builder.
- /// The syntax node.
- /// The error builder.
- public static ErrorBuilder AddLocation(this ErrorBuilder builder, ISyntaxNode node)
- {
- ArgumentNullException.ThrowIfNull(node);
+ ///
+ /// Sets the message of the error.
+ ///
+ /// The format of the message.
+ /// The first argument for the message.
+ /// The second argument for the message.
+ /// The error builder.
+ public ErrorBuilder SetMessage([StringSyntax("CompositeFormat")] string format, object? arg1, object? arg2)
+ {
+ ArgumentNullException.ThrowIfNull(builder);
+ ArgumentException.ThrowIfNullOrEmpty(format);
- if (node.Location is null)
+ return builder.SetMessage(string.Format(CultureInfo.InvariantCulture, format, arg1, arg2));
+ }
+
+ ///
+ /// Sets the message of the error.
+ ///
+ /// The format of the message.
+ /// The first argument for the message.
+ /// The second argument for the message.
+ /// The third argument for the message.
+ /// The error builder.
+ public ErrorBuilder SetMessage([StringSyntax("CompositeFormat")] string format, object? arg1, object? arg2, object? arg3)
{
- return builder;
+ ArgumentNullException.ThrowIfNull(builder);
+ ArgumentException.ThrowIfNullOrEmpty(format);
+
+ return builder.SetMessage(string.Format(CultureInfo.InvariantCulture, format, arg1, arg2, arg3));
}
- builder.AddLocation(new Location(node.Location.Line, node.Location.Column));
- return builder;
- }
+ ///
+ /// Sets the message of the error.
+ ///
+ /// The format of the message.
+ /// The argument for the message.
+ /// The error builder.
+ public ErrorBuilder SetMessage([StringSyntax("CompositeFormat")] string format, string? arg1)
+ {
+ ArgumentNullException.ThrowIfNull(builder);
+ ArgumentException.ThrowIfNullOrEmpty(format);
- ///
- /// Adds a location to the error if the error does not already have a location.
- ///
- /// The error builder.
- /// The syntax node.
- /// The error builder.
- public static ErrorBuilder TryAddLocation(this ErrorBuilder builder, ISyntaxNode? node)
- {
- if (node?.Location is null)
+ return builder.SetMessage(string.Format(CultureInfo.InvariantCulture, format, arg1));
+ }
+
+ ///
+ /// Sets the message of the error.
+ ///
+ /// The format of the message.
+ /// The first argument for the message.
+ /// The second argument for the message.
+ /// The error builder.
+ public ErrorBuilder SetMessage([StringSyntax("CompositeFormat")] string format, string? arg1, string? arg2)
{
- return builder;
+ ArgumentNullException.ThrowIfNull(builder);
+ ArgumentException.ThrowIfNullOrEmpty(format);
+
+ return builder.SetMessage(string.Format(CultureInfo.InvariantCulture, format, arg1, arg2));
}
- builder.TryAddLocation(new Location(node.Location.Line, node.Location.Column));
- return builder;
- }
+ ///
+ /// Sets the message of the error.
+ ///
+ /// The format of the message.
+ /// The first argument for the message.
+ /// The second argument for the message.
+ /// The third argument for the message.
+ /// The error builder.
+ public ErrorBuilder SetMessage([StringSyntax("CompositeFormat")] string format, string? arg1, string? arg2, string? arg3)
+ {
+ ArgumentNullException.ThrowIfNull(builder);
+ ArgumentException.ThrowIfNullOrEmpty(format);
- ///
- /// Adds multiple locations to the error.
- ///
- /// The error builder.
- /// The syntax nodes.
- /// The error builder.
- public static ErrorBuilder AddLocations(this ErrorBuilder builder, IEnumerable nodes)
- {
- ArgumentNullException.ThrowIfNull(builder);
- ArgumentNullException.ThrowIfNull(nodes);
+ return builder.SetMessage(string.Format(CultureInfo.InvariantCulture, format, arg1, arg2, arg3));
+ }
+
+ ///
+ /// Sets the message of the error.
+ ///
+ /// The format of the message.
+ /// The arguments for the message.
+ /// The error builder.
+ public ErrorBuilder SetMessage(
+ [StringSyntax("CompositeFormat")] string format,
+#if NET10_0_OR_GREATER
+ params ReadOnlySpan