From 6552a1d6d320995b53501f88a6a5d83bbc9cfbaf Mon Sep 17 00:00:00 2001 From: Thomas Vervest Date: Thu, 18 Jul 2024 15:57:03 +0200 Subject: [PATCH] feat: add timeout and signal arguments to client-side --- src/client.test.ts | 31 +++++++++++++++++++++++++++++++ src/client.ts | 16 +++++++++++++--- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/client.test.ts b/src/client.test.ts index 5ef7dd6..c56a31d 100644 --- a/src/client.test.ts +++ b/src/client.test.ts @@ -143,4 +143,35 @@ describe("gqlClientFetch", () => { expect(gqlResponse).rejects.toThrow(); }); + + it.only("should use time out after 30 seconds by default", async () => { + const timeoutSpy = vi.spyOn(AbortSignal, "timeout"); + fetchMock.mockResponse(responseString); + + await fetcher(query, { + myVar: "baz", + }); + + expect(timeoutSpy).toHaveBeenCalledWith(30000); + + // It should not try to POST the query if the persisted query cannot be parsed + expect(fetchMock).toHaveBeenCalledTimes(1); + }); + + it.only("should use the provided timeout duration", async () => { + const fetcher = initClientFetcher("https://localhost/graphql", { + timeout: 1, + }); + const timeoutSpy = vi.spyOn(AbortSignal, "timeout"); + fetchMock.mockResponse(responseString); + + await fetcher(query, { + myVar: "baz", + }); + + expect(timeoutSpy).toHaveBeenCalledWith(1); + + // It should not try to POST the query if the persisted query cannot be parsed + expect(fetchMock).toHaveBeenCalledTimes(1); + }); }); diff --git a/src/client.ts b/src/client.ts index 2080163..8443443 100644 --- a/src/client.ts +++ b/src/client.ts @@ -17,17 +17,25 @@ type Options = { * @default false */ persistedQueries?: boolean; + + /** + * Sets the timeout duration in ms after which a request will throw a timeout error + * + * @default 30000 + */ + timeout?: number; }; export type ClientFetcher = ( astNode: DocumentTypeDecoration, - variables?: TVariables + variables?: TVariables, + signal?: AbortSignal ) => Promise>; export const initClientFetcher = ( endpoint: string, - { persistedQueries = false }: Options = {} + { persistedQueries = false, timeout = 30000 }: Options = {} ): ClientFetcher => /** * Executes a GraphQL query post request on the client. @@ -37,7 +45,8 @@ export const initClientFetcher = */ async ( astNode: DocumentTypeDecoration, - variables?: TVariables + variables?: TVariables, + signal: AbortSignal = AbortSignal.timeout(timeout) ): Promise> => { const query = astNode.toString(); @@ -72,6 +81,7 @@ export const initClientFetcher = headers: defaultHeaders, method: "GET", credentials: "include", + signal, }) ); }