-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6f6151a
commit 56b3ab6
Showing
17 changed files
with
506 additions
and
385 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/** | ||
* @module veact.watch | ||
* @author Surmon <https://github.com/surmon-china> | ||
*/ | ||
|
||
import { useState as useReactState } from 'react' | ||
import { watch as vueWatch } from '@vue/reactivity' | ||
import type { | ||
ReactiveMarker, | ||
DebuggerOptions, | ||
WatchCallback, | ||
WatchSource, | ||
WatchHandle, | ||
} from '@vue/reactivity' | ||
import { onBeforeUnmount } from './lifecycle' | ||
import { logger } from './_logger' | ||
|
||
// changelog: https://github.com/vuejs/core/blob/main/CHANGELOG.md | ||
// https://github.com/vuejs/core/blob/main/packages/runtime-core/src/apiWatch.ts | ||
// https://github.com/vuejs/core/blob/main/packages/reactivity/src/watch.ts | ||
|
||
export interface WatchOptions<Immediate = boolean> extends DebuggerOptions { | ||
immediate?: Immediate | ||
deep?: boolean | number | ||
once?: boolean | ||
// The `flush` option is not supported in react at the moment. | ||
// flush?: 'pre' | 'post' | 'sync' | ||
} | ||
|
||
export type MultiWatchSources = (WatchSource<unknown> | object)[] | ||
|
||
type MaybeUndefined<T, I> = I extends true ? T | undefined : T | ||
type MapSources<T, Immediate> = { | ||
[K in keyof T]: T[K] extends WatchSource<infer V> | ||
? MaybeUndefined<V, Immediate> | ||
: T[K] extends object | ||
? MaybeUndefined<T[K], Immediate> | ||
: never | ||
} | ||
|
||
/** | ||
* Watches one or more reactive data sources and invokes a callback function when the sources change. | ||
* | ||
* @param source - The watcher's source. | ||
* @param callback - This function will be called when the source is changed. | ||
* @param options - An optional options object that does not support the `flush` option compared to Vue (3.5.0). | ||
* @see {@link https://vuejs.org/api/reactivity-core.html#watch Vue `watch()`} | ||
* | ||
* @example | ||
* ```js | ||
* const count = ref(0) | ||
* watch(count, (count, prevCount) => { | ||
* // ... | ||
* }) | ||
* ``` | ||
*/ | ||
|
||
// overload: single source + cb | ||
export function watch<T, Immediate extends Readonly<boolean> = false>( | ||
source: WatchSource<T>, | ||
callback: WatchCallback<T, MaybeUndefined<T, Immediate>>, | ||
options?: WatchOptions<Immediate>, | ||
): WatchHandle | ||
|
||
// overload: reactive array or tuple of multiple sources + cb | ||
export function watch<T extends Readonly<MultiWatchSources>, Immediate extends Readonly<boolean> = false>( | ||
sources: readonly [...T] | T, | ||
callback: [T] extends [ReactiveMarker] | ||
? WatchCallback<T, MaybeUndefined<T, Immediate>> | ||
: WatchCallback<MapSources<T, false>, MapSources<T, Immediate>>, | ||
options?: WatchOptions<Immediate>, | ||
): WatchHandle | ||
|
||
// overload: array of multiple sources + cb | ||
export function watch<T extends MultiWatchSources, Immediate extends Readonly<boolean> = false>( | ||
sources: [...T], | ||
callback: WatchCallback<MapSources<T, false>, MapSources<T, Immediate>>, | ||
options?: WatchOptions<Immediate>, | ||
): WatchHandle | ||
|
||
// overload: watching reactive object w/ cb | ||
export function watch<T extends object, Immediate extends Readonly<boolean> = false>( | ||
source: T, | ||
callback: WatchCallback<T, MaybeUndefined<T, Immediate>>, | ||
options?: WatchOptions<Immediate>, | ||
): WatchHandle | ||
|
||
// implementation | ||
export function watch<T = any, Immediate extends Readonly<boolean> = false>( | ||
source: T | WatchSource<T>, | ||
callback: WatchCallback<T>, | ||
options: WatchOptions<Immediate> = {}, | ||
): WatchHandle { | ||
return vueWatch(source as any, callback, { | ||
...options, | ||
onWarn: logger.warn, | ||
scheduler: (job) => job(), | ||
}) | ||
} | ||
|
||
/** | ||
* Watches one or more reactive data sources and invokes a callback function when the sources change. | ||
* | ||
* @param source - The watcher's source. | ||
* @param callback - This function will be called when the source is changed. | ||
* @param options - An optional options object that does not support the `flush` option compared to Vue (3.5.0). | ||
* @see {@link https://vuejs.org/api/reactivity-core.html#watch Vue `watch()`} | ||
* | ||
* @example | ||
* ```js | ||
* const count = useRef(0) | ||
* useWatch(count, (count, prevCount) => { | ||
* // ... | ||
* }) | ||
* ``` | ||
*/ | ||
export const useWatch: typeof watch = (source: any, callback: any, options = {}) => { | ||
const [watchHandle] = useReactState(() => watch(source as any, callback, options)) | ||
onBeforeUnmount(() => watchHandle.stop()) | ||
return watchHandle | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/** | ||
* @module veact.watchEffect | ||
* @author Surmon <https://github.com/surmon-china> | ||
*/ | ||
|
||
import { useState as useReactState } from 'react' | ||
import { watch as vueWatch } from '@vue/reactivity' | ||
import type { WatchEffect, WatchHandle, DebuggerOptions } from '@vue/reactivity' | ||
import { onBeforeUnmount } from './lifecycle' | ||
import { logger } from './_logger' | ||
|
||
// changelog: https://github.com/vuejs/core/blob/main/CHANGELOG.md | ||
// https://github.com/vuejs/core/blob/main/packages/runtime-core/src/apiWatch.ts | ||
// https://github.com/vuejs/core/blob/main/packages/reactivity/src/watch.ts | ||
|
||
export type WatchEffectOptions = DebuggerOptions | ||
|
||
/** | ||
* Runs a function immediately while reactively tracking its dependencies and re-runs it whenever the dependencies are changed. | ||
* | ||
* @param effectFn - The effect function to run. | ||
* @param options - An optional options object that can be used to adjust the effect's flush timing or to debug the effect's dependencies; the `flush` option is not supported compared to Vue (3.5.0). | ||
* @see {@link https://vuejs.org/api/reactivity-core.html#watcheffect Vue `watchEffect()`} | ||
* | ||
* @example | ||
* ```js | ||
* const count = ref(0) | ||
* watchEffect(() => console.log(count.value)) | ||
* // -> logs 0 | ||
* | ||
* count.value++ | ||
* // -> logs 1 | ||
* ``` | ||
*/ | ||
export function watchEffect(effectFn: WatchEffect, options: WatchEffectOptions = {}): WatchHandle { | ||
return vueWatch(effectFn, null, { | ||
...options, | ||
onWarn: logger.warn, | ||
scheduler: (job) => job(), | ||
}) | ||
} | ||
|
||
/** | ||
* Runs a function immediately while reactively tracking its dependencies and re-runs it whenever the dependencies are changed. | ||
* | ||
* @param effect - The effect function to run. | ||
* @param options - An optional options object that can be used to adjust the effect's flush timing or to debug the effect's dependencies; the `flush` option is not supported compared to Vue (3.5.0). | ||
* @see {@link https://vuejs.org/api/reactivity-core.html#watcheffect Vue `watchEffect()`} | ||
* | ||
* @example | ||
* ```js | ||
* const count = useRef(0) | ||
* useWatchEffect(() => console.log(count.value)) | ||
* // -> logs 0 | ||
* | ||
* count.value++ | ||
* // -> logs 1 | ||
* ``` | ||
*/ | ||
export const useWatchEffect: typeof watchEffect = (effect: any, options?: any) => { | ||
const [watchHandle] = useReactState(() => watchEffect(effect, options)) | ||
onBeforeUnmount(() => watchHandle.stop()) | ||
return watchHandle | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters