Skip to content

Commit

Permalink
Merge pull request #7 from veactjs/dev
Browse files Browse the repository at this point in the history
v1.0.0
  • Loading branch information
surmon-china authored Sep 5, 2024
2 parents 6f6151a + d867e84 commit 94b0e9c
Show file tree
Hide file tree
Showing 24 changed files with 610 additions and 1,298 deletions.
9 changes: 2 additions & 7 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.detectIndentation": false,
"editor.formatOnSave": true,
"editor.formatOnType": true,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit"
},
"typescript.tsdk": "node_modules/typescript/lib"
"editor.formatOnSave": true
}
3 changes: 3 additions & 0 deletions dev/Readonly.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ export const Component: React.FC = () => {
<div>
<mark>renderCount: {renderCount}</mark>
<pre>shallowReadonlyObject = {JSON.stringify(shallowReadonlyObject, null, 2)}</pre>
{/* @ts-ignore */}
<button onClick={() => shallowReadonlyObject.data++}>shallowReadonlyObject.data++</button>
<button onClick={() => shallowReadonlyObject.nested.data++}>shallowReadonlyObject.nested.data++</button>
<hr />
<pre>readonlyObject = {JSON.stringify(readonlyObject, null, 2)}</pre>
{/* @ts-ignore */}
<button onClick={() => readonlyObject.data++}>readonlyObject.data++</button>
{/* @ts-ignore */}
<button onClick={() => readonlyObject.nested.data++}>readonlyObject.nested.data++</button>
</div>
)
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "veact",
"version": "1.0.0-beta.2",
"version": "1.0.0",
"description": "Mutable state enhancer library for React by @vue/reactivity",
"keywords": [
"React",
Expand Down Expand Up @@ -50,7 +50,7 @@
"react-dom": "^16.8.0 || ^17 || ^18 || ^19"
},
"dependencies": {
"@vue/reactivity": "^3.5.0-beta.2"
"@vue/reactivity": ">=3.5"
},
"devDependencies": {
"@eslint/js": "^9.x",
Expand All @@ -64,14 +64,14 @@
"eslint-config-prettier": "^9.x",
"eslint-plugin-prettier": "^5.x",
"globals": "^15.9.0",
"jsdom": "^24.x",
"happy-dom": "^15.x",
"prettier": "^3.x",
"react": "^18.x",
"react-dom": "^18.x",
"typescript": "^5.5.4",
"typescript-eslint": "^8.x",
"vite": "^5.x",
"vite-plugin-dts": "^4.0.3",
"vite-plugin-dts": "^4.1.0",
"vitest": "^2.x"
}
}
1,018 changes: 335 additions & 683 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

45 changes: 0 additions & 45 deletions src/_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,3 @@ export type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N

export const increment = (s: number) => s + 1
export const useForceUpdate = () => useReducer(increment, 0)[1]

// compare whether a value has changed, accounting for NaN.
export const hasChanged = (value: any, oldValue: any): boolean => {
return value !== oldValue && (value === value || oldValue === oldValue)
}

export const isArray = Array.isArray
export const objectToString = Object.prototype.toString
export const toTypeString = (value: unknown): string => {
return objectToString.call(value)
}
export const isMap = (value: unknown): value is Map<any, any> => {
return toTypeString(value) === '[object Map]'
}
export const isSet = (value: unknown): value is Set<any> => {
return toTypeString(value) === '[object Set]'
}
export const isDate = (value: unknown): value is Date => {
return value instanceof Date
}
export const isFunction = (value: unknown): value is (...args: any[]) => any => {
return typeof value === 'function'
}
export const isString = (value: unknown): value is string => {
return typeof value === 'string'
}
export const isSymbol = (value: unknown): value is symbol => {
return typeof value === 'symbol'
}
export const isObject = (value: unknown): value is Record<any, any> => {
return value !== null && typeof value === 'object'
}
export const isPlainObject = (value: unknown): value is object => {
return toTypeString(value) === '[object Object]'
}
export const isPromise = <T = any>(value: unknown): value is Promise<T> => {
return isObject(value) && isFunction(value.then) && isFunction(value.catch)
}

export const removeArrayItem = <T>(array: T[], element: T) => {
const i = array.indexOf(element)
if (i > -1) {
array.splice(i, 1)
}
}
14 changes: 7 additions & 7 deletions src/computed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
*/

