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
}
--- 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