From df9612ac2d28c0efe107757fb72b881005ab1802 Mon Sep 17 00:00:00 2001 From: Maik Marschner Date: Tue, 24 Sep 2024 17:56:06 +0200 Subject: [PATCH 1/4] chore: remove yarn lockfile as this project uses npm --- README.md | 15 +- yarn.lock | 2527 ----------------------------------------------------- 2 files changed, 8 insertions(+), 2534 deletions(-) delete mode 100644 yarn.lock diff --git a/README.md b/README.md index e33ce35..81cb1b2 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ const Changelog = () => {

{changelog.title}

@@ -53,7 +53,10 @@ const Changelog = () => { ### Component ```tsx -import { ChangelogContainer, MinimalChangelogList, } from '@wertarbyte/updatehive-react'; +import { + ChangelogContainer, + MinimalChangelogList, +} from '@wertarbyte/updatehive-react'; return ( Date: Tue, 24 Sep 2024 18:05:14 +0200 Subject: [PATCH 2/4] fix: reload changelogs if the config changes --- lib/changelog.hook.ts | 73 +++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/lib/changelog.hook.ts b/lib/changelog.hook.ts index 2a30ad3..2d85945 100644 --- a/lib/changelog.hook.ts +++ b/lib/changelog.hook.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { Changelog, UpdateHiveConfig, @@ -27,47 +27,46 @@ export function useChangelogs(config: UpdateHiveConfig): UpdateHiveHookResult { const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(); - const fetchData = async () => { - setIsLoading(true); + const requestURL = useMemo(() => buildRequestURL(config), [config]); + const apiKey = config.connection.API_KEY; - const requestURL = buildRequestURL(config); - - try { - const result = await fetch(requestURL, { - headers: { - Authorization: `Bearer ${config.connection.API_KEY}`, - Accept: 'application/vnd.wertarbyte.changelog.v1+json', - }, - }); - - if (!result.ok) { - const error = await result.json(); - throw new Error(error.message); - } + useEffect(() => { + void (async () => { + setIsLoading(true); - const resultData: Changelog[] | undefined = await result.json(); + try { + const result = await fetch(requestURL, { + headers: { + Authorization: `Bearer ${apiKey}`, + Accept: 'application/vnd.wertarbyte.changelog.v1+json', + }, + }); - if (resultData) { - setData( - resultData.sort((a, b) => Date.parse(b.releaseDate) - Date.parse(a.releaseDate)), - ); + if (!result.ok) { + const error = await result.json(); + throw new Error(error.message); + } + const resultData: Changelog[] | undefined = await result.json(); + if (resultData) { + setData( + resultData.sort( + (a, b) => Date.parse(b.releaseDate) - Date.parse(a.releaseDate), + ), + ); + } else { + setError('Did not receive a changelog.'); + } + } catch (error) { + if (error instanceof Error) { + setError(error.message); + } else { + setError('An unknown error occurred.'); + } } - } catch (error) { - if (error instanceof Error) { - setError(error.message); - } else { - setError('An unknown error occurred.'); - } - } - - setIsLoading(false); - }; - useEffect(() => { - void fetchData(); - // Explicitly set to empty array to avoid multiple requests. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + setIsLoading(false); + })(); + }, [apiKey, requestURL]); return { loading: isLoading, From 2cc6083d4bd30dc791389c6935ddd801895f8f28 Mon Sep 17 00:00:00 2001 From: Maik Marschner Date: Tue, 24 Sep 2024 18:08:30 +0200 Subject: [PATCH 3/4] fix: abort the request when unmounting the component or changing the config while the changelog is loading --- lib/changelog.hook.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/changelog.hook.ts b/lib/changelog.hook.ts index 2d85945..32f01da 100644 --- a/lib/changelog.hook.ts +++ b/lib/changelog.hook.ts @@ -31,6 +31,8 @@ export function useChangelogs(config: UpdateHiveConfig): UpdateHiveHookResult { const apiKey = config.connection.API_KEY; useEffect(() => { + const ac = new AbortController(); + void (async () => { setIsLoading(true); @@ -40,6 +42,7 @@ export function useChangelogs(config: UpdateHiveConfig): UpdateHiveHookResult { Authorization: `Bearer ${apiKey}`, Accept: 'application/vnd.wertarbyte.changelog.v1+json', }, + signal: ac.signal, }); if (!result.ok) { @@ -58,6 +61,9 @@ export function useChangelogs(config: UpdateHiveConfig): UpdateHiveHookResult { } } catch (error) { if (error instanceof Error) { + if (error.name === 'AbortError') { + return; // fetch aborted, ie. unmounted component or config changed + } setError(error.message); } else { setError('An unknown error occurred.'); @@ -66,6 +72,10 @@ export function useChangelogs(config: UpdateHiveConfig): UpdateHiveHookResult { setIsLoading(false); })(); + + return () => { + ac.abort(); + }; }, [apiKey, requestURL]); return { From fa8fc9913e07d74a17bdab1d609756bc90f25b42 Mon Sep 17 00:00:00 2001 From: Maik Marschner Date: Tue, 24 Sep 2024 18:08:51 +0200 Subject: [PATCH 4/4] fix: use proper tsdoc for the config type --- lib/changelog.types.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/changelog.types.ts b/lib/changelog.types.ts index e20fe88..45c6778 100644 --- a/lib/changelog.types.ts +++ b/lib/changelog.types.ts @@ -1,21 +1,25 @@ /** * Configuration to retrieve changelogs from UpdateHive. - * - * @param connection - * API_KEY: API_KEY to access UpdateHive public REST API. - * url: Override the default URL to UpdateHive API. - * - * @param changelogs - * product: Product ID to retrieve changelogs for. - * onlyLast: Retrieve only the last changelog. */ export type UpdateHiveConfig = { connection: { + /** + * API_KEY to access UpdateHive public REST API. + */ API_KEY: string; + /** + * Override the default URL to UpdateHive API. + */ url?: string; }; changelogs: { + /** + * Product ID to retrieve changelogs for. + */ product: string; + /** + * Retrieve only the last changelog. + */ onlyLast?: boolean; }; };