import { DocumentNode , GraphQLFormattedError } from 'graphql' ; import { v4 } from 'uuid' ; import { isListeningOnDocument } from './isListeningOnDocument' ; import { FinchDocumentEventNames , FinchResponseEvent } from './types' ; const DEFAULT_TIMEOUT = 3000 ; interface QueryApiFromDocumentOptions { timeout ? : number ; extensionId : string ; } param query param variables param options param options . timeout returns export const queryApiFromDocument = async < Query extends { } , Variables extends any > ( query , variables ? , options ? ) : Promise < { data : Query | null ; errors : Array < GraphQLFormattedError > ; } > => { if ( ! isListeningOnDocument ( ) ) { return Promise . reject ( new Error ( 'Finch is not currently listening for messages' ) ) ; } const requestId = v4 ( ) ; return new Promise ( ( resolve , reject ) => { const timer = setTimeout ( ( ) => { reject ( new Error ( 'Finch request has timed out.' ) ) ; window . removeEventListener ( 'message' , onMessage ) ; } , options ?. timeout ?? DEFAULT_TIMEOUT ) ; const onMessage = async ( event ) => { if ( ! event . data . type || event . data . type !== FinchDocumentEventNames . Response || event . data . requestId !== requestId ) { return ; } clearTimeout ( timer ) ; resolve ( { data : event . data . data as Query | null , errors : event . data . errors } ) ; window . removeEventListener ( 'message' , onMessage ) ; } ; window . addEventListener ( 'message' , onMessage ) ; window . postMessage ( { type : FinchDocumentEventNames . Request , extensionId : options ?. extensionId , query , variables , requestId } , '*' ) ; } ) ; } ;