Skip to content

Commit

Permalink
correctly detect which responses are streamed for recording increment…
Browse files Browse the repository at this point in the history
…al payloads
  • Loading branch information
thomasheyenbrock committed May 18, 2024
1 parent 9dc9e64 commit 6f3fcb3
Showing 1 changed file with 46 additions and 3 deletions.
49 changes: 46 additions & 3 deletions packages/graphiql-react/src/execution.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import {
isObservable,
Unsubscribable,
} from '@graphiql/toolkit';
import { ExecutionResult, FragmentDefinitionNode, print } from 'graphql';
import {
ExecutionResult,
FragmentDefinitionNode,
getOperationAST,
OperationTypeNode,
print,
} from 'graphql';
import { getFragmentDependenciesForAST } from 'graphql-language-service';
import { ReactNode, useCallback, useMemo, useRef, useState } from 'react';

Expand Down Expand Up @@ -195,6 +201,12 @@ export function ExecutionContextProvider({

const opName = operationName ?? queryEditor.operationName ?? undefined;

let isSubscription = false;

Check warning on line 204 in packages/graphiql-react/src/execution.tsx

View check run for this annotation

Codecov / codecov/patch

packages/graphiql-react/src/execution.tsx#L204

Added line #L204 was not covered by tests
if (queryEditor.documentAST) {
const operation = getOperationAST(queryEditor.documentAST, opName);
isSubscription = operation?.operation === OperationTypeNode.SUBSCRIPTION;

Check warning on line 207 in packages/graphiql-react/src/execution.tsx

View check run for this annotation

Codecov / codecov/patch

packages/graphiql-react/src/execution.tsx#L206-L207

Added lines #L206 - L207 were not covered by tests
}

history?.addToHistory({
query,
variables: variablesString,
Expand Down Expand Up @@ -247,15 +259,35 @@ export function ExecutionContextProvider({
},
);

// Subscriptions are always considered streamed responses
let isStreaming = isSubscription;

Check warning on line 263 in packages/graphiql-react/src/execution.tsx

View check run for this annotation

Codecov / codecov/patch

packages/graphiql-react/src/execution.tsx#L263

Added line #L263 was not covered by tests

const value = await Promise.resolve(fetch);
if (isObservable(value)) {
// If the fetcher returned an Observable, then subscribe to it, calling
// the callback on each next value, and handling both errors and the
// completion of the Observable.
//
// Note: The naming of the React state assumes that in this case the
// operation is a subscription (which in practice it most likely is),
// but technically it can also be a query or mutation where the fetcher
// decided to return an observable with either a single payload or
// multiple payloads (defer/stream). As the naming is part of the
// public API of this context we decide not to change it until defer/
// stream is officially part of the GraphQL spec.
setSubscription(
value.subscribe({
next(result) {
handleResponse(result, true);
handleResponse(

Check warning on line 281 in packages/graphiql-react/src/execution.tsx

View check run for this annotation

Codecov / codecov/patch

packages/graphiql-react/src/execution.tsx#L281

Added line #L281 was not covered by tests
result,
// If the initial payload contains `hasNext` for a query or
// mutation then we know it's a streamed response.
isStreaming || result.hasNext,
);

// If there's more than one payload then we're streaming, so set
// this flag to `true` for any future calls to `next`.
isStreaming = true;

Check warning on line 290 in packages/graphiql-react/src/execution.tsx

View check run for this annotation

Codecov / codecov/patch

packages/graphiql-react/src/execution.tsx#L290

Added line #L290 was not covered by tests
},
error(error: Error) {
setIsFetching(false);
Expand All @@ -274,9 +306,20 @@ export function ExecutionContextProvider({
setSubscription({
unsubscribe: () => value[Symbol.asyncIterator]().return?.(),
});

for await (const result of value) {
handleResponse(result, true);
handleResponse(

Check warning on line 311 in packages/graphiql-react/src/execution.tsx

View check run for this annotation

Codecov / codecov/patch

packages/graphiql-react/src/execution.tsx#L311

Added line #L311 was not covered by tests
result,
// If the initial payload contains `hasNext` for a query or
// mutation then we know it's a streamed response.
isStreaming || result.hasNext,
);

// If there's more than one payload then we're streaming, so set this
// flag to `true` for any future loop iterations.
isStreaming = true;

Check warning on line 320 in packages/graphiql-react/src/execution.tsx

View check run for this annotation

Codecov / codecov/patch

packages/graphiql-react/src/execution.tsx#L320

Added line #L320 was not covered by tests
}

setIsFetching(false);
setSubscription(null);
} else {
Expand Down

0 comments on commit 6f3fcb3

Please sign in to comment.