msw
Version:
1 lines • 3.25 kB
Source Map (JSON)
{"version":3,"sources":["../../../../src/core/utils/internal/observe-response-body-stream.ts"],"sourcesContent":["import { DeferredPromise } from '@open-draft/deferred-promise'\nimport { FetchResponse } from '@mswjs/interceptors'\nimport { copyResponseOwnProperties } from '../HttpResponse/decorators'\n\nexport interface ObservedResponse {\n response: Response\n /**\n * A promise that resolves once the response body stream has settled:\n * it was closed, errored, or canceled, and will not be used anymore.\n */\n settled: Promise<void>\n}\n\n/**\n * Observe the `ReadableStream` body of the given response.\n * Returns a copy of that response whose body reports when it has\n * settled (was read to completion, errored, or canceled by the consumer).\n * Returns `null` for responses whose body cannot be observed\n * (no body, already used, or locked).\n */\nexport function observeResponseBodyStream(\n response: Response,\n): ObservedResponse | null {\n if (response.body == null || response.bodyUsed || response.body.locked) {\n return null\n }\n\n const settled = new DeferredPromise<void>()\n const reader = response.body.getReader()\n\n /**\n * @note Relay the body through a manual underlying source instead of\n * `.pipeThrough(new TransformStream({ flush, cancel }))`. The `cancel`\n * transformer callback is not implemented in Chromium, which loses\n * the stream error/cancelation signals there entirely.\n */\n const observedStream = new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n const readResult = await reader.read()\n\n if (readResult.done) {\n settled.resolve()\n controller.close()\n return\n }\n\n controller.enqueue(readResult.value)\n } catch (error) {\n settled.resolve()\n throw error\n }\n },\n async cancel(reason) {\n settled.resolve()\n await reader.cancel(reason)\n },\n })\n\n /**\n * @note Reconstruct the response because the body of an existing\n * response cannot be replaced. Use `FetchResponse` to support\n * non-standard response status codes (e.g. 101).\n */\n const observedResponse = new FetchResponse(observedStream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n })\n\n copyResponseOwnProperties(response, observedResponse)\n\n return {\n response: observedResponse,\n settled,\n }\n}\n"],"mappings":"AAAA,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,iCAAiC;AAkBnC,SAAS,0BACd,UACyB;AACzB,MAAI,SAAS,QAAQ,QAAQ,SAAS,YAAY,SAAS,KAAK,QAAQ;AACtE,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,IAAI,gBAAsB;AAC1C,QAAM,SAAS,SAAS,KAAK,UAAU;AAQvC,QAAM,iBAAiB,IAAI,eAA2B;AAAA,IACpD,MAAM,KAAK,YAAY;AACrB,UAAI;AACF,cAAM,aAAa,MAAM,OAAO,KAAK;AAErC,YAAI,WAAW,MAAM;AACnB,kBAAQ,QAAQ;AAChB,qBAAW,MAAM;AACjB;AAAA,QACF;AAEA,mBAAW,QAAQ,WAAW,KAAK;AAAA,MACrC,SAAS,OAAO;AACd,gBAAQ,QAAQ;AAChB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,MAAM,OAAO,QAAQ;AACnB,cAAQ,QAAQ;AAChB,YAAM,OAAO,OAAO,MAAM;AAAA,IAC5B;AAAA,EACF,CAAC;AAOD,QAAM,mBAAmB,IAAI,cAAc,gBAAgB;AAAA,IACzD,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB,SAAS,SAAS;AAAA,EACpB,CAAC;AAED,4BAA0B,UAAU,gBAAgB;AAEpD,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,EACF;AACF;","names":[]}