UNPKG

react-relay-network-modern

Version:

Network Layer for React Relay and Express (Batch Queries, AuthToken, Logging, Retry)

66 lines (51 loc) 1.54 kB
/* @flow */ /* eslint-disable no-await-in-loop */ import type { MiddlewareRaw, RelayRequestAny, FetchResponse, MiddlewareRawNextFn, } from '../definition'; export type ProgressOpts = { sizeHeader?: string, onProgress: (runningTotal: number, totalSize: ?number) => any, }; function createProgressHandler(opts: ProgressOpts) { const { onProgress, sizeHeader = 'Content-Length' } = opts || {}; return async (res: FetchResponse) => { const { body, headers } = res; if (!body) { return; } const totalResponseSize = headers.get(sizeHeader); let totalSize = null; if (totalResponseSize !== null) { totalSize = parseInt(totalResponseSize, 10); } const reader = body.getReader(); let completed = false; let runningTotal = 0; do { const step: { value: ?any, done: boolean } = await reader.read(); const { done, value } = step; const length = (value && value.length) || 0; completed = done; if (!completed) { runningTotal += length; onProgress(runningTotal, totalSize); } } while (!completed); }; } export default function progressMiddleware(opts: ProgressOpts): MiddlewareRaw { const progressHandler = createProgressHandler(opts); const mw = (next: MiddlewareRawNextFn) => async (req: RelayRequestAny): Promise<FetchResponse> => { const res: FetchResponse = await next(req); progressHandler(res.clone()); return res; }; mw.isRawMiddleware = true; return (mw: any); }