value-enhancer
Advanced tools
Comparing version 5.2.1 to 5.3.0
@@ -199,3 +199,3 @@ /** | ||
*/ | ||
declare function flatten<TSrcValue = any, TValOrValue = any>(val: ReadonlyVal<TSrcValue>, get: (value: TSrcValue) => TValOrValue, config?: ValConfig<UnwrapVal<TValOrValue>>): ReadonlyVal<UnwrapVal<TValOrValue>>; | ||
declare function flatten<TSrcValue = any, TValOrValue = any>(val: ReadonlyVal<TSrcValue>, get?: (value: TSrcValue) => TValOrValue, config?: ValConfig<UnwrapVal<TValOrValue>>): ReadonlyVal<UnwrapVal<TValOrValue>>; | ||
@@ -208,3 +208,3 @@ /** | ||
* If the value is a val, it will be auto-flattened. | ||
* @param listen A function that takes a notify function and returns a disposer. | ||
* @param onChange A function that takes a notify function and returns a disposer. | ||
* The notify function should be called when the value changes. | ||
@@ -214,14 +214,3 @@ * @param config custom config for the val. | ||
*/ | ||
/** | ||
* Creates a readonly val from a getter function and a listener function. | ||
* If the value is a val, it will be auto-flattened. | ||
* | ||
* @param getValue A function that returns the current value. | ||
* If the value is a val, it will be auto-flattened. | ||
* @param listen A function that takes a notify function and returns a disposer. | ||
* The notify function should be called when the value changes. | ||
* @param config custom config for the val. | ||
* @returns A readonly val with value of inner val. | ||
*/ | ||
declare const flattenFrom: <TValOrValue = any>(getValue: () => TValOrValue, listen: (notify: () => void) => ValDisposer | void | undefined, config?: ValConfig<UnwrapVal<TValOrValue>> | undefined) => ReadonlyVal<UnwrapVal<TValOrValue>>; | ||
declare const flattenFrom: <TValOrValue = any>(getValue: () => TValOrValue, onChange: (notify: () => void) => ValDisposer | void | undefined, config?: ValConfig<UnwrapVal<TValOrValue>> | undefined) => ReadonlyVal<UnwrapVal<TValOrValue>>; | ||
@@ -232,3 +221,3 @@ /** | ||
* @param getValue A function that returns the current value. | ||
* @param listen A function that takes a notify function and returns a disposer. | ||
* @param onChange A function that takes a notify function and returns a disposer. | ||
* The notify function should be called when the value changes. | ||
@@ -259,3 +248,3 @@ * @param config custom config for the val. | ||
*/ | ||
declare const from: <TValue = any>(getValue: () => TValue, listen: (handler: () => void) => ValDisposer | void | undefined, config?: ValConfig<TValue> | undefined) => ReadonlyVal<TValue>; | ||
declare const from: <TValue = any>(getValue: () => TValue, onChange: (notify: () => void) => ValDisposer | void | undefined, config?: ValConfig<TValue> | undefined) => ReadonlyVal<TValue>; | ||
@@ -265,4 +254,2 @@ declare const nextTick: () => Promise<void>; | ||
/** | ||
* @deprecated | ||
* @ignore | ||
* Set the value of a val. | ||
@@ -269,0 +256,0 @@ * It works for both `Val` and `ReadonlyVal` type (if the `ReadonlyVal` is actually a `Val`). |
@@ -107,12 +107,33 @@ 'use strict'; | ||
// src/agent.ts | ||
var registry = /* @__PURE__ */ new FinalizationRegistry(invoke); | ||
var ValAgent = class { | ||
constructor(getValue2, config, onStart) { | ||
this.#onStart = onStart; | ||
constructor(getValue2, config, onChange) { | ||
this.#getValue = getValue2; | ||
this.q = (config?.equal ?? strictEqual) || void 0; | ||
this.e = config?.eager; | ||
if (onChange) { | ||
const ref = new WeakRef(this); | ||
const disposeEffect = () => { | ||
if (disposeListen) { | ||
const dispose = disposeListen; | ||
disposeListen = void 0; | ||
dispose(); | ||
} | ||
}; | ||
let disposeListen = onChange(() => { | ||
const agent = ref.deref(); | ||
if (agent) { | ||
agent.n(); | ||
} else { | ||
disposeEffect(); | ||
} | ||
}); | ||
if (disposeListen) { | ||
registry.register(this, this.#disposeEffect = disposeEffect); | ||
} | ||
} | ||
} | ||
s = /* @__PURE__ */ new Map(); | ||
b = 2 /* ValueDirty */; | ||
v = INIT_VALUE; | ||
b = 4 /* NeedResolveValue */; | ||
v; | ||
c = INIT_VALUE; | ||
@@ -122,21 +143,20 @@ q; | ||
u = () => { | ||
if (this.b & 2 /* ValueDirty */) { | ||
if (this.b & 4 /* NeedResolveValue */) { | ||
this.b &= ~4 /* NeedResolveValue */; | ||
const newValue = this.#getValue(); | ||
if (this.c === INIT_VALUE) { | ||
this.d(newValue); | ||
this.f(newValue); | ||
} else if (!this.q?.(newValue, this.c)) { | ||
this.d(newValue); | ||
this.b |= 12 /* ShouldInvoke */; | ||
this.f(newValue); | ||
if (this.b & 1 /* Notifying */) { | ||
this.b |= 2 /* ValueChanged */; | ||
} | ||
} | ||
if (this.s.size) { | ||
this.b &= ~2 /* ValueDirty */; | ||
} | ||
} | ||
this.b &= ~1 /* Notified */; | ||
return this.c; | ||
}; | ||
n = () => { | ||
this.b |= 2 /* ValueDirty */; | ||
if (!(this.b & 1 /* Notified */)) { | ||
this.b |= 1 /* Notified */; | ||
this.b |= 4 /* NeedResolveValue */; | ||
if (this.s.size) { | ||
this.b |= 1 /* Notifying */; | ||
if (this[3 /* Computed */]) { | ||
@@ -147,21 +167,10 @@ this.#invoke(3 /* Computed */); | ||
this.u(); | ||
if (this.b & 4 /* ShouldInvokeEager */) { | ||
this.b &= ~4 /* ShouldInvokeEager */; | ||
if (this.b & 2 /* ValueChanged */) { | ||
this.#invoke(2 /* Eager */); | ||
} else { | ||
this.b &= ~12 /* ShouldInvoke */; | ||
return; | ||
} | ||
} else { | ||
this.b &= ~4 /* ShouldInvokeEager */; | ||
} | ||
if (this[1 /* Async */]) { | ||
schedule(this); | ||
} else { | ||
this.b &= ~8 /* ShouldInvokeAsync */; | ||
} | ||
schedule(this); | ||
} | ||
}; | ||
a(subscriber, mode) { | ||
const oldSize = this.s.size; | ||
const currentMode = this.s.get(subscriber); | ||
@@ -173,8 +182,2 @@ if (currentMode) { | ||
this[mode]++; | ||
if (!oldSize) { | ||
this.u(); | ||
this.b &= ~12 /* ShouldInvoke */; | ||
this.#onStartDisposer?.(); | ||
this.#onStartDisposer = this.#onStart?.(this.n); | ||
} | ||
return () => this.r(subscriber); | ||
@@ -194,9 +197,2 @@ } | ||
} | ||
if (!this.s.size) { | ||
this.b |= 2 /* ValueDirty */; | ||
if (this.#onStartDisposer) { | ||
this.#onStartDisposer(); | ||
this.#onStartDisposer = null; | ||
} | ||
} | ||
} | ||
@@ -206,19 +202,22 @@ t() { | ||
this.u(); | ||
if (this.b & 8 /* ShouldInvokeAsync */) { | ||
this.b &= ~8 /* ShouldInvokeAsync */; | ||
if (this.b & 2 /* ValueChanged */) { | ||
this.#invoke(1 /* Async */); | ||
} | ||
} else { | ||
this.b &= ~8 /* ShouldInvokeAsync */; | ||
} | ||
this.b &= ~(1 /* Notifying */ | 2 /* ValueChanged */); | ||
} | ||
d(value) { | ||
this.d = this.q?.(value, value) ? this.f : this.g; | ||
this.d(value); | ||
d() { | ||
this.r(); | ||
registry.unregister(this); | ||
this.#disposeEffect?.(); | ||
} | ||
g(value) { | ||
f(value) { | ||
this.f = this.q?.(value, value) ? this.g : this.h; | ||
this.f(value); | ||
} | ||
h(value) { | ||
this.c = value; | ||
this.v = this.#numberVersion++ | 0; | ||
} | ||
f(value) { | ||
g(value) { | ||
this.c = this.v = value; | ||
@@ -230,5 +229,4 @@ } | ||
#numberVersion = 0; | ||
#disposeEffect; | ||
#getValue; | ||
#onStart; | ||
#onStartDisposer; | ||
#invoke(mode) { | ||
@@ -275,2 +273,5 @@ for (const [sub, subMode] of this.s) { | ||
} | ||
d() { | ||
this.r(); | ||
} | ||
}; | ||
@@ -287,2 +288,3 @@ | ||
this.get = agent.u; | ||
agent.u(); | ||
} | ||
@@ -320,3 +322,3 @@ get $version() { | ||
dispose() { | ||
this.#agent.r(); | ||
this.#agent.d(); | ||
} | ||
@@ -378,5 +380,3 @@ /** | ||
// src/from.ts | ||
var from = (getValue2, listen, config) => { | ||
return new ValImpl(new ValAgent(getValue2, config, listen)); | ||
}; | ||
var from = (getValue2, onChange, config) => new ValImpl(new ValAgent(getValue2, config, onChange)); | ||
@@ -423,14 +423,12 @@ // src/combine.ts | ||
// src/flatten-from.ts | ||
var flattenFrom = (getValue2, listen, config) => { | ||
var flattenFrom = (getValue2, onChange, config) => { | ||
let innerDisposer; | ||
let currentValVersion = INIT_VALUE; | ||
let currentMaybeVal = INIT_VALUE; | ||
let dirty = true; | ||
let needCheckOuterVal = true; | ||
const useDefaultEqual = config?.equal == null; | ||
const subs = new ValAgent( | ||
const agent = new ValAgent( | ||
() => { | ||
if (dirty) { | ||
if (subs.s.size) { | ||
dirty = false; | ||
} | ||
if (needCheckOuterVal) { | ||
needCheckOuterVal = false; | ||
const lastMaybeVal = currentMaybeVal; | ||
@@ -440,6 +438,4 @@ currentMaybeVal = getValue2(); | ||
if (!strictEqual(currentMaybeVal, lastMaybeVal)) { | ||
innerDisposer &&= innerDisposer(); | ||
if (subs.s.size) { | ||
innerDisposer = currentMaybeVal.$valCompute(subs.n); | ||
} | ||
innerDisposer?.(); | ||
innerDisposer = currentMaybeVal.$valCompute(agent.n); | ||
} | ||
@@ -453,4 +449,4 @@ } else { | ||
currentValVersion = currentMaybeVal.$version; | ||
if (useDefaultEqual && !strictEqual(currentValVersion, lastValVersion)) { | ||
subs.b |= 12 /* ShouldInvoke */; | ||
if (useDefaultEqual && agent.b & 1 /* Notifying */ && !strictEqual(currentValVersion, lastValVersion)) { | ||
agent.b |= 2 /* ValueChanged */; | ||
} | ||
@@ -465,11 +461,7 @@ return currentMaybeVal.value; | ||
(notify) => { | ||
const outerDisposer = listen(() => { | ||
dirty = true; | ||
const outerDisposer = onChange(() => { | ||
needCheckOuterVal = true; | ||
notify(); | ||
}); | ||
if (!innerDisposer && isVal(currentMaybeVal)) { | ||
innerDisposer = currentMaybeVal.$valCompute(notify); | ||
} | ||
return () => { | ||
dirty = true; | ||
innerDisposer &&= innerDisposer(); | ||
@@ -480,3 +472,3 @@ outerDisposer?.(); | ||
); | ||
return new ValImpl(subs); | ||
return new ValImpl(agent); | ||
}; | ||
@@ -483,0 +475,0 @@ |
{ | ||
"name": "value-enhancer", | ||
"version": "5.2.1", | ||
"version": "5.3.0", | ||
"private": false, | ||
@@ -44,2 +44,15 @@ "description": "A tiny library to enhance value with reactive wrapper.", | ||
], | ||
"scripts": { | ||
"prepublishOnly": "pnpm run build", | ||
"lint": "eslint --ext .ts,.tsx . && prettier --check . && tsc --noEmit", | ||
"test": "node --expose-gc ./node_modules/jest/bin/jest.js", | ||
"test:CI": "tsc --noEmit -p ./test/tsconfig.json && node --expose-gc ./node_modules/jest/bin/jest.js --collect-coverage", | ||
"docs": "typedoc --options typedoc.json", | ||
"types": "cross-env NODE_ENV=production tsc --declaration --emitDeclarationOnly --jsx react --esModuleInterop --outDir dist", | ||
"build:index": "tsup --config tsup-config/index.tsup.config.ts", | ||
"build:collections": "tsup --config tsup-config/collections.tsup.config.ts", | ||
"build": "cross-env NODE_ENV=production pnpm run build:index && cross-env NODE_ENV=production pnpm run build:collections", | ||
"build:min": "cross-env NODE_ENV=production MINIFY=true pnpm run build:index && cross-env NODE_ENV=production MINIFY=true pnpm run build:collections && node scripts/gzip.mjs", | ||
"release": "standard-version" | ||
}, | ||
"devDependencies": { | ||
@@ -63,15 +76,3 @@ "@jest/globals": "^29.5.0", | ||
"yoctocolors": "^1.0.0" | ||
}, | ||
"scripts": { | ||
"lint": "eslint --ext .ts,.tsx . && prettier --check . && tsc --noEmit", | ||
"test": "jest", | ||
"test:CI": "tsc --noEmit -p ./test/tsconfig.json && jest --collect-coverage", | ||
"docs": "typedoc --options typedoc.json", | ||
"types": "cross-env NODE_ENV=production tsc --declaration --emitDeclarationOnly --jsx react --esModuleInterop --outDir dist", | ||
"build:index": "tsup --config tsup-config/index.tsup.config.ts", | ||
"build:collections": "tsup --config tsup-config/collections.tsup.config.ts", | ||
"build": "cross-env NODE_ENV=production pnpm run build:index && cross-env NODE_ENV=production pnpm run build:collections", | ||
"build:min": "cross-env NODE_ENV=production MINIFY=true pnpm run build:index && cross-env NODE_ENV=production MINIFY=true pnpm run build:collections && node scripts/gzip.mjs", | ||
"release": "standard-version" | ||
} | ||
} | ||
} |
107
src/agent.ts
@@ -11,2 +11,4 @@ import type { Task } from "./scheduler"; | ||
const registry = /* @__PURE__ */ new FinalizationRegistry<() => void>(invoke); | ||
export enum SubMode { | ||
@@ -19,7 +21,5 @@ Async = 1, | ||
export enum AgentStatus { | ||
Notified = 1 << 0, | ||
ValueDirty = 1 << 1, | ||
ShouldInvokeEager = 1 << 2, | ||
ShouldInvokeAsync = 1 << 3, | ||
ShouldInvoke = AgentStatus.ShouldInvokeEager | AgentStatus.ShouldInvokeAsync, | ||
Notifying = 1 << 0, | ||
ValueChanged = 1 << 1, | ||
NeedResolveValue = 1 << 2, | ||
} | ||
@@ -35,2 +35,3 @@ | ||
remove_(subscriber?: (...args: any[]) => any): void; | ||
dispose_(): void; | ||
} | ||
@@ -42,13 +43,35 @@ | ||
config?: ValConfig<TValue>, | ||
onStart?: (notify: () => void) => ValDisposer | void | undefined | ||
onChange?: (notify: () => void) => ValDisposer | void | undefined | ||
) { | ||
this.#onStart = onStart; | ||
this.#getValue = getValue; | ||
this.equal_ = (config?.equal ?? strictEqual) || void 0; | ||
this.eager_ = config?.eager; | ||
if (onChange) { | ||
const ref = new WeakRef(this); | ||
const disposeEffect = () => { | ||
if (disposeListen) { | ||
// prevent infinite recursion if user returns the notify function | ||
const dispose = disposeListen; | ||
disposeListen = void 0; | ||
dispose(); | ||
} | ||
}; | ||
let disposeListen = onChange(() => { | ||
const agent = ref.deref(); | ||
if (agent) { | ||
agent.notify_(); | ||
} else { | ||
disposeEffect(); | ||
} | ||
}); | ||
if (disposeListen) { | ||
registry.register(this, (this.#disposeEffect = disposeEffect)); | ||
} | ||
} | ||
} | ||
public readonly subs_ = new Map<ValSubscriber<TValue>, SubMode>(); | ||
public status_: number = AgentStatus.ValueDirty; | ||
public version_: ValVersion = INIT_VALUE; | ||
public status_ = AgentStatus.NeedResolveValue; | ||
public version_: ValVersion; | ||
public value_: TValue = INIT_VALUE; | ||
@@ -59,3 +82,4 @@ public equal_?: (newValue: TValue, oldValue: TValue) => boolean; | ||
public resolveValue_ = (): TValue => { | ||
if (this.status_ & AgentStatus.ValueDirty) { | ||
if (this.status_ & AgentStatus.NeedResolveValue) { | ||
this.status_ &= ~AgentStatus.NeedResolveValue; | ||
const newValue = this.#getValue(); | ||
@@ -66,9 +90,7 @@ if (this.value_ === INIT_VALUE) { | ||
this._bumpVersion_(newValue); | ||
this.status_ |= AgentStatus.ShouldInvoke; | ||
if (this.status_ & AgentStatus.Notifying) { | ||
this.status_ |= AgentStatus.ValueChanged; | ||
} | ||
} | ||
if (this.subs_.size) { | ||
this.status_ &= ~AgentStatus.ValueDirty; | ||
} | ||
} | ||
this.status_ &= ~AgentStatus.Notified; | ||
return this.value_; | ||
@@ -78,5 +100,5 @@ }; | ||
public notify_ = (): void => { | ||
this.status_ |= AgentStatus.ValueDirty; | ||
if (!(this.status_ & AgentStatus.Notified)) { | ||
this.status_ |= AgentStatus.Notified; | ||
this.status_ |= AgentStatus.NeedResolveValue; | ||
if (this.subs_.size) { | ||
this.status_ |= AgentStatus.Notifying; | ||
if (this[SubMode.Computed]) { | ||
@@ -87,17 +109,8 @@ this.#invoke(SubMode.Computed); | ||
this.resolveValue_(); | ||
if (this.status_ & AgentStatus.ShouldInvokeEager) { | ||
this.status_ &= ~AgentStatus.ShouldInvokeEager; | ||
if (this.status_ & AgentStatus.ValueChanged) { | ||
this.#invoke(SubMode.Eager); | ||
} else { | ||
this.status_ &= ~AgentStatus.ShouldInvoke; | ||
return; | ||
} | ||
} else { | ||
this.status_ &= ~AgentStatus.ShouldInvokeEager; | ||
} | ||
if (this[SubMode.Async]) { | ||
schedule(this); | ||
} else { | ||
this.status_ &= ~AgentStatus.ShouldInvokeAsync; | ||
} | ||
// always schedule an async task for cleaning the Notifying status | ||
schedule(this); | ||
} | ||
@@ -107,3 +120,2 @@ }; | ||
public add_(subscriber: ValSubscriber, mode: SubMode): () => void { | ||
const oldSize = this.subs_.size; | ||
const currentMode = this.subs_.get(subscriber); | ||
@@ -116,9 +128,2 @@ if (currentMode) { | ||
if (!oldSize) { | ||
this.resolveValue_(); | ||
this.status_ &= ~AgentStatus.ShouldInvoke; | ||
this.#onStartDisposer?.(); | ||
this.#onStartDisposer = this.#onStart?.(this.notify_); | ||
} | ||
return () => this.remove_(subscriber); | ||
@@ -139,9 +144,2 @@ } | ||
} | ||
if (!this.subs_.size) { | ||
this.status_ |= AgentStatus.ValueDirty; | ||
if (this.#onStartDisposer) { | ||
this.#onStartDisposer(); | ||
this.#onStartDisposer = null; | ||
} | ||
} | ||
} | ||
@@ -152,11 +150,15 @@ | ||
this.resolveValue_(); | ||
if (this.status_ & AgentStatus.ShouldInvokeAsync) { | ||
this.status_ &= ~AgentStatus.ShouldInvokeAsync; | ||
if (this.status_ & AgentStatus.ValueChanged) { | ||
this.#invoke(SubMode.Async); | ||
} | ||
} else { | ||
this.status_ &= ~AgentStatus.ShouldInvokeAsync; | ||
} | ||
this.status_ &= ~(AgentStatus.Notifying | AgentStatus.ValueChanged); | ||
} | ||
public dispose_(): void { | ||
this.remove_(); | ||
registry.unregister(this); | ||
this.#disposeEffect?.(); | ||
} | ||
private _bumpVersion_(value: TValue): void { | ||
@@ -183,6 +185,5 @@ this._bumpVersion_ = this.equal_?.(value, value) | ||
#numberVersion = 0; | ||
#disposeEffect?: () => void; | ||
readonly #getValue: () => TValue; | ||
readonly #onStart?: (notify: () => void) => ValDisposer | void | undefined; | ||
#onStartDisposer?: ValDisposer | void | null; | ||
@@ -236,2 +237,6 @@ #invoke(mode: SubMode): void { | ||
} | ||
public dispose_(): void { | ||
this.remove_(); | ||
} | ||
} |
import type { ReadonlyVal, ValConfig } from "./typings"; | ||
import { from } from "./from"; | ||
import { INIT_VALUE, identity, strictEqual } from "./utils"; | ||
import { identity, INIT_VALUE, strictEqual } from "./utils"; | ||
@@ -6,0 +6,0 @@ export type DerivedValTransform<TValue = any, TDerivedValue = any> = ( |
@@ -19,3 +19,3 @@ import type { | ||
* If the value is a val, it will be auto-flattened. | ||
* @param listen A function that takes a notify function and returns a disposer. | ||
* @param onChange A function that takes a notify function and returns a disposer. | ||
* The notify function should be called when the value changes. | ||
@@ -25,23 +25,5 @@ * @param config custom config for the val. | ||
*/ | ||
// export const flattenFrom2 = <TValOrValue = any>( | ||
// getValue: () => TValOrValue, | ||
// listen: (notify: () => void) => ValDisposer | void | undefined, | ||
// config?: ValConfig<UnwrapVal<TValOrValue>> | ||
// ): ReadonlyVal<UnwrapVal<TValOrValue>> => | ||
// new FlattenFromImpl(getValue, listen, config); | ||
/** | ||
* Creates a readonly val from a getter function and a listener function. | ||
* If the value is a val, it will be auto-flattened. | ||
* | ||
* @param getValue A function that returns the current value. | ||
* If the value is a val, it will be auto-flattened. | ||
* @param listen A function that takes a notify function and returns a disposer. | ||
* The notify function should be called when the value changes. | ||
* @param config custom config for the val. | ||
* @returns A readonly val with value of inner val. | ||
*/ | ||
export const flattenFrom = <TValOrValue = any>( | ||
getValue: () => TValOrValue, | ||
listen: (notify: () => void) => ValDisposer | void | undefined, | ||
onChange: (notify: () => void) => ValDisposer | void | undefined, | ||
config?: ValConfig<UnwrapVal<TValOrValue>> | ||
@@ -52,11 +34,9 @@ ): ReadonlyVal<UnwrapVal<TValOrValue>> => { | ||
let currentMaybeVal: TValOrValue = INIT_VALUE; | ||
let dirty = true; | ||
let needCheckOuterVal = true; | ||
const useDefaultEqual = config?.equal == null; | ||
const subs = new ValAgent( | ||
const agent = new ValAgent( | ||
() => { | ||
if (dirty) { | ||
if (subs.subs_.size) { | ||
dirty = false; | ||
} | ||
if (needCheckOuterVal) { | ||
needCheckOuterVal = false; | ||
@@ -68,6 +48,4 @@ const lastMaybeVal = currentMaybeVal; | ||
if (!strictEqual(currentMaybeVal, lastMaybeVal)) { | ||
innerDisposer &&= innerDisposer(); | ||
if (subs.subs_.size) { | ||
innerDisposer = currentMaybeVal.$valCompute(subs.notify_); | ||
} | ||
innerDisposer?.(); | ||
innerDisposer = currentMaybeVal.$valCompute(agent.notify_); | ||
} | ||
@@ -84,5 +62,6 @@ } else { | ||
useDefaultEqual && | ||
agent.status_ & AgentStatus.Notifying && | ||
!strictEqual(currentValVersion, lastValVersion) | ||
) { | ||
subs.status_ |= AgentStatus.ShouldInvoke; | ||
agent.status_ |= AgentStatus.ValueChanged; | ||
} | ||
@@ -97,11 +76,7 @@ return currentMaybeVal.value; | ||
notify => { | ||
const outerDisposer = listen(() => { | ||
dirty = true; | ||
const outerDisposer = onChange(() => { | ||
needCheckOuterVal = true; | ||
notify(); | ||
}); | ||
if (!innerDisposer && isVal(currentMaybeVal)) { | ||
innerDisposer = currentMaybeVal.$valCompute(notify); | ||
} | ||
return () => { | ||
dirty = true; | ||
innerDisposer &&= innerDisposer(); | ||
@@ -113,3 +88,3 @@ outerDisposer?.(); | ||
return new ValImpl(subs); | ||
return new ValImpl(agent); | ||
}; |
@@ -47,3 +47,3 @@ import type { ReadonlyVal, UnwrapVal, ValConfig } from "./typings"; | ||
val: ReadonlyVal<TSrcValue>, | ||
get: (value: TSrcValue) => TValOrValue, | ||
get?: (value: TSrcValue) => TValOrValue, | ||
config?: ValConfig<UnwrapVal<TValOrValue>> | ||
@@ -50,0 +50,0 @@ ): ReadonlyVal<UnwrapVal<TValOrValue>>; |
@@ -9,3 +9,3 @@ import { ValAgent } from "./agent"; | ||
* @param getValue A function that returns the current value. | ||
* @param listen A function that takes a notify function and returns a disposer. | ||
* @param onChange A function that takes a notify function and returns a disposer. | ||
* The notify function should be called when the value changes. | ||
@@ -38,6 +38,4 @@ * @param config custom config for the val. | ||
getValue: () => TValue, | ||
listen: (handler: () => void) => ValDisposer | void | undefined, | ||
onChange: (notify: () => void) => ValDisposer | void | undefined, | ||
config?: ValConfig<TValue> | ||
): ReadonlyVal<TValue> => { | ||
return new ValImpl(new ValAgent(getValue, config, listen)); | ||
}; | ||
): ReadonlyVal<TValue> => new ValImpl(new ValAgent(getValue, config, onChange)); |
@@ -13,4 +13,2 @@ import type { | ||
/** | ||
* @deprecated | ||
* @ignore | ||
* Set the value of a val. | ||
@@ -107,5 +105,10 @@ * It works for both `Val` and `ReadonlyVal` type (if the `ReadonlyVal` is actually a `Val`). | ||
export const invoke = <TValue>( | ||
fn: (value: TValue) => void, | ||
value: TValue | ||
export interface Invoke { | ||
(fn: () => void): void; | ||
<TValue>(fn: (value: TValue) => void, value: TValue): void; | ||
} | ||
export const invoke: Invoke = <TValue>( | ||
fn: (value?: TValue) => void, | ||
value?: TValue | ||
): void => { | ||
@@ -112,0 +115,0 @@ try { |
@@ -29,2 +29,3 @@ import type { | ||
this.get = agent.resolveValue_; | ||
agent.resolveValue_(); | ||
} | ||
@@ -80,3 +81,3 @@ | ||
public dispose(): void { | ||
this.#agent.remove_(); | ||
this.#agent.dispose_(); | ||
} | ||
@@ -83,0 +84,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
154273
4476