Skip to content

Commit

Permalink
Merge pull request #2 from leynier/feat/wrapped-all-promises-function…
Browse files Browse the repository at this point in the history
…s-recursively-recursively-to-the-root-prototype

feat: wrapped all promises functions recursively recursively to the root prototype
  • Loading branch information
leynier authored Nov 23, 2024
2 parents 138cd1d + 29e142b commit 4900175
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 15 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nuxt-use-async-data-wrapper",
"version": "1.1.0",
"version": "1.2.0",
"description": "A utility to wrap Promise-returning functions with useAsyncData for Nuxt",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
14 changes: 7 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,26 +88,26 @@ import { ref } from 'vue';
const id = ref(1);
// Function without arguments
const { data: dataList, pending: listPending, error: listError } = wrappedService.fetchData();
const { data: dataList, status: listStatus, error: listError } = wrappedService.fetchData();
// Function with arguments
const { data: itemData, pending: itemPending, error: itemError } = wrappedService.getItem(() => [id.value]);
const { data: itemData, status: itemStatus, error: itemError } = wrappedService.getItem(() => [id.value]);
// Reactivity: when id.value changes, itemData updates automatically
</script>
<template>
<div>
<h1>Data List</h1>
<div v-if="listPending">Loading...</div>
<div v-if="listStatus === 'pending'">Loading...</div>
<div v-else-if="listError">Error: {{ listError.message }}</div>
<div v-else>
<pre>{{ dataList }}</pre>
</div>
<h1>Item Data (ID: {{ id }})</h1>
<input v-model="id" type="number" min="1" />
<div v-if="itemPending">Loading...</div>
<div v-if="itemStatus === 'pending'">Loading...</div>
<div v-else-if="itemError">Error: {{ itemError.message }}</div>
<div v-else>
<pre>{{ itemData }}</pre>
Expand Down Expand Up @@ -160,7 +160,7 @@ async function fetchData() {
const wrappedService = useAsyncDataWrapper({ fetchData });

// Use in a component
const { data, pending, error } = wrappedService.fetchData();
const { data, status, error } = wrappedService.fetchData();
```

### Function With Arguments
Expand All @@ -179,7 +179,7 @@ import { ref } from 'vue';

const id = ref(1);

const { data, pending, error } = wrappedService.getItem(() => [id.value]);
const { data, status, error } = wrappedService.getItem(() => [id.value]);

// When id.value changes, data is automatically refreshed
```
Expand All @@ -193,7 +193,7 @@ You can pass options to `useAsyncData` through the wrapped functions to control
### Example with Options

```typescript
const { data, pending, error } = wrappedService.fetchData({
const { data, status, error } = wrappedService.fetchData({
lazy: true,
server: false,
default: () => [],
Expand Down
23 changes: 16 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ export type AsyncDataWrapper<T> = {
? /**
* Functions without arguments.
* @param options - Optional AsyncDataOptions to configure useAsyncData.
* @returns AsyncDataResult containing the data, pending state, and error.
* @returns AsyncDataResult containing the data, status state, and error.
*/
(options?: AsyncDataOptions<R>) => AsyncDataResult<R>
: /**
* Functions with arguments.
* @param argsSupplier - A function that returns the arguments array for the original function.
* @param options - Optional AsyncDataOptions to configure useAsyncData.
* @returns AsyncDataResult containing the data, pending state, and error.
* @returns AsyncDataResult containing the data, status state, and error.
*/
(
argsSupplier: () => Args,
Expand Down Expand Up @@ -65,12 +65,21 @@ export function useAsyncDataWrapper<T extends Record<string, any>>(
obj: T,
): AsyncDataWrapper<T> {
const composable = {} as AsyncDataWrapper<T>;
const proto = Object.getPrototypeOf(obj);

// Get function names from the object's prototype, excluding the constructor
const functionNames = Object.getOwnPropertyNames(proto).filter(
key => key !== 'constructor' && typeof obj[key] === 'function',
);
// Get all function names from the object and its prototypes
const functionNameSet = new Set<string>();
let currentObj = obj;
while (currentObj && currentObj !== Object.prototype) {
const keys = Object.getOwnPropertyNames(currentObj);
for (const key of keys) {
// Exclude constructor and non-function properties
if (key !== 'constructor' && typeof currentObj[key] === 'function') {
functionNameSet.add(key);
}
}
currentObj = Object.getPrototypeOf(currentObj);
}
const functionNames = Array.from(functionNameSet);

for (const key of functionNames) {
// Bind the function to preserve context
Expand Down

0 comments on commit 4900175

Please sign in to comment.