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

feat(core): Allow fetch exchange to handle subscriptions (#3106)

authored by kitten.sh and committed by

GitHub 97c8be2c a28a58f5

+38 -3
+5
.changeset/tricky-poets-clap.md
··· 1 + --- 2 + '@urql/core': minor 3 + --- 4 + 5 + Allow subscriptions to be handled by the `fetchExchange` when `fetchSubscriptions` is turned on.
+10
packages/core/src/client.ts
··· 100 100 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API} for the Fetch API spec. 101 101 */ 102 102 fetch?: typeof fetch; 103 + /** Allows a subscription to be executed using a `fetch` API request. 104 + * 105 + * @remarks 106 + * If your API supports the `text/event-stream` and/or `multipart/mixed` response protocol, and you use 107 + * this protocol to handle subscriptions, then you may switch this flag to `true`. 108 + * 109 + * This means you won’t have to create a {@link subscriptionExchange} to handle subscriptions with an 110 + * external transport, and will instead be able to use GraphQL over HTTP transports. 111 + */ 112 + fetchSubscriptions?: boolean; 103 113 /** A list of `Exchange`s that will be used to create the `Client`'s execution pipeline. 104 114 * 105 115 * @remarks
+10 -2
packages/core/src/exchanges/fetch.ts
··· 31 31 const fetchResults$ = pipe( 32 32 ops$, 33 33 filter(operation => { 34 - return operation.kind === 'query' || operation.kind === 'mutation'; 34 + return ( 35 + operation.kind !== 'teardown' && 36 + (operation.kind !== 'subscription' || 37 + !!operation.context.fetchSubscriptions) 38 + ); 35 39 }), 36 40 mergeMap(operation => { 37 41 const body = makeFetchBody(operation); ··· 87 91 const forward$ = pipe( 88 92 ops$, 89 93 filter(operation => { 90 - return operation.kind !== 'query' && operation.kind !== 'mutation'; 94 + return ( 95 + operation.kind === 'teardown' || 96 + (operation.kind === 'subscription' && 97 + !operation.context.fetchSubscriptions) 98 + ); 91 99 }), 92 100 forward 93 101 );
+3 -1
packages/core/src/internal/fetchOptions.ts
··· 121 121 ): RequestInit => { 122 122 const headers: HeadersInit = { 123 123 accept: 124 - 'application/graphql-response+json, application/graphql+json, application/json, text/event-stream, multipart/mixed', 124 + operation.kind === 'subscription' 125 + ? 'text/event-stream, multipart/mixed' 126 + : 'application/graphql-response+json, application/graphql+json, application/json, text/event-stream, multipart/mixed', 125 127 }; 126 128 const extraOptions = 127 129 (typeof operation.context.fetchOptions === 'function'
+10
packages/core/src/types.ts
··· 473 473 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/fetch} for a description of this object. 474 474 */ 475 475 fetchOptions?: RequestInit | (() => RequestInit); 476 + /** Allows the `fetchExchange` to handle subscriptions. 477 + * 478 + * @remarks 479 + * When set to `true`, subscriptions are allowed to be handled by the {@link fetchExchange} and will 480 + * be sent using a `fetch` call as GraphQL over HTTP requests. 481 + * This may be enabled on {@link ClientOptions.fetchSubscriptions} when your API supports the 482 + * `text/event-stream` and `multipart/mixed` response protocols and is able to use them to 483 + * respond with subscription results. 484 + */ 485 + fetchSubscriptions?: boolean; 476 486 /** The request and caching strategy instructing cache exchanges how to treat cached results. 477 487 * 478 488 * @remarks