From 568324c9e8bcc08b02653342538e872de60b8c79 Mon Sep 17 00:00:00 2001 From: Sorin Muntean Date: Fri, 15 Mar 2024 16:23:04 +0100 Subject: [PATCH 1/2] `useCachedPromise`: Fix `mutate` not working when paginating beyond the first page. --- docs/utils-reference/getting-started.md | 16 ++++++++--- package.json | 2 +- src/useCachedPromise.ts | 2 +- tests/src/cached-promise-paginated.tsx | 33 ++++++++++++++--------- tests/src/fetch-paginated.tsx | 13 ++++++++- tests/src/promise-paginated.tsx | 36 ++++++++++++++++--------- 6 files changed, 71 insertions(+), 31 deletions(-) diff --git a/docs/utils-reference/getting-started.md b/docs/utils-reference/getting-started.md index 3b66b8d..4840da1 100644 --- a/docs/utils-reference/getting-started.md +++ b/docs/utils-reference/getting-started.md @@ -16,22 +16,30 @@ npm install --save @raycast/utils ## Changelog -### v1.13.1 +### v1.13.3 + +- Fixed `optimisticUpdate` not working when paginating beyond the first page when using `useCachedPromise` or other hooks that build on top of it.. + +### v1.13.2 - Added default OAuth URLs for Google, Jira, and Zoom +### v1.13.1 + +- Fixed `useFetch` type for non-paginated overload. + ### v1.13.0 - Added pagination support to `usePromise`, `useCachedPromise` and `useFetch`. ### v1.12.5 -- Add string array support for OAuth scope (Thanks @tonka3000!). +- Added string array support for OAuth scope (Thanks @tonka3000!). ### v1.12.4 -- Add `tokenResponseParser` and `tokenRefreshResponseParser` in the options of `OAuthService`. -- Fix built-in Slack OAuthServices. +- Added `tokenResponseParser` and `tokenRefreshResponseParser` in the options of `OAuthService`. +- Fixed built-in Slack OAuthServices. ### v1.12.3 diff --git a/package.json b/package.json index aafc076..c85b28f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@raycast/utils", - "version": "1.13.2", + "version": "1.13.3", "description": "Set of utilities to streamline building Raycast extensions", "author": "Raycast Technologies Ltd.", "homepage": "https://developers.raycast.com/utils-reference", diff --git a/src/useCachedPromise.ts b/src/useCachedPromise.ts index 24a3ed7..6ea37ac 100644 --- a/src/useCachedPromise.ts +++ b/src/useCachedPromise.ts @@ -263,7 +263,7 @@ export function useCachedPromise< data: returnedData, isLoading: state.isLoading, error: state.error, - mutate, + mutate: paginationArgsRef.current && paginationArgsRef.current.page > 0 ? _mutate : mutate, pagination, revalidate, }; diff --git a/tests/src/cached-promise-paginated.tsx b/tests/src/cached-promise-paginated.tsx index b94f3e8..4760851 100644 --- a/tests/src/cached-promise-paginated.tsx +++ b/tests/src/cached-promise-paginated.tsx @@ -6,7 +6,7 @@ import { setTimeout } from "timers/promises"; export default function Command() { const [searchText, setSearchText] = useState(""); - const { isLoading, data, pagination, revalidate } = useCachedPromise( + const { isLoading, data, mutate, pagination, revalidate } = useCachedPromise( (text: string) => async (options) => { await setTimeout(500); const data = items(text, options.page); @@ -20,18 +20,27 @@ export default function Command() { ); return ( - - revalidate()} /> - - } - > + {data.map((item) => ( - + + revalidate()} /> + { + mutate(setTimeout(1000), { + optimisticUpdate: () => { + return [item]; + }, + }); + }} + /> + + } + /> ))} ); diff --git a/tests/src/fetch-paginated.tsx b/tests/src/fetch-paginated.tsx index 7f1d8d2..dcad2cf 100644 --- a/tests/src/fetch-paginated.tsx +++ b/tests/src/fetch-paginated.tsx @@ -1,6 +1,7 @@ import { ActionPanel, Action, Icon, Image, List, Grid } from "@raycast/api"; import { useFetch } from "@raycast/utils"; import { useState } from "react"; +import { setTimeout } from "timers/promises"; type SearchResult = { companies: Company[]; @@ -39,7 +40,7 @@ function getSearchParams(searchText: string, page: number) { export default function Command() { const [searchText, setSearchText] = useState(""); - const { isLoading, pagination, data, revalidate } = useFetch( + const { isLoading, pagination, data, mutate, revalidate } = useFetch( (pagination) => "https://api.ycombinator.com/v0.1/companies?" + getSearchParams(searchText, pagination.page + 1).toString(), { @@ -64,6 +65,16 @@ export default function Command() { actions={ revalidate()} /> + { + mutate(setTimeout(1000), { + optimisticUpdate: () => { + return [company]; + }, + }); + }} + /> } /> diff --git a/tests/src/promise-paginated.tsx b/tests/src/promise-paginated.tsx index acf38d3..797fd87 100644 --- a/tests/src/promise-paginated.tsx +++ b/tests/src/promise-paginated.tsx @@ -1,11 +1,12 @@ import { List, ActionPanel, Action } from "@raycast/api"; import { usePromise } from "@raycast/utils"; import { useState } from "react"; +import { setTimeout as setTimeoutAsync } from "timers/promises"; export default function Command() { const [searchText, setSearchText] = useState(""); - const { isLoading, data, revalidate, pagination } = usePromise( + const { isLoading, data, revalidate, mutate, pagination } = usePromise( (text: string) => async (options) => { await sleep(500); const data = items(text, options.page); @@ -15,17 +16,28 @@ export default function Command() { ); return ( - - revalidate()} /> - - } - > - {data?.map((item) => )} + + {data?.map((item) => ( + + revalidate()} /> + { + mutate(setTimeoutAsync(1000), { + optimisticUpdate: () => { + return [item]; + }, + }); + }} + /> + + } + /> + ))} ); } From 728c8d24f5bc11635fce869fdc570343c260617f Mon Sep 17 00:00:00 2001 From: Sorin Muntean Date: Mon, 18 Mar 2024 10:05:39 +0100 Subject: [PATCH 2/2] `useFetch`: Fix `mapResult` being required when not using paginated overload. --- docs/utils-reference/getting-started.md | 7 ++++--- src/useFetch.ts | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/utils-reference/getting-started.md b/docs/utils-reference/getting-started.md index 4840da1..1a9ab66 100644 --- a/docs/utils-reference/getting-started.md +++ b/docs/utils-reference/getting-started.md @@ -19,6 +19,7 @@ npm install --save @raycast/utils ### v1.13.3 - Fixed `optimisticUpdate` not working when paginating beyond the first page when using `useCachedPromise` or other hooks that build on top of it.. +- Fixed `useFetch` type requiring `mapResult` for non-paginated overload. ### v1.13.2 @@ -34,12 +35,12 @@ npm install --save @raycast/utils ### v1.12.5 -- Added string array support for OAuth scope (Thanks @tonka3000!). +- Add string array support for OAuth scope (Thanks @tonka3000!). ### v1.12.4 -- Added `tokenResponseParser` and `tokenRefreshResponseParser` in the options of `OAuthService`. -- Fixed built-in Slack OAuthServices. +- Add `tokenResponseParser` and `tokenRefreshResponseParser` in the options of `OAuthService`. +- Fix built-in Slack OAuthServices. ### v1.12.3 diff --git a/src/useFetch.ts b/src/useFetch.ts index cab29d0..fe26fcb 100644 --- a/src/useFetch.ts +++ b/src/useFetch.ts @@ -131,7 +131,7 @@ export function useFetch( url: RequestInfo, options?: RequestInit & { - mapResult: (result: V) => { data: T; hasMore?: boolean }; + mapResult?: (result: V) => { data: T; hasMore?: boolean }; parseResponse?: (response: Response) => Promise; } & Omit Promise, U>, "abortable">, ): UseCachedPromiseReturnType & { pagination: undefined };