import { ApolloLink , Operation , FetchResult , Observable , fromError , } from 'apollo-link' ; import { serializeFetchParameter , selectURI , parseAndCheckHttpResponse , checkFetcher , selectHttpOptionsAndBody , createSignalIfSupported , fallbackHttpConfig , HttpOptions , } from 'apollo-link-http-common' ; import { BatchLink } from 'apollo-link-batch' ; export namespace BatchHttpLink { export interface Options extends HttpOptions { /**
         * The maximum number of operations to include in one fetch.
         *
         * Defaults to 10.
         */ batchMax ? : number ; /**
         * The interval at which to batch, in milliseconds.
         *
         * Defaults to 10.
         */ batchInterval ? : number ; /**
         * Sets the key for an Operation, which specifies the batch an operation is included in
         */ batchKey ? : ( operation : Operation ) => string ; } } /**
 * Transforms Operation for into HTTP results.
 * context can include the headers property, which will be passed to the fetch function
 */ export class BatchHttpLink extends ApolloLink { private batchInterval : number ; private batchMax : number ; private batcher : ApolloLink ; constructor ( fetchParams ? ) { super ( ) ; let { uri = '/graphql' , fetch : fetcher , includeExtensions , batchInterval , batchMax , batchKey , ... requestOptions } = fetchParams || ( { } as BatchHttpLink . Options ) ; checkFetcher ( fetcher ) ; if ( ! fetcher ) { fetcher = fetch ; } const linkConfig = { http : { includeExtensions } , options : requestOptions . fetchOptions , credentials : requestOptions . credentials , headers : requestOptions . headers , } ; this . batchInterval = batchInterval || 10 ; this . batchMax = batchMax || 10 ; const batchHandler = ( operations ) => { const chosenURI = selectURI ( operations [ 0 ] , uri ) ; const context = operations [ 0 ] . getContext ( ) ; const clientAwarenessHeaders = { } ; if ( context . clientAwareness ) { const { name , version } = context . clientAwareness ; if ( name ) { clientAwarenessHeaders [ 'apollographql-client-name' ] = name ; } if ( version ) { clientAwarenessHeaders [ 'apollographql-client-version' ] = version ; } } const contextConfig = { http : context . http , options : context . fetchOptions , credentials : context . credentials , headers : { ... clientAwarenessHeaders , ... context . headers } , } ; const optsAndBody = operations . map ( operation => selectHttpOptionsAndBody ( operation , fallbackHttpConfig , linkConfig , contextConfig ) ) ; const loadedBody = optsAndBody . map ( ( { body } ) => body ) ; const options = optsAndBody [ 0 ] . options ; if ( options . method === 'GET' ) { return fromError < FetchResult [ ] > ( new Error ( 'apollo-link-batch-http does not support GET requests' ) ) ; } try { ( options as any ) . body = serializeFetchParameter ( loadedBody , 'Payload' ) ; } catch ( parseError ) { return fromError < FetchResult [ ] > ( parseError ) ; } let controller ; if ( ! ( options as any ) . signal ) { const { controller : _controller , signal } = createSignalIfSupported ( ) ; controller = _controller ; if ( controller ) ( options as any ) . signal = signal ; } return new Observable < FetchResult [ ] > ( observer => { fetcher ( chosenURI , options ) . then ( response => { operations . forEach ( operation => operation . setContext ( { response } ) ) ; return response ; } ) . then ( parseAndCheckHttpResponse ( operations ) ) . then ( result => { observer . next ( result ) ; observer . complete ( ) ; return result ; } ) . catch ( err => { if ( err . name === 'AbortError' ) return ; if ( err . result && err . result . errors && err . result . data ) { observer . next ( err . result ) ; } observer . error ( err ) ; } ) ; return ( ) => { if ( controller ) controller . abort ( ) ; } ; } ) ; } ; batchKey = batchKey || ( ( operation ) => { const context = operation . getContext ( ) ; const contextConfig = { http : context . http , options : context . fetchOptions , credentials : context . credentials , headers : context . headers , } ; return selectURI ( operation , uri ) + JSON . stringify ( contextConfig ) ; } ) ; this . batcher = new BatchLink ( { batchInterval : this . batchInterval , batchMax : this . batchMax , batchKey , batchHandler , } ) ; } public request ( operation ) { return this . batcher . request ( operation ) ; } }