From 2bfe77cea9a230bc896594db1c10d12c3183a629 Mon Sep 17 00:00:00 2001 From: 9swampy Date: Wed, 17 Apr 2024 01:16:25 +0100 Subject: [PATCH 1/5] Introduce overrideOptions and progress JSDocs annotations. --- README.md | 18 ++++----- src/index.ts | 110 ++++++++++++++++++++++++++++++--------------------- src/types.ts | 22 ++++++++++- 3 files changed, 94 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index ed689e1..dd56bd3 100644 --- a/README.md +++ b/README.md @@ -76,15 +76,15 @@ export default function App() { - An object with the following keys: -| key | description | arguments | -| ------------ | -------------------------------- | --------------------------------------------------------- | -| size | size in bytes | n/a | -| elapsed | elapsed time in seconds | n/a | -| percentage | percentage in string | n/a | -| download | download function handler | (downloadUrl: string, filename: string, timeout?: number) | -| cancel | cancel function handler | n/a | -| error | error object from the request | n/a | -| isInProgress | boolean denoting download status | n/a | +| key | description | arguments | +| ------------ | -------------------------------- | ------------------------------------------------------------------------------------------------- | +| size | size in bytes | n/a | +| elapsed | elapsed time in seconds | n/a | +| percentage | percentage in string | n/a | +| download | download function handler | (downloadUrl: string, filename: string, timeout?: number, overrideOptions?: UseDownloaderOptions) | +| cancel | cancel function handler | n/a | +| error | error object from the request | n/a | +| isInProgress | boolean denoting download status | n/a | ```jsx const { size, elapsed, percentage, download, cancel, error, isInProgress } = diff --git a/src/index.ts b/src/index.ts index c1230a6..694e844 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,11 @@ import { UseDownloaderOptions, } from './types'; +/** + * + * @param param0 + * @returns + */ export const resolver = ({ setSize, @@ -15,67 +20,74 @@ export const resolver = setPercentageCallback, setErrorCallback, }: ResolverProps) => - (response: Response): Response => { - if (!response.ok) { - throw Error(`${response.status} ${response.type} ${response.statusText}`); - } + (response: Response): Response => { + if (!response.ok) { + throw Error(`${response.status} ${response.type} ${response.statusText}`); + } - if (!response.body) { - throw Error('ReadableStream not yet supported in this browser.'); - } + if (!response.body) { + throw Error('ReadableStream not yet supported in this browser.'); + } - const responseBody = response.body; + const responseBody = response.body; - const contentEncoding = response.headers.get('content-encoding'); - const contentLength = response.headers.get( - contentEncoding ? 'x-file-size' : 'content-length' - ); + const contentEncoding = response.headers.get('content-encoding'); + const contentLength = response.headers.get( + contentEncoding ? 'x-file-size' : 'content-length' + ); - const total = parseInt(contentLength || '0', 10); + const total = parseInt(contentLength || '0', 10); - setSize(() => total); + setSize(() => total); - let loaded = 0; + let loaded = 0; - const stream = new ReadableStream({ - start(controller) { - setControllerCallback(controller); + const stream = new ReadableStream({ + start(controller) { + setControllerCallback(controller); - const reader = responseBody.getReader(); + const reader = responseBody.getReader(); - async function read(): Promise { - return reader - .read() - .then(({ done, value }) => { - if (done) { - return controller.close(); - } + async function read(): Promise { + return reader + .read() + .then(({ done, value }) => { + if (done) { + return controller.close(); + } - loaded += value?.byteLength || 0; + loaded += value?.byteLength || 0; - if (value) { - controller.enqueue(value); - } + if (value) { + controller.enqueue(value); + } - setPercentageCallback({ loaded, total }); + setPercentageCallback({ loaded, total }); - return read(); - }) - .catch((error: Error) => { - setErrorCallback(error); - reader.cancel('Cancelled'); + return read(); + }) + .catch((error: Error) => { + setErrorCallback(error); + reader.cancel('Cancelled'); - return controller.error(error); - }); - } + return controller.error(error); + }); + } - return read(); - }, - }); + return read(); + }, + }); - return new Response(stream); - }; + return new Response(stream); + }; +/** + * + * @param {Blob} data + * @param {string} filename + * @param {string} mime + * @returns + */ export const jsDownload = ( data: Blob, filename: string, @@ -118,12 +130,17 @@ export const jsDownload = ( }, 200); }; +/** + * Initialise a new instance of downloader. + * @param {UseDownloaderOptions} options + * @returns UseDownloader + */ export default function useDownloader( options: UseDownloaderOptions = {} ): UseDownloader { let debugMode = false; try { - debugMode = process ? !!process?.env?.REACT_APP_DEBUG_MODE : false; + debugMode = process ? !!process?.env?.REACT_APP_DEBUG_MODE : false; } catch { debugMode = false; } @@ -182,7 +199,7 @@ export default function useDownloader( }, [setControllerCallback]); const handleDownload: DownloadFunction = useCallback( - async (downloadUrl, filename, timeout = 0) => { + async (downloadUrl, filename, timeout = 0, overrideOptions = {}) => { if (isInProgress) return null; clearAllStateCallback(); @@ -208,6 +225,7 @@ export default function useDownloader( return fetch(downloadUrl, { method: 'GET', ...options, + ...overrideOptions, signal: fetchController.signal, }) .then(resolverWithProgress) diff --git a/src/types.ts b/src/types.ts index 4b1d554..bb9fbda 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,6 +4,12 @@ export type ErrorMessage = { errorMessage: string; } | null; +/** + * Initiate the download of the specified asset from the specified url. Optionally supply timeout and overrideOptions. + * @example await download('https://example.com/file.zip', 'file.zip') + * @example await download('https://example.com/file.zip', 'file.zip', 500) timeouts after 500ms + * @example await download('https://example.com/file.zip', 'file.zip', undefined, { method: 'GET' }) skips optional timeout but supplies overrideOptions + */ export type DownloadFunction = ( /** Download url * @example https://upload.wikimedia.org/wikipedia/commons/4/4d/%D0%93%D0%BE%D0%B2%D0%B5%D1%80%D0%BB%D0%B0_%D1%96_%D0%9F%D0%B5%D1%82%D1%80%D0%BE%D1%81_%D0%B2_%D0%BF%D1%80%D0%BE%D0%BC%D1%96%D0%BD%D1%8F%D1%85_%D0%B2%D1%80%D0%B0%D0%BD%D1%96%D1%88%D0%BD%D1%8C%D0%BE%D0%B3%D0%BE_%D1%81%D0%BE%D0%BD%D1%86%D1%8F.jpg @@ -14,9 +20,23 @@ export type DownloadFunction = ( */ filename: string, /** Optional timeout to download items */ - timeout?: number + timeout?: number, + /** Optional options to supplement and/or override UseDownloader options */ + overrideOptions?: UseDownloaderOptions ) => Promise; +/** + * Provides access to Downloader functionality and settings. + * + * @interface EditDialogField + * @field {number} size in bytes. + * @field {number} elapsed time in seconds. + * @field {number} percentage in string + * @field {DownloadFunction} download function handler + * @field {void} cancel function handler + * @field {ErrorMessage} error object from the request + * @field {boolean} isInProgress boolean flag denoting download status + */ export interface UseDownloader { /** Size in bytes */ size: number; From 51593b38d4787d23d183bb892d6a4c721095eb10 Mon Sep 17 00:00:00 2001 From: Olavo Parno Date: Wed, 17 Apr 2024 12:03:05 -0300 Subject: [PATCH 2/5] chore: adjust linting and stuff --- README.md | 2 +- src/index.ts | 110 +++++++++++++++++++++++++-------------------------- src/types.ts | 10 ++--- 3 files changed, 61 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index dd56bd3..be7aa08 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ | Statements | Branches | Functions | Lines | | ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| ![Statements](https://img.shields.io/badge/statements-87.38%25-yellow.svg?style=flat&logo=jest) | ![Branches](https://img.shields.io/badge/branches-72.5%25-red.svg?style=flat&logo=jest) | ![Functions](https://img.shields.io/badge/functions-81.81%25-yellow.svg?style=flat&logo=jest) | ![Lines](https://img.shields.io/badge/lines-88%25-yellow.svg?style=flat&logo=jest) | +| ![Statements](https://img.shields.io/badge/statements-87.38%25-yellow.svg?style=flat&logo=jest) | ![Branches](https://img.shields.io/badge/branches-73.17%25-red.svg?style=flat&logo=jest) | ![Functions](https://img.shields.io/badge/functions-81.81%25-yellow.svg?style=flat&logo=jest) | ![Lines](https://img.shields.io/badge/lines-88%25-yellow.svg?style=flat&logo=jest) | ## Table of Contents diff --git a/src/index.ts b/src/index.ts index 694e844..fe698ac 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,9 +9,9 @@ import { } from './types'; /** - * - * @param param0 - * @returns + * Resolver function to handle the download progress. + * @param {ResolverProps} props + * @returns {Response} */ export const resolver = ({ @@ -20,73 +20,73 @@ export const resolver = setPercentageCallback, setErrorCallback, }: ResolverProps) => - (response: Response): Response => { - if (!response.ok) { - throw Error(`${response.status} ${response.type} ${response.statusText}`); - } + (response: Response): Response => { + if (!response.ok) { + throw Error(`${response.status} ${response.type} ${response.statusText}`); + } - if (!response.body) { - throw Error('ReadableStream not yet supported in this browser.'); - } + if (!response.body) { + throw Error('ReadableStream not yet supported in this browser.'); + } - const responseBody = response.body; + const responseBody = response.body; - const contentEncoding = response.headers.get('content-encoding'); - const contentLength = response.headers.get( - contentEncoding ? 'x-file-size' : 'content-length' - ); + const contentEncoding = response.headers.get('content-encoding'); + const contentLength = response.headers.get( + contentEncoding ? 'x-file-size' : 'content-length' + ); - const total = parseInt(contentLength || '0', 10); + const total = parseInt(contentLength || '0', 10); - setSize(() => total); + setSize(() => total); - let loaded = 0; + let loaded = 0; - const stream = new ReadableStream({ - start(controller) { - setControllerCallback(controller); + const stream = new ReadableStream({ + start(controller) { + setControllerCallback(controller); - const reader = responseBody.getReader(); + const reader = responseBody.getReader(); - async function read(): Promise { - return reader - .read() - .then(({ done, value }) => { - if (done) { - return controller.close(); - } + async function read(): Promise { + return reader + .read() + .then(({ done, value }) => { + if (done) { + return controller.close(); + } - loaded += value?.byteLength || 0; + loaded += value?.byteLength || 0; - if (value) { - controller.enqueue(value); - } + if (value) { + controller.enqueue(value); + } - setPercentageCallback({ loaded, total }); + setPercentageCallback({ loaded, total }); - return read(); - }) - .catch((error: Error) => { - setErrorCallback(error); - reader.cancel('Cancelled'); + return read(); + }) + .catch((error: Error) => { + setErrorCallback(error); + reader.cancel('Cancelled'); - return controller.error(error); - }); - } + return controller.error(error); + }); + } - return read(); - }, - }); + return read(); + }, + }); - return new Response(stream); - }; + return new Response(stream); + }; /** - * - * @param {Blob} data - * @param {string} filename - * @param {string} mime - * @returns + * jsDownload function to handle the download process. + * @param {Blob} data + * @param {string} filename + * @param {string} mime + * @returns {boolean | NodeJS.Timeout} */ export const jsDownload = ( data: Blob, @@ -131,9 +131,9 @@ export const jsDownload = ( }; /** - * Initialise a new instance of downloader. - * @param {UseDownloaderOptions} options - * @returns UseDownloader + * useDownloader hook to handle the download process. + * @param {UseDownloaderOptions} options + * @returns {UseDownloader} */ export default function useDownloader( options: UseDownloaderOptions = {} diff --git a/src/types.ts b/src/types.ts index bb9fbda..c224401 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,6 +4,11 @@ export type ErrorMessage = { errorMessage: string; } | null; +/** useDownloader options for fetch call + * See fetch RequestInit for more details + */ +export type UseDownloaderOptions = RequestInit; + /** * Initiate the download of the specified asset from the specified url. Optionally supply timeout and overrideOptions. * @example await download('https://example.com/file.zip', 'file.zip') @@ -80,8 +85,3 @@ interface CustomNavigator extends Navigator { export interface WindowDownloaderEmbedded extends Window { navigator: CustomNavigator; } - -/** useDownloader options for fetch call - * See fetch RequestInit for more details - */ -export type UseDownloaderOptions = RequestInit; From 7b00739007fdf78b457bc22ed7d21e5e83a5a9a0 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:04:24 +0000 Subject: [PATCH 3/5] docs: update README.md [skip ci] --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dd56bd3..c4e03c4 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,10 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Sam
Sam "Betty" McKoy

🐛 Peran Osborn
Peran Osborn

🐛 🤔 Marcos
Marcos

🐛 🤔 - 9swampy
9swampy

🐛 💻 + 9swampy
9swampy

🐛 💻 + + + Dave Carlson
Dave Carlson

🤔 From 6ee52a6393f393d3241d68c7c68c491d6f8bfe65 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:04:25 +0000 Subject: [PATCH 4/5] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3c6bae9..537f2f8 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -72,6 +72,15 @@ "bug", "code" ] + }, + { + "login": "davecarlson", + "name": "Dave Carlson", + "avatar_url": "https://avatars.githubusercontent.com/u/299702?v=4", + "profile": "https://github.com/davecarlson", + "contributions": [ + "ideas" + ] } ], "contributorsPerLine": 7, @@ -82,4 +91,4 @@ "skipCi": true, "commitConvention": "angular", "commitType": "docs" -} \ No newline at end of file +} From 21c00f6223dca19afc9c79cef7d3eacd444d8ca7 Mon Sep 17 00:00:00 2001 From: Olavo Parno Date: Wed, 17 Apr 2024 12:05:04 -0300 Subject: [PATCH 5/5] chore(release): 1.2.8 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c9d1da..eafe413 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [1.2.8](https://github.com/the-bugging/react-use-downloader/compare/v1.2.6...v1.2.8) (2024-04-17) + + +### Documentation + +* update .all-contributorsrc [skip ci] ([6ee52a6](https://github.com/the-bugging/react-use-downloader/commit/6ee52a6393f393d3241d68c7c68c491d6f8bfe65)) +* update README.md [skip ci] ([7b00739](https://github.com/the-bugging/react-use-downloader/commit/7b00739007fdf78b457bc22ed7d21e5e83a5a9a0)) + ### [1.2.7](https://github.com/the-bugging/react-use-downloader/compare/v1.2.6...v1.2.7) (2024-04-16) ### [1.2.6](https://github.com/the-bugging/react-use-downloader/compare/v1.2.5...v1.2.6) (2024-04-09) diff --git a/package.json b/package.json index 93d9589..acd6395 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-use-downloader", - "version": "1.2.7", + "version": "1.2.8", "description": "Creates a download handler function and gives progress information", "author": "Olavo Parno", "license": "MIT",