UNPKG

response-iterator

Version:

Creates an async iterator for a variety of inputs in the browser and node. Supports fetch, node-fetch, and cross-fetch

1 lines 9.12 kB
{"version":3,"file":"response-iterator.min.cjs","sources":["../../src/iterators/async.ts","../../src/iterators/nodeStream.ts","../../src/iterators/promise.ts","../../src/iterators/reader.ts","../../src/index.ts"],"sourcesContent":["export default function asyncIterator<T, TReturn = unknown, TNext = unknown>(source: AsyncIterableIterator<T, TReturn, TNext>): AsyncIterableIterator<T, TReturn, TNext> {\n const iterator = source[Symbol.asyncIterator]();\n return {\n next(): Promise<IteratorResult<T, TReturn>> {\n return iterator.next();\n },\n [Symbol.asyncIterator](): AsyncIterator<T, TReturn, TNext> {\n return this;\n },\n } as AsyncIterableIterator<T, TReturn, TNext>;\n}\n","import type { Readable as NodeReadableStream } from 'stream';\n\nconst hasIterator = typeof Symbol !== 'undefined' && Symbol.asyncIterator;\n\n/* c8 ignore start */\nexport default function nodeStreamIterator<T, TReturn = unknown, TNext = unknown>(stream: NodeReadableStream): AsyncIterableIterator<T, TReturn, TNext> {\n let cleanup = null;\n let error = null;\n let done = false;\n const data = [];\n const waiting = [];\n\n function onData(chunk) {\n if (error) return;\n if (waiting.length) return waiting.shift()[0]({ value: chunk, done: false });\n data.push(chunk);\n }\n function onError(err) {\n error = err;\n const all = waiting.slice();\n all.forEach((pair) => {\n pair[1](err);\n });\n !cleanup || cleanup();\n }\n function onEnd() {\n done = true;\n const all = waiting.slice();\n all.forEach((pair) => {\n pair[0]({ value: undefined, done: true });\n });\n !cleanup || cleanup();\n }\n\n cleanup = () => {\n cleanup = null;\n stream.removeListener('data', onData);\n stream.removeListener('error', onError);\n stream.removeListener('end', onEnd);\n stream.removeListener('finish', onEnd);\n stream.removeListener('close', onEnd);\n };\n stream.on('data', onData);\n stream.on('error', onError);\n stream.on('end', onEnd);\n stream.on('finish', onEnd);\n stream.on('close', onEnd);\n\n function getNext(): Promise<IteratorResult<T, TReturn>> {\n return new Promise((resolve, reject) => {\n if (error) return reject(error);\n if (data.length) return resolve({ value: data.shift(), done: false });\n if (done) return resolve({ value: undefined, done: true });\n waiting.push([resolve, reject]);\n });\n }\n\n const iterator = {\n next(): Promise<IteratorResult<T, TReturn>> {\n return getNext();\n },\n };\n\n if (hasIterator) {\n iterator[Symbol.asyncIterator] = function (): AsyncIterator<T, TReturn> {\n return this;\n };\n }\n\n return iterator as AsyncIterableIterator<T, TReturn, TNext>;\n}\n/* c8 ignore stop */\n","const hasIterator = typeof Symbol !== 'undefined' && Symbol.asyncIterator;\n\n/* c8 ignore start */\nexport default function promiseIterator<T, TReturn = unknown, TNext = unknown>(promise: Promise<T>): AsyncIterableIterator<T, TReturn, TNext> {\n let resolved = false;\n\n const iterator = {\n next(): Promise<IteratorResult<T, TReturn>> {\n if (resolved) return Promise.resolve({ value: undefined, done: true });\n resolved = true;\n return new Promise((resolve, reject) => {\n promise\n .then((value: T) => {\n resolve({ value, done: false } as IteratorResult<T, TReturn>);\n })\n .catch(reject);\n });\n },\n };\n\n if (hasIterator) {\n iterator[Symbol.asyncIterator] = function (): AsyncIterator<T, TReturn> {\n return this;\n };\n }\n\n return iterator as AsyncIterableIterator<T, TReturn, TNext>;\n}\n/* c8 ignore stop */\n","const hasIterator = typeof Symbol !== 'undefined' && Symbol.asyncIterator;\n\n/* c8 ignore start */\nexport default function readerIterator<T, TReturn = unknown, TNext = unknown>(reader: ReadableStreamReader<T>): AsyncIterableIterator<T, TReturn, TNext> {\n const iterator = {\n next(): Promise<IteratorResult<T, TReturn>> {\n return reader.read(undefined) as Promise<IteratorResult<T, TReturn>>;\n },\n };\n\n if (hasIterator) {\n iterator[Symbol.asyncIterator] = function (): AsyncIterator<T, TReturn> {\n return this;\n };\n }\n\n return iterator as AsyncIterableIterator<T, TReturn, TNext>;\n}\n/* c8 ignore stop */\n","import type { Readable as NodeReadableStream } from 'stream';\nimport type { AxiosResponse } from 'axios';\nimport type { Response as NodeResponse } from 'node-fetch';\n\nimport asyncIterator from './iterators/async.js';\nimport nodeStreamIterator from './iterators/nodeStream.js';\nimport promiseIterator from './iterators/promise.js';\nimport readerIterator from './iterators/reader.js';\n\ninterface CrossFetchResponse {\n _bodyBlob: Blob;\n}\n\nconst hasIterator = typeof Symbol !== 'undefined' && Symbol.asyncIterator;\n\n/**\n * @param response A response. Supports fetch, node-fetch, and cross-fetch\n */\nexport default function responseIterator<T, TReturn = unknown, TNext = unknown>(response: unknown): AsyncIterableIterator<T, TReturn, TNext> {\n if (response === undefined) throw new Error('Missing response for responseIterator');\n\n // determine the body\n let body: unknown = response;\n if ((response as NodeResponse).body) body = (response as NodeResponse).body;\n // node-fetch, browser fetch, undici\n else if ((response as AxiosResponse).data) body = (response as AxiosResponse).data;\n // axios\n /* c8 ignore start */ else if ((response as CrossFetchResponse)._bodyBlob) body = (response as CrossFetchResponse)._bodyBlob; // cross-fetch\n /* c8 ignore stop */\n\n // adapt the body\n if (hasIterator && body[Symbol.asyncIterator]) return asyncIterator<T, TReturn, TNext>(body as AsyncIterableIterator<T, TReturn, TNext>);\n /* c8 ignore start */\n if ((body as ReadableStream<T>).getReader) return readerIterator<T, TReturn, TNext>((body as ReadableStream<T>).getReader());\n if ((body as Blob).stream) return readerIterator<T, TReturn, TNext>(((body as Blob).stream() as unknown as ReadableStream<T>).getReader());\n if ((body as Blob).arrayBuffer) return promiseIterator<T, TReturn, TNext>((body as Blob).arrayBuffer() as unknown as Promise<T>);\n if ((body as NodeReadableStream).pipe) return nodeStreamIterator<T, TReturn, TNext>(body as NodeReadableStream);\n /* c8 ignore stop */\n\n throw new Error('Unknown body type for responseIterator. Maybe you are not passing a streamable response');\n}\n"],"names":["asyncIterator","source","iterator","Symbol","next","this","hasIterator","nodeStreamIterator","stream","cleanup","error","done","data","waiting","onData","chunk","length","shift","value","push","onError","err","slice","forEach","pair","onEnd","undefined","removeListener","on","Promise","resolve","reject","readerIterator","reader","read","response","Error","promise","resolved","body","_bodyBlob","getReader","arrayBuffer","then","catch","pipe"],"mappings":"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"}