import { useState as useReactState } from 'react'
import { useWatch } from './watch/watch'
import { useForceUpdate } from './_utils'
import { computed as vComputed } from '@vue/reactivity'
import { computed as vueComputed } from '@vue/reactivity'
import type {
ComputedGetter,
DebuggerOptions,
ComputedRef,
WritableComputedOptions,
ComputedGetter,
WritableComputedRef,
WritableComputedOptions,
DebuggerOptions,
} from '@vue/reactivity'
import { useWatch } from './watch'
import { useForceUpdate } from './_utils'

/**
* Takes a getter function and returns a readonly reactive ref object for the
Expand Down Expand Up @@ -55,7 +55,7 @@ export function useComputed<T, S = T>(
debugOptions?: DebuggerOptions,
): WritableComputedRef<T, S>
export function useComputed(arg1: any, arg2: any) {
const [value] = useReactState(() => vComputed(arg1, arg2))
const [value] = useReactState(() => vueComputed(arg1, arg2))
const forceUpdate = useForceUpdate()
useWatch(value, forceUpdate)
return value
Expand Down
6 changes: 3 additions & 3 deletions src/effectScope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { useState as useReactState, useRef as useReactRef, useCallback as useReactCallback } from 'react'
import { effectScope } from '@vue/reactivity'
import { effectScope as vueEffectScope } from '@vue/reactivity'
import { ArgumentTypes } from './_utils'

/**
Expand All @@ -16,9 +16,9 @@ import { ArgumentTypes } from './_utils'
* @param detached - Can be used to create a "detached" effect scope.
* @see {@link https://vuejs.org/api/reactivity-advanced.html#effectscope Vue `effectScope()`}
*/
export function useEffectScope(...args: ArgumentTypes<typeof effectScope>) {
export function useEffectScope(...args: ArgumentTypes<typeof vueEffectScope>) {
const hasRun = useReactRef(false)
const [scope] = useReactState(() => effectScope(...args))
const [scope] = useReactState(() => vueEffectScope(...args))
const originalRunRef = useReactRef(scope.run)
const runFn = useReactCallback(<T>(fn: () => T) => {
if (!hasRun.current) {
Expand Down
12 changes: 5 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

// redirect all APIs from @vue/reactivity
export * from '@vue/reactivity'
export { watch as baseWatch } from '@vue/reactivity'

// lifecycle hooks
export { onMounted, onUpdated, onBeforeUnmount } from './lifecycle'
Expand All @@ -22,15 +23,12 @@ export { useReadonly, useShallowReadonly } from './readonly'
export { useComputed } from './computed'

// watch and hooks
export { watch, useWatch } from './watch/watch'
export type { WatchOptions, WatchSource, MultiWatchSources, WatchCallback } from './watch/watch'
export { watch, useWatch } from './watch'
export type { WatchOptions, MultiWatchSources } from './watch'

// watchEffect and hooks
export { watchEffect, useWatchEffect } from './watch/watchEffect'
export type { WatchEffect, WatchEffectOptions } from './watch/watchEffect'

// watch handle
export type { WatchStopHandle, WatchHandle } from './watch/type'
export { watchEffect, useWatchEffect } from './watchEffect'
export type { WatchEffectOptions } from './watchEffect'

// effectScope hooks
export { useEffectScope } from './effectScope'
Expand Down
10 changes: 5 additions & 5 deletions src/reactive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
*/

import { useState as useReactState } from 'react'
import { useWatch } from './watch/watch'
import { useForceUpdate } from './_utils'
import { reactive as vReactive, shallowReactive as vShallowReactive } from '@vue/reactivity'
import { reactive as vueReactive, shallowReactive as vueShallowReactive } from '@vue/reactivity'
import type { Reactive, ShallowReactive } from '@vue/reactivity'
import { useWatch } from './watch'
import { useForceUpdate } from './_utils'

/**
* Returns a reactive proxy of the object.
Expand All @@ -26,7 +26,7 @@ import type { Reactive, ShallowReactive } from '@vue/reactivity'
*/
export function useReactive<T extends object>(target: T): Reactive<T>
export function useReactive(target: object) {
const [value] = useReactState(() => vReactive(target))
const [value] = useReactState(() => vueReactive(target))
const forceUpdate = useForceUpdate()
useWatch(value, forceUpdate)
return value
Expand Down Expand Up @@ -63,7 +63,7 @@ export function useReactive(target: object) {
* ```
*/
export function useShallowReactive<T extends object>(target: T): ShallowReactive<T> {
const [value] = useReactState(() => vShallowReactive(target))
const [value] = useReactState(() => vueShallowReactive(target))
const forceUpdate = useForceUpdate()
useWatch(value, forceUpdate)
return value
Expand Down
2 changes: 1 addition & 1 deletion src/reactivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @author Surmon <https://github.com/surmon-china>
*/

import { useWatch } from './watch/watch'
import { useWatch } from './watch'
import { useForceUpdate } from './_utils'

/**
Expand Down
10 changes: 5 additions & 5 deletions src/readonly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
*/

import { useState as useReactState } from 'react'
import { useWatch } from './watch/watch'
import { useForceUpdate } from './_utils'
import { readonly as vReadonly, shallowReadonly as vShallowReadonly } from '@vue/reactivity'
import { readonly as vueReadonly, shallowReadonly as vueShallowReadonly } from '@vue/reactivity'
import type { DeepReadonly, UnwrapNestedRefs } from '@vue/reactivity'
import { useWatch } from './watch'
import { useForceUpdate } from './_utils'

/**
* Takes an object (reactive or plain) or a ref and returns a readonly proxy to
Expand Down Expand Up @@ -38,7 +38,7 @@ import type { DeepReadonly, UnwrapNestedRefs } from '@vue/reactivity'
* ```
*/
export function useReadonly<T extends object>(target: T): DeepReadonly<UnwrapNestedRefs<T>> {
const [value] = useReactState(() => vReadonly(target))
const [value] = useReactState(() => vueReadonly(target))
const forceUpdate = useForceUpdate()
useWatch(value, forceUpdate)
return value
Expand Down Expand Up @@ -78,7 +78,7 @@ export function useReadonly<T extends object>(target: T): DeepReadonly<UnwrapNes
* ```
*/
export function useShallowReadonly<T extends object>(target: T): Readonly<T> {
const [value] = useReactState(() => vShallowReadonly(target))
const [value] = useReactState(() => vueShallowReadonly(target))
const forceUpdate = useForceUpdate()
useWatch(value, forceUpdate)
return value
Expand Down
24 changes: 12 additions & 12 deletions src/ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
*/

import { useState as useReactState } from 'react'
import { useForceUpdate, IfAny } from './_utils'
import { useWatch } from './watch/watch'
import { ref as vRef, shallowRef as vShallowRef, customRef as vCustomRef } from '@vue/reactivity'
import { ref as vueRef, shallowRef as vueShallowRef, customRef as vueCustomRef } from '@vue/reactivity'
import type { Ref, UnwrapRef, ShallowRef, CustomRefFactory } from '@vue/reactivity'
import { useForceUpdate, IfAny } from './_utils'
import { useWatch } from './watch'

/**
* Takes an inner value and returns a reactive and mutable ref object, which
Expand All @@ -30,10 +30,10 @@ export function useRef<T>(
): [T] extends [Ref] ? IfAny<T, Ref<T>, T> : Ref<UnwrapRef<T>, UnwrapRef<T> | T>
export function useRef<T = any>(): Ref<T | undefined>
export function useRef(initValue?: unknown) {
const [refObj] = useReactState(() => vRef(initValue))
const [refObject] = useReactState(() => vueRef(initValue))
const forceUpdate = useForceUpdate()
useWatch(refObj, forceUpdate, { deep: true })
return refObj as unknown as any
useWatch(refObject, forceUpdate, { deep: true })
return refObject as unknown as any
}

/**
Expand All @@ -56,10 +56,10 @@ export function useShallowRef<T>(
): Ref extends T ? (T extends Ref ? IfAny<T, ShallowRef<T>, T> : ShallowRef<T>) : ShallowRef<T>
export function useShallowRef<T = any>(): ShallowRef<T | undefined>
export function useShallowRef(initValue?: unknown) {
const [sRefObj] = useReactState(() => vShallowRef(initValue))
const [shallowRefObject] = useReactState(() => vueShallowRef(initValue))
const forceUpdate = useForceUpdate()
useWatch(sRefObj, forceUpdate)
return sRefObj
useWatch(shallowRefObject, forceUpdate)
return shallowRefObject
}

/**
Expand All @@ -70,8 +70,8 @@ export function useShallowRef(initValue?: unknown) {
* @see {@link https://vuejs.org/api/reactivity-advanced.html#customref Vue `customRef()`}
*/
export function useCustomRef<T>(factory: CustomRefFactory<T>): Ref<T> {
const [cRefObj] = useReactState(() => vCustomRef(factory))
const [customRefObject] = useReactState(() => vueCustomRef(factory))
const forceUpdate = useForceUpdate()
useWatch(cRefObj, forceUpdate)
return cRefObj
useWatch(customRefObject, forceUpdate)
return customRefObject
}
Loading

0 comments on commit 94b0e9c

Please sign in to comment.