diff --git a/package-lock.json b/package-lock.json index 42109639..1e28a3bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@sanity/client", - "version": "6.21.2", + "version": "6.21.3-canary.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@sanity/client", - "version": "6.21.2", + "version": "6.21.3-canary.0", "license": "MIT", "dependencies": { "@sanity/eventsource": "^5.0.2", diff --git a/package.json b/package.json index a09b0f5a..c7fed679 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sanity/client", - "version": "6.21.2", + "version": "6.21.3-canary.0", "description": "Client for retrieving, creating and patching data from Sanity.io", "keywords": [ "sanity", diff --git a/src/SanityClient.ts b/src/SanityClient.ts index a8136e65..7b2c2868 100644 --- a/src/SanityClient.ts +++ b/src/SanityClient.ts @@ -900,7 +900,7 @@ export class SanityClient { */ getDocument = Record>( id: string, - options?: {tag?: string}, + options?: {signal?: AbortSignal; tag?: string}, ): Promise | undefined> { return lastValueFrom(dataMethods._getDocument(this, this.#httpRequest, id, options)) } @@ -916,7 +916,7 @@ export class SanityClient { */ getDocuments = Record>( ids: string[], - options?: {tag?: string}, + options?: {signal?: AbortSignal; tag?: string}, ): Promise<(SanityDocument | null)[]> { return lastValueFrom(dataMethods._getDocuments(this, this.#httpRequest, ids, options)) } diff --git a/src/data/dataMethods.ts b/src/data/dataMethods.ts index c7eb8e05..309c2e3e 100644 --- a/src/data/dataMethods.ts +++ b/src/data/dataMethods.ts @@ -129,9 +129,14 @@ export function _getDocument>( client: ObservableSanityClient | SanityClient, httpRequest: HttpRequest, id: string, - opts: {tag?: string} = {}, + opts: {signal?: AbortSignal; tag?: string} = {}, ): Observable | undefined> { - const options = {uri: _getDataUrl(client, 'doc', id), json: true, tag: opts.tag} + const options = { + uri: _getDataUrl(client, 'doc', id), + json: true, + tag: opts.tag, + signal: opts.signal, + } return _requestObservable | undefined>(client, httpRequest, options).pipe( filter(isResponse), map((event) => event.body.documents && event.body.documents[0]), @@ -143,9 +148,14 @@ export function _getDocuments>( client: ObservableSanityClient | SanityClient, httpRequest: HttpRequest, ids: string[], - opts: {tag?: string} = {}, + opts: {signal?: AbortSignal; tag?: string} = {}, ): Observable<(SanityDocument | null)[]> { - const options = {uri: _getDataUrl(client, 'doc', ids.join(',')), json: true, tag: opts.tag} + const options = { + uri: _getDataUrl(client, 'doc', ids.join(',')), + json: true, + tag: opts.tag, + signal: opts.signal, + } return _requestObservable<(SanityDocument | null)[]>(client, httpRequest, options).pipe( filter(isResponse), map((event: Any) => { diff --git a/test/client.test.ts b/test/client.test.ts index 954c7607..242d0233 100644 --- a/test/client.test.ts +++ b/test/client.test.ts @@ -893,28 +893,84 @@ describe('client', async () => { } }) - test.skipIf(isEdge || typeof globalThis.AbortController === 'undefined')( + describe.skipIf(isEdge || typeof globalThis.AbortController === 'undefined')( 'can cancel request with an abort controller signal', - async () => { - expect.assertions(2) + () => { + test('client.fetch', async () => { + expect.assertions(2) - nock(projectHost()).get(`/v1/data/query/foo?query=*`).delay(100).reply(200, { - ms: 123, - query: '*', - result: [], + nock(projectHost()).get(`/v1/data/query/foo?query=*`).delay(100).reply(200, { + ms: 123, + query: '*', + result: [], + }) + + const abortController = new AbortController() + const promise = getClient().fetch('*', {}, {signal: abortController.signal}) + await new Promise((resolve) => setTimeout(resolve, 10)) + + try { + abortController.abort() + await promise + } catch (err: any) { + expect(err).toBeInstanceOf(Error) + expect(err.name, 'should throw AbortError').toBe('AbortError') + } + }) + test('client.getDocument', async () => { + expect.assertions(2) + + nock(projectHost()) + .get('/v1/data/doc/foo/abc123dfg') + .delay(100) + .reply(200, { + ms: 123, + documents: [{_id: 'abc123dfg', mood: 'lax'}], + }) + + const abortController = new AbortController() + const promise = getClient().getDocument('abc123dfg', {signal: abortController.signal}) + await new Promise((resolve) => setTimeout(resolve, 10)) + + try { + abortController.abort() + await promise + } catch (err: any) { + if (err.name === 'AssertionError') throw err + expect(err).toBeInstanceOf(Error) + expect(err.name, 'should throw AbortError').toBe('AbortError') + } }) - const abortController = new AbortController() - const fetch = getClient().fetch('*', {}, {signal: abortController.signal}) - await new Promise((resolve) => setTimeout(resolve, 10)) + test('client.getDocuments', async () => { + expect.assertions(2) + + nock(projectHost()) + .get('/v1/data/doc/foo/abc123dfg,abc321dfg') + .delay(100) + .reply(200, { + ms: 123, + documents: [ + {_id: 'abc123dfg', mood: 'lax'}, + {_id: 'abc321dfg', mood: 'tense'}, + ], + }) - try { - abortController.abort() - await fetch - } catch (err: any) { - expect(err).toBeInstanceOf(Error) - expect(err.name, 'should throw AbortError').toBe('AbortError') - } + const abortController = new AbortController() + const promise = getClient().getDocuments(['abc123dfg', 'abc321dfg'], { + signal: abortController.signal, + }) + await new Promise((resolve) => setTimeout(resolve, 10)) + + try { + abortController.abort() + await promise + } catch (err: any) { + if (err.name === 'AssertionError') throw err + expect(err).toBeInstanceOf(Error) + expect(err.name, 'should throw AbortError').toBe('AbortError') + } + }) }, )