Skip to content

Commit

Permalink
v1.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
infinite-system committed Aug 20, 2024
1 parent 189090b commit 03b274e
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 76 deletions.
19 changes: 12 additions & 7 deletions docs/docs/components/usage/CounterComposablesDestructuring.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { ivue, iuse, iref, type UseComposable } from 'ivue';
* Use the ivue Utility Type: UseComposable<typeof YourComposableFunctionName>
* to get he resulting unwrapped composable properties and functions.
*/
type UseMouse = UseComposable<typeof useCustomMouse>;
type UseCustomMouse = UseComposable<typeof useCustomMouse>;
class Counter {
count = iref(0);
Expand All @@ -16,20 +16,25 @@ class Counter {
this.count++;
}
// x, y are Refs that will be unwrapped and destructured into this class
x: UseMouse['x']; // Unwrapped Ref<number> becomes -> number
y: UseMouse['y']; // Unwrapped Ref<number> becomes -> number
/**
* 'x', 'y', 'sum', 'total' are Refs that will be unwrapped to their bare raw types and destructured into the class.
* Even though unwrapped (de-Refed), they will maintain their behavior as Refs and thus will maintain reactivity
* and at the same time get destructured into this class root level scope because
* Vue 3's `reactive()` Proxy will be able to resolve those Refs internally.
*/
x: UseCustomMouse['x']; // Unwrapped Ref<number> becomes -> number
y: UseCustomMouse['y']; // Unwrapped Ref<number> becomes -> number
sum: UseMouse['sum']; // 'sum' method that will be destructured into this class on construct()
total: UseMouse['total']; // 'total' computed Ref that will also be destructured into this class on construct()
sum: UseCustomMouse['sum']; // 'sum' method that will be destructured into this class on construct()
total: UseCustomMouse['total']; // 'total' computed Ref that will also be destructured into this class on construct()
constructor() {
({
x: this.x,
y: this.y,
sum: this.sum,
total: this.total
} = iuse(useCustomMouse()));
} = iuse(useCustomMouse(5)));
}
}
Expand Down
13 changes: 11 additions & 2 deletions docs/docs/components/usage/CounterComposablesIvueDestructuring.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,23 @@ class Counter {
this.count++;
}
// x, y are Refs that will be unwrapped and destructured into this class
/**
* 'x', 'y', 'total' are Refs that will be unwrapped to their bare raw types and destructured into the class.
* Even though unwrapped (de-Refed), they will maintain their behavior as Refs and thus will maintain reactivity
* and at the same time get destructured into this class root level scope because
* Vue 3's `reactive()` Proxy will be able to resolve those Refs internally.
*/
x: CustomMouse['x']; // Unwrapped Ref<number> becomes -> number
y: CustomMouse['y']; // Unwrapped Ref<number> becomes -> number
total: CustomMouse['total']; // Unwrapped Ref<number> becomes -> number
total: CustomMouse['total']; // Unwrapped ComputedRef<number> becomes -> number
sum: CustomMouse['sum']; // Function remains a function
constructor() {
({
x: this.x,
y: this.y,
sum: this.sum,
total: this.total,
} = iuse(CustomMouse, 5));
}
Expand All @@ -33,4 +41,5 @@ const counter = ivue(Counter);
<br />
Total (computed): {{ counter.total }}
<br />
<button class="button" @click="() => counter.sum()">Click This Big Sum Button To Total X + Y</button>
</template>
21 changes: 13 additions & 8 deletions docs/docs/components/usage/classes/CustomMouse.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { useMouse } from '@vueuse/core';
import { iuse, type UseComposable } from 'ivue';
import { iref, iuse, type UseComposable } from 'ivue';

type UseMouse = UseComposable<typeof useMouse>
type UseMouse = UseComposable<typeof useMouse>;

export class CustomMouse {

x: UseMouse['x'];
y: UseMouse['y'];

constructor(public test: number) {
({ x: this.x, y: this.y } = iuse(useMouse()))
_sum = iref(0);

constructor(public requiredProp: number) {
({ x: this.x, y: this.y } = iuse(useMouse()));
}

sum() {
this._sum = this.x + this.y + this.requiredProp;
}

get total() {
return this.x + this.y;
return this._sum;
}
}
}
12 changes: 3 additions & 9 deletions docs/docs/components/usage/functions/useCustomMouse.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
import { computed, ref } from 'vue';
import { useMouse } from '@vueuse/core';

