UNPKG

@apollo/client

Version:

A fully-featured caching GraphQL client.

97 lines 3.25 kB
import { DeepMerger, hasDirectives, isNonEmptyArray, } from "@apollo/client/utilities/internal"; class DeferRequest { hasNext = true; errors = []; extensions = {}; data = {}; mergeIn(normalized, merger) { if (normalized.data !== undefined) { this.data = merger.merge(this.data, normalized.data); } if (normalized.errors) { this.errors.push(...normalized.errors); } Object.assign(this.extensions, normalized.extensions); } handle( // we'll get `undefined` here in case of a `no-cache` fetch policy, // so we'll continue with the last value this request had accumulated cacheData = this.data, chunk) { this.hasNext = chunk.hasNext; this.data = cacheData; this.mergeIn(chunk, new DeepMerger()); if (hasIncrementalChunks(chunk)) { const merger = new DeepMerger(); for (const incremental of chunk.incremental) { let { data, path, errors, extensions } = incremental; if (data && path) { for (let i = path.length - 1; i >= 0; --i) { const key = path[i]; const isNumericKey = !isNaN(+key); const parent = isNumericKey ? [] : {}; parent[key] = data; data = parent; } } this.mergeIn({ errors, extensions, data: data ? data : undefined, }, merger); } } const result = { data: this.data }; if (isNonEmptyArray(this.errors)) { result.errors = this.errors; } if (Object.keys(this.extensions).length > 0) { result.extensions = this.extensions; } return result; } } /** * This handler implements the `@defer` directive as specified in this historical commit: * https://github.com/graphql/graphql-spec/tree/48cf7263a71a683fab03d45d309fd42d8d9a6659/spec */ export class Defer20220824Handler { isIncrementalResult(result) { return "hasNext" in result; } extractErrors(result) { const acc = []; const push = ({ errors, }) => { if (errors) { acc.push(...errors); } }; if (this.isIncrementalResult(result)) { push(result); if (hasIncrementalChunks(result)) { result.incremental.forEach(push); } } if (acc.length) { return acc; } } prepareRequest(request) { if (hasDirectives(["defer"], request.query)) { const context = request.context ?? {}; const http = (context.http ??= {}); http.accept = [ "multipart/mixed;deferSpec=20220824", ...(http.accept || []), ]; } return request; } startRequest(_) { return new DeferRequest(); } } // only exported for use in tests export function hasIncrementalChunks(result) { return isNonEmptyArray(result.incremental); } //# sourceMappingURL=defer20220824.js.map