Content-Length: 8908 | pFad | http://github.com/vueuse/vueuse/pull/4803.patch

thub.com From 05ce3c88513b20b0572a392e90237fa1e22baf2a Mon Sep 17 00:00:00 2001 From: Arkeviz Date: Sun, 8 Jun 2025 02:13:56 +0300 Subject: [PATCH 1/3] feat(useAsyncState): add isomorphic destructure using `makeDestructurable` utility and some tests for it --- packages/core/useAsyncState/index.test.ts | 18 +++++++- packages/core/useAsyncState/index.ts | 52 +++++++++++++++++------ 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/packages/core/useAsyncState/index.test.ts b/packages/core/useAsyncState/index.test.ts index e259d28c866..307227ca35e 100644 --- a/packages/core/useAsyncState/index.test.ts +++ b/packages/core/useAsyncState/index.test.ts @@ -8,7 +8,7 @@ describe('useAsyncState', () => { }) const p1 = (num = 1) => { - return new Promise((resolve) => { + return new Promise((resolve) => { setTimeout(() => { resolve(num) }, 50) @@ -83,4 +83,20 @@ describe('useAsyncState', () => { const { execute } = useAsyncState(p2, '0', { throwError: true, immediate: false }) await expect(execute()).rejects.toThrowError('error') }) + + describe('useAsyncState with array destructing', () => { + it('should work', async () => { + const [state, execute] = useAsyncState(p1, 0, { immediate: false }) + expect(state.value).toBe(0) + await execute(0, 2) + expect(state.value).toBe(2) + }) + + it('should work with error', async () => { + const [_state, execute, _isLoading, _isReady, error] = useAsyncState(p2, '0', { immediate: false }) + expect(error.value).toBeUndefined() + await execute() + expect(error.value).toBeInstanceOf(Error) + }) + }) }) diff --git a/packages/core/useAsyncState/index.ts b/packages/core/useAsyncState/index.ts index ec1a4f2786a..e884ac5ed90 100644 --- a/packages/core/useAsyncState/index.ts +++ b/packages/core/useAsyncState/index.ts @@ -1,8 +1,8 @@ import type { Ref, ShallowRef, UnwrapRef } from 'vue' -import { noop, promiseTimeout, until } from '@vueuse/shared' +import { makeDestructurable, noop, promiseTimeout, until } from '@vueuse/shared' import { ref as deepRef, shallowRef } from 'vue' -export interface UseAsyncStateReturnBase { +export interface UseAsyncStateReturnBase extends Record { state: Shallow extends true ? Ref : Ref> isReady: Ref isLoading: Ref @@ -10,9 +10,23 @@ export interface UseAsyncStateReturnBase Promise } +type UseAsyncStatePromiseLike = PromiseLike> + +export type UseAsyncStateReturnArray = [ + state: UseAsyncStateReturnBase['state'], + execute: UseAsyncStateReturnBase['execute'], + isLoading: UseAsyncStateReturnBase['isLoading'], + isReady: UseAsyncStateReturnBase['isReady'], + error: UseAsyncStateReturnBase['error'], +] + export type UseAsyncStateReturn = UseAsyncStateReturnBase - & PromiseLike> + & UseAsyncStateReturnArray + +export type UseAsyncStateReturnWithThen = + UseAsyncStateReturn + & UseAsyncStatePromiseLike export interface UseAsyncStateOptions { /** @@ -82,7 +96,7 @@ export function useAsyncState | ((...args: Params) => Promise), initialState: Data, options?: UseAsyncStateOptions, -): UseAsyncStateReturn { +): UseAsyncStateReturnWithThen { const { immediate = true, delay = 0, @@ -141,18 +155,30 @@ export function useAsyncState = [ + state as Shallow extends true ? ShallowRef : Ref>, + execute, + isLoading, + isReady, + error, + ] + + type UseAsyncStateThenParams = Parameters['then']> + type UseAsyncStateThenReturn = ReturnType['then']> + function then(onFulfilled: UseAsyncStateThenParams[0], onRejected: UseAsyncStateThenParams[1]): UseAsyncStateThenReturn { + return waitUntilIsLoaded() + .then(onFulfilled, onRejected) + } function waitUntilIsLoaded() { - return new Promise>((resolve, reject) => { - until(isLoading).toBe(false).then(() => resolve(shell)).catch(reject) + return new Promise>((resolve, reject) => { + until(isLoading).toBe(false).then( + () => resolve( + makeDestructurable(shell, arrayShell), + ), + ).catch(reject) }) } - return { - ...shell, - then(onFulfilled, onRejected) { - return waitUntilIsLoaded() - .then(onFulfilled, onRejected) - }, - } + return makeDestructurable({ ...shell, then }, arrayShell) as UseAsyncStateReturnWithThen } From aa4f1f5eb20f4b65e71067722e2670144fe8e3dd Mon Sep 17 00:00:00 2001 From: Arkeviz Date: Sun, 8 Jun 2025 02:16:26 +0300 Subject: [PATCH 2/3] docs(useAsyncState): add array destructure example and paragraph about this possibility --- packages/core/useAsyncState/index.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/core/useAsyncState/index.md b/packages/core/useAsyncState/index.md index 80cb7e70f7d..d8e77498b74 100644 --- a/packages/core/useAsyncState/index.md +++ b/packages/core/useAsyncState/index.md @@ -6,16 +6,27 @@ category: State Reactive async state. Will not block your setup function and will trigger changes once the promise is ready. The state is a `shallowRef` by default. +Also supports isomorphic destructuring via [makeDestructurable](https://vueuse.org/shared/makeDestructurable) utility. + ## Usage ```ts import { useAsyncState } from '@vueuse/core' import axios from 'axios' +// Object destructure example const { state, isReady, isLoading } = useAsyncState( axios .get('https://jsonplaceholder.typicode.com/todos/1') .then(t => t.data), { id: null }, ) + +// Array destructure example (in right order) +const [state, execute, isLoading, isReady, error] = useAsyncState( + axios + .get('https://jsonplaceholder.typicode.com/todos/1') + .then(t => t.data), + { id: null }, +) ``` From f0d4f7f86f8e1d0cb63ee4bb4a52228396e44fa4 Mon Sep 17 00:00:00 2001 From: Arkeviz Date: Sun, 8 Jun 2025 12:06:01 +0300 Subject: [PATCH 3/3] fix(useAsyncState): rename useAsyncState return type --- packages/core/useAsyncState/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/useAsyncState/index.ts b/packages/core/useAsyncState/index.ts index e884ac5ed90..05b58b50ded 100644 --- a/packages/core/useAsyncState/index.ts +++ b/packages/core/useAsyncState/index.ts @@ -24,7 +24,7 @@ export type UseAsyncStateReturn & UseAsyncStateReturnArray -export type UseAsyncStateReturnWithThen = +export type UseAsyncStateReturnWithPromiseLike = UseAsyncStateReturn & UseAsyncStatePromiseLike @@ -96,7 +96,7 @@ export function useAsyncState | ((...args: Params) => Promise), initialState: Data, options?: UseAsyncStateOptions, -): UseAsyncStateReturnWithThen { +): UseAsyncStateReturnWithPromiseLike { const { immediate = true, delay = 0, @@ -180,5 +180,5 @@ export function useAsyncState + return makeDestructurable({ ...shell, then }, arrayShell) as UseAsyncStateReturnWithPromiseLike }








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/vueuse/vueuse/pull/4803.patch

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy