From 8035ea9b12ea409a952f8f3c2409343da35bbd27 Mon Sep 17 00:00:00 2001 From: CRIMX Date: Mon, 15 Apr 2024 14:11:36 +0800 Subject: [PATCH] feat(utils): export attachSetter --- src/index.ts | 13 +++++++-- src/utils.ts | 62 ++++++++++++++++++++++++++++++++++++++++--- src/val.ts | 6 ++--- src/value-enhancer.ts | 55 -------------------------------------- 4 files changed, 73 insertions(+), 63 deletions(-) delete mode 100644 src/value-enhancer.ts diff --git a/src/index.ts b/src/index.ts index 74b81c7..74fbc2b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,6 +16,15 @@ export type { ValSubscriber, ValVersion, } from "./typings"; -export { arrayShallowEqual, identity, isVal, strictEqual } from "./utils"; +export { + arrayShallowEqual, + attachSetter, + identity, + isVal, + reaction, + setValue, + strictEqual, + subscribe, + unsubscribe, +} from "./utils"; export { groupVals, readonlyVal, val } from "./val"; -export { reaction, setValue, subscribe, unsubscribe } from "./value-enhancer"; diff --git a/src/utils.ts b/src/utils.ts index 44bf0ba..6c60ba3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,10 +1,66 @@ import type { ReadonlyVal, Val, + ValDisposer, ValInputsValueTuple, + ValSubscriber, ValVersion, } from "./typings"; +/** + * @deprecated + * Set the value of a val. + * It works for both `Val` and `ReadonlyVal` type (if the `ReadonlyVal` is actually a `Val`). + * Throws error if the val is really `ReadonlyVal`. + */ +export const setValue = ( + val: ReadonlyVal, + value: TValue +): void => { + try { + (val as Val).set?.(value); + } catch { + // ignore + } +}; + +/** + * Subscribe to value changes with immediate emission. + * @param val + * @param subscriber + * @param eager by default subscribers will be notified on next tick. set `true` to notify subscribers of value changes synchronously. + * @returns a disposer function that cancels the subscription + */ +export const subscribe = ( + val: ReadonlyVal, + subscriber: ValSubscriber, + eager?: boolean +): ValDisposer => val.subscribe(subscriber, eager); + +/** + * Subscribe to value changes without immediate emission. + * @param val + * @param subscriber + * @param eager by default subscribers will be notified on next tick. set `true` to notify subscribers of value changes synchronously. + * @returns a disposer function that cancels the subscription + */ +export const reaction = ( + val: ReadonlyVal, + subscriber: ValSubscriber, + eager?: boolean +): ValDisposer => val.reaction(subscriber, eager); + +/** + * Remove the given subscriber. + * Remove all if no subscriber provided. + * @param val + * @param subscriber + */ +export const unsubscribe = ( + val: ReadonlyVal, + subscriber?: (...args: any[]) => any +): void => val.unsubscribe(subscriber); + /** Returns the value passed in. */ export const identity = (value: TValue): TValue => value; @@ -62,12 +118,12 @@ export const invoke = ( }; /** - * Make a readonly Val writable by providing a set method + * Attach a new setter to a val. * @param val$ a readonly Val * @param set a function that sets the value of val$ - * @returns The same val$ but writable + * @returns The same val$ with the new setter. */ -export const makeWritable = ( +export const attachSetter = ( val$: ReadonlyVal, set: (this: void, value: TValue) => void ): Val => (((val$ as Val).set = set), val$ as Val); diff --git a/src/val.ts b/src/val.ts index 08ce388..b7b0c7b 100644 --- a/src/val.ts +++ b/src/val.ts @@ -10,7 +10,7 @@ import type { } from "./typings"; import { SubscriberMode, Subscribers } from "./subscribers"; -import { invoke, makeWritable, strictEqual } from "./utils"; +import { attachSetter, invoke, strictEqual } from "./utils"; /** * Bare minimum implementation of a readonly val. @@ -62,7 +62,7 @@ export class ValImpl implements ReadonlyVal { public ref(writable?: boolean): ReadonlyVal { const val$ = new ValRefImpl(this, this.#config); - return writable ? makeWritable(val$, this.set) : val$; + return writable ? attachSetter(val$, this.set) : val$; } public reaction( @@ -251,7 +251,7 @@ export function val( config?: ValConfig ): Val> { const [val$, set] = readonlyVal(value, config); - return makeWritable(val$, set); + return attachSetter(val$, set); } /** diff --git a/src/value-enhancer.ts b/src/value-enhancer.ts deleted file mode 100644 index ed0c79f..0000000 --- a/src/value-enhancer.ts +++ /dev/null @@ -1,55 +0,0 @@ -import type { ReadonlyVal, Val, ValDisposer, ValSubscriber } from "./typings"; - -/** - * @deprecated - * Set the value of a val. - * It works for both `Val` and `ReadonlyVal` type (if the `ReadonlyVal` is actually a `Val`). - * Throws error if the val is really `ReadonlyVal`. - */ -export const setValue = ( - val: ReadonlyVal, - value: TValue -): void => { - try { - (val as Val).set?.(value); - } catch { - // ignore - } -}; - -/** - * Subscribe to value changes with immediate emission. - * @param val - * @param subscriber - * @param eager by default subscribers will be notified on next tick. set `true` to notify subscribers of value changes synchronously. - * @returns a disposer function that cancels the subscription - */ -export const subscribe = ( - val: ReadonlyVal, - subscriber: ValSubscriber, - eager?: boolean -): ValDisposer => val.subscribe(subscriber, eager); - -/** - * Subscribe to value changes without immediate emission. - * @param val - * @param subscriber - * @param eager by default subscribers will be notified on next tick. set `true` to notify subscribers of value changes synchronously. - * @returns a disposer function that cancels the subscription - */ -export const reaction = ( - val: ReadonlyVal, - subscriber: ValSubscriber, - eager?: boolean -): ValDisposer => val.reaction(subscriber, eager); - -/** - * Remove the given subscriber. - * Remove all if no subscriber provided. - * @param val - * @param subscriber - */ -export const unsubscribe = ( - val: ReadonlyVal, - subscriber?: (...args: any[]) => any -): void => val.unsubscribe(subscriber);