export function useCustomMouse() {
export function useCustomMouse(requiredProp: number) {
const { x, y } = useMouse();

const _sum = ref(0);

function sum() {
_sum.value = x.value + y.value;
_sum.value = x.value + y.value + requiredProp;
}

const _total = computed(() => {
// Returning without .value, not entirely correctly, but will still work in Vue template.
// This is to test the impressive IVue unwrapping capabilities of deeply nested and confusing Refs
return _sum;
});

const total = computed(() => {
// Returning without .value, not entirely correctly, but will still work in Vue template.
// This is to test the impressive IVue unwrapping capabilities of deeply nested and confusing Refs
return _total;
return _sum;
});

return {
Expand Down
22 changes: 12 additions & 10 deletions docs/docs/pages/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,49 +249,51 @@ See the highlighted sections related to destructuring composable usage.

<CounterComposablesDestructuring />

## Using Inside Composables
### Using `ivue` Composables With Destructuring

See the highlighted sections related to using `ivue` inside a composable.
See the highlighted sections related to using `ivue` based composables.

::: code-group
<<< @/components/usage/CounterInsideComposables.vue{14 vue:line-numbers}
<<< @/components/usage/CounterComposablesIvueDestructuring.vue{14 vue:line-numbers}
<<< @/components/usage/classes/CustomMouse.ts{ts:line-numbers} [classes/CustomMouse.ts]
:::

:::details For this example we initialize the component like this:

```vue
<template>
<CounterInsideComposables />
<CounterComposablesIvueDestructuring />
</template>
```

:::

<div style="font-size: 18px; font-weight: 500;">Result</div>

<CounterInsideComposables />
<CounterComposablesIvueDestructuring />

## Using `ivue` Composables

See the highlighted sections related to using `ivue` based composables.
## Using Inside Composables

See the highlighted sections related to using `ivue` inside a composable.

::: code-group
<<< @/components/usage/CounterComposablesIvueDestructuring.vue{14 vue:line-numbers}
<<< @/components/usage/CounterInsideComposables.vue{14 vue:line-numbers}
:::

:::details For this example we initialize the component like this:

```vue
<template>
<CounterComposablesIvueDestructuring />
<CounterInsideComposables />
</template>
```

:::

<div style="font-size: 18px; font-weight: 500;">Result</div>

<CounterComposablesIvueDestructuring />
<CounterInsideComposables />

## Using Computeds

Expand Down
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-vue": "^9.14.1",
"execa": "^8.0.0",
"ivue": "^1.1.21",
"ivue": "^1.2.0",
"typescript": "^4.5.4",
"vite-plugin-dynamic-import": "^1.5.0",
"vite-tsconfig-paths": "^4.3.2",
Expand Down
8 changes: 4 additions & 4 deletions docs/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2193,10 +2193,10 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==

ivue@^1.1.21:
version "1.1.21"
resolved "https://registry.yarnpkg.com/ivue/-/ivue-1.1.21.tgz#c7288973d5832dc2f8685c9be302346945b6ae33"
integrity sha512-1PY91pKuBmBh82PN2Qqk4ThehMPciaiaAcYwXlkLGDh/zbf943wGZStKrrDxiccloTssgyy3f/s6fBq9ky1oOg==
ivue@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/ivue/-/ivue-1.2.0.tgz#dfcd014c123d82f647d94bcab356179dce2ec3ff"
integrity sha512-IGhB63qOmDvp+U2mh3UnGCSstljLtyfPzQOCqqEicpHQpZIcWX/NYKDp84ykErZ0GU9Q1L9nzLH2JbVmued6+A==

js-tokens@^4.0.0:
version "4.0.0"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ivue",
"version": "1.1.21",
"version": "1.2.1",
"description": "Infinite Vue – Class Based Architecture for Vue 3",
"type": "module",
"exports": {
Expand Down
85 changes: 51 additions & 34 deletions src/ivue.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { ComputedRef, ExtractPropTypes, Ref, ToRef } from 'vue';
import { UnwrapRef, computed, reactive, ref, toRef } from 'vue';
import { computed, reactive, ref, toRef } from 'vue';
import type { Ref as DemiRef } from 'vue-demi';

/** Types */
Expand Down Expand Up @@ -44,7 +44,7 @@ export type UnwrapRefRecursively<T = any> = T extends Ref | DemiRef
: T;

/**
* Helper type for UseComposable.
* Helper type for UseComposable, unwraps any type of Vue 3 composable down to its bare types.
*/
export type UnwrapComposableReturn<T> = T extends Ref | DemiRef
? UnwrapRefRecursively<T>
Expand All @@ -57,8 +57,9 @@ export type UnwrapComposableReturn<T> = T extends Ref | DemiRef
/**
* Fully unwraps to bare value types any Vue 3 composable return definition type.
*/
export type UseComposable<T extends (...args: any[]) => any> =
UnwrapComposableReturn<ReturnType<T>>;
export type UseComposable<T extends AnyFn> = UnwrapComposableReturn<
ReturnType<T>
>;

/**
* Extracts object defined emit types by converting them to a plain interface
Expand All @@ -85,18 +86,23 @@ export type ExtendSlots<T> = PrefixKeys<T, 'before--'> &
PrefixKeys<T, 'after--'>;

/** Helper Types. */
/**
* Any JavaScript function of any type.
*/
export type AnyFn = (...args: any[]) => any;

/**
* Any JavaScript class of any type.
*/
export type AnyClass = abstract new (...args: any[]) => any;

/**
* Descriptors map.
* Descriptors map type.
*/
export type Descriptors = Map<string, PropertyDescriptor>;

/**
* Computeds hash map.
* Computeds hash map type.
*/
export type Computeds = Record<string, ComputedRef>;

Expand Down Expand Up @@ -134,10 +140,7 @@ export type IFnParameter<
/**
* Get function arguments Parmeters<F> parameter by key K
*/
export type FnParameter<
F extends (...args: any[]) => any,
K extends number
> = Parameters<F>[K];
export type FnParameter<F extends AnyFn, K extends number> = Parameters<F>[K];

/**
* Convert Union Type to Intersection Type.
Expand Down Expand Up @@ -317,31 +320,45 @@ export function getAllClassProperties(obj: object): Set<string> {
* @param val T
* @returns {UnwrapRef<T>}
*/
export function iref<T>(val?: T): UnwrapRef<T> {
return ref(val) as unknown as UnwrapRef<T>;
}
export const iref = ref as <T = any>(value?: T) => T;

/**
* Two modes of operation:
* 1. `iuse()` converts the types of a Composable / Ref to pure raw type definition.
* Returns for all properties of an object an unwrapped raw type definition,
* unwraps direct Refs & ComputedRefs as well.
*
* 2. If AnyClass is supplied into `iuse(AnyClass, ...args)` and that class's ...args,
* it returns a 'ivue(AnyClass, ...args).toRefs()` object for all properties but casts
* their types as raw (no-Ref) types to fit with reactive() structure of the
* ivue wrapper class context.
*/
export function iuse<T extends AnyClass | Object>(
val?: T,
...args: InferredArgs<T>
): T extends AnyClass ? InstanceType<T> : UnwrapComposableReturn<T> {
return isClass(val)
? ivue(
val as T extends AnyClass ? T : any,
...(args as InferredArgs<T>)
).toRefs()
: (val as unknown as UnwrapComposableReturn<T>);
* Three modes of operation:
* 1. `iuse(useComposable(arg, arg2, arg3, ...))` converts the return types of a Composable / Ref to pure raw type definition.
* Returns for all properties of an object an unwrapped raw type definition,
* unwraps direct Refs & ComputedRefs as well down to their raw types.
*
* 2. `iuse(useComposable, arg, arg2, arg3, ...)` for cleaner syntax for #1, it does exactly the same thing but
* here the TypeScript inference works for composable function arguments to assist you with intellisence,
* like they work for constructor arguments in the cause of `ivue()` core function,
* making the API cleaner to look at and make it compatible with how this function operates with classes, see #3.
*
* 3. `iuse(AnyClass, ...args)` If AnyClass is supplied and that class's arguments into `iuse(AnyClass, ...args)`,
* it returns an 'ivue(AnyClass, ...args).toRefs()` object for all properties but casts
* their types as raw (no-Ref) types to fit with reactive() structure of the ivue class context.
*/
export function iuse<T extends AnyClass | AnyFn | Object>(
classFunctionObject?: T,
...args: T extends AnyClass
? InferredArgs<T>
: T extends AnyFn
? Parameters<T extends (...args: any[]) => any ? T : any>
: any
): T extends AnyClass
? InstanceType<T>
: T extends AnyFn
? UseComposable<T>
: UnwrapComposableReturn<T> {
return typeof classFunctionObject === 'function'
? isClass(classFunctionObject)
? ivue(
classFunctionObject as T extends AnyClass ? T : any,
...(args as InferredArgs<T extends AnyClass ? T : any>)
).toRefs()
: (classFunctionObject as AnyFn)(
...(args as Parameters<T extends AnyFn ? AnyFn : any>)
)
: (classFunctionObject as unknown as UnwrapComposableReturn<T>);
}

/**
Expand All @@ -352,7 +369,7 @@ export function iuse<T extends AnyClass | Object>(
* @param computeds @see Computeds
* @returns {ExtendWithToRefs<T>['toRefs']}
*/
export function ivueToRefs<T extends AnyClass>(
function ivueToRefs<T extends AnyClass>(
vue: IVue<T>,
descriptors: Descriptors,
computeds: Computeds
Expand Down

0 comments on commit 03b274e

Please sign in to comment.