import mitt from 'mitt' ; import { graphqlFetchOptions } from './graphqlFetchOptions' ; import { hashObject } from './hashObject' ; import { GraphQLCache , GraphQLCacheKey , GraphQLCacheValue , GraphQLFetchOptions } from '../index' ; const { on , off , emit } = mitt ( ) ; kind name param options param { GraphQLCache } options . cache param { GraphQLCache } options . cacheWrapper see [`reportCacheErrors`] reportCacheErrors to setup error reporting.
 *  example export class GraphQL { constructor ( { cache = { } , cacheWrapper } = { } ) { this . cache = cache ; this . cacheWrapper = cacheWrapper ; } kind name example cacheWrapper : Function ; kind name param { string } type param { Function } handler see [`reportCacheErrors`] reportCacheErrors can be used with this to setup error reporting.
      on = on ; kind name param { string } type param { Function } handler off = off ; param { string } type param { * } details ignore emit = emit ; kind name type { GraphQLCache } example example cache : GraphQLCache ; name operations : Record < GraphQLCacheKey , Promise < GraphQLCacheValue > > = { } ; /**
     * Signals that [GraphQL cache] GraphQL subscribers such as the
     * operation. Emits a [`GraphQL`] GraphQL instance `reload` event.
     *  kind name param { GraphQLCacheKey } exceptCacheKey A [GraphQL cache] GraphQL [key] GraphQLCacheKey for cache to exempt from reloading.
     *  example <caption>Reloading the [GraphQL cache] GraphQL .</caption>
     * ```js
     * graphql.reload()
     * ```
      reload = ( exceptCacheKey ) => { this . emit ( 'reload' , { exceptCacheKey } ) ; } ; /**
     * Resets the [GraphQL cache] GraphQL , useful when a user logs
     * out. Emits a [`GraphQL`] GraphQL instance `reset` event.
     *  kind name param { GraphQLCacheKey } exceptCacheKey A [GraphQL cache] GraphQL [key] GraphQLCacheKey for cache to exempt from deletion. Useful for resetting cache after a mutation, preserving the mutation cache.
     *  example <caption>Resetting the [GraphQL cache] GraphQL .</caption>
     * ```js
     * graphql.reset()
     * ```
      reset = ( exceptCacheKey ) => { let cacheKeys = Object . keys ( this . cache ) ; exceptCacheKey ? cacheKeys = cacheKeys . filter ( ( hash ) => hash !== exceptCacheKey ) : '' ; cacheKeys . forEach ( ( cacheKey ) => delete this . cache [ cacheKey ] ) ; this . emit ( 'reset' , { exceptCacheKey } ) ; } ; param { GraphQLFetchOptions } fetchOptions param { GraphQLCacheKey } cacheKey [GraphQL cache] GraphQL [key] GraphQLCacheKey .
     *  returns { Promise < GraphQLCacheValue > } A promise that resolves the [GraphQL cache] GraphQL [value] GraphQLCacheValue .
     *  ignore fetch = ( { url , ... options } , cacheKey ) : Promise < GraphQLCacheValue > => { let fetchResponse ; const fetcher = typeof fetch === 'function' ? fetch : ( ) => Promise . reject ( new Error ( 'Global fetch API or polyfill unavailable.' ) ) ; const cacheValue = { } ; const cacheValuePromise = fetcher ( url , options ) . then ( ( response ) => { fetchResponse = response ; if ( ! response . ok ) cacheValue . httpError = { status : response . status , statusText : response . statusText , } ; return response . json ( ) . then ( ( { errors , data } ) => { if ( ! errors && ! data ) cacheValue . parseError = 'Malformed payload.' ; if ( errors ) cacheValue . graphQLErrors = errors ; if ( data ) cacheValue . data = data ; } , ( { message } ) => { cacheValue . parseError = message ; } ) ; } , ( { message } ) => { cacheValue . fetchError = message ; } ) . then ( ( ) => { this . cache [ cacheKey ] = this . cacheWrapper ? this . cacheWrapper ( cacheValue ) : cacheValue ; delete this . operations [ cacheKey ] ; this . emit ( 'cache' , { cacheKey , cacheValue , response : fetchResponse , } ) ; return cacheValue ; } ) ; this . operations [ cacheKey ] = cacheValuePromise ; this . emit ( 'fetch' , { cacheKey , cacheValuePromise } ) ; return cacheValuePromise ; } ; /**
     * Loads or reuses an already loading GraphQL operation in
     * [GraphQL operations] GraphQL . Emits a
     * [`GraphQL`] GraphQL instance `fetch` event if an already loading
     * operation isn’t reused, and a `cache` event once it’s loaded into the
     * [GraphQL cache] GraphQL .
     *  kind name param options param { GraphQLOperation } options . operation param { GraphQLFetchOptionsOverride } options . fetchOptionsOverride Overrides default GraphQL operation [`fetch` options] GraphQLFetchOptions .
     *  param { boolean } options . reloadOnLoad Should a [GraphQL reload] GraphQL happen after the operation loads, excluding the loaded operation cache.
     *  param { boolean } options . resetOnLoad Should a [GraphQL reset] GraphQL happen after the operation loads, excluding the loaded operation cache.
     *  returns { GraphQLOperationLoading } operate = ( { operation , fetchOptionsOverride , reloadOnLoad , resetOnLoad } ) => { if ( reloadOnLoad && resetOnLoad ) throw new Error ( 'operate() options “reloadOnLoad” and “resetOnLoad” can’t both be true.' ) ; const fetchOptions = graphqlFetchOptions ( operation ) ; fetchOptionsOverride && fetchOptionsOverride ( fetchOptions ) ; const cacheKey = hashObject ( fetchOptions ) ; const cacheValuePromise = this . operations [ cacheKey ] || this . fetch ( fetchOptions , cacheKey ) ; cacheValuePromise . then ( ( ) => { if ( reloadOnLoad ) this . reload ( cacheKey ) ; else if ( resetOnLoad ) this . reset ( cacheKey ) ; } ) ; return { cacheKey , cacheValue : this . cache [ cacheKey ] , cacheValuePromise , } ; } ; }