Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.

fix(core): Return fetch source cancellation to old behaviour (#3239)

Changed files
+14 -9
.changeset
packages
core
src
internal
+5
.changeset/famous-snakes-double.md
···
···
+
---
+
'@urql/core': patch
+
---
+
+
Return `AbortController` invocation to previous behaviour where it used to be more forceful. It will now properly abort outside of when our generator yields results, and hence now also cancels requests again that have already delivered headers but are currently awaiting a response body.
+9 -9
packages/core/src/internal/fetchSource.ts
···
-
import { Source, fromAsyncIterable, filter, pipe } from 'wonka';
import { Operation, OperationResult, ExecutionResult } from '../types';
import { makeResult, makeErrorResult, mergeResultPatch } from '../utils';
···
fetchOptions: RequestInit
) {
let networkMode = true;
-
let abortController: AbortController | void;
let result: OperationResult | null = null;
let response: Response | void;
try {
-
if (typeof AbortController !== 'undefined') {
-
fetchOptions.signal = (abortController = new AbortController()).signal;
-
}
-
// Delay for a tick to give the Client a chance to cancel the request
// if a teardown comes in immediately
yield await Promise.resolve();
···
: error,
response
);
-
} finally {
-
if (abortController) abortController.abort();
}
}
···
url: string,
fetchOptions: RequestInit
): Source<OperationResult> {
return pipe(
fromAsyncIterable(fetchOperation(operation, url, fetchOptions)),
-
filter((result): result is OperationResult => !!result)
);
}
···
+
import { Source, fromAsyncIterable, onEnd, filter, pipe } from 'wonka';
import { Operation, OperationResult, ExecutionResult } from '../types';
import { makeResult, makeErrorResult, mergeResultPatch } from '../utils';
···
fetchOptions: RequestInit
) {
let networkMode = true;
let result: OperationResult | null = null;
let response: Response | void;
try {
// Delay for a tick to give the Client a chance to cancel the request
// if a teardown comes in immediately
yield await Promise.resolve();
···
: error,
response
);
}
}
···
url: string,
fetchOptions: RequestInit
): Source<OperationResult> {
+
let abortController: AbortController | void;
+
if (typeof AbortController !== 'undefined') {
+
fetchOptions.signal = (abortController = new AbortController()).signal;
+
}
return pipe(
fromAsyncIterable(fetchOperation(operation, url, fetchOptions)),
+
filter((result): result is OperationResult => !!result),
+
onEnd(() => {
+
if (abortController) abortController.abort();
+
})
);
}