kr-observable
Version:
Adds reactivity power for your JavaScript
81 lines (80 loc) • 2.01 kB
JavaScript
import { Utils } from './Utils.js';
import { Global } from './global.js';
export class Computed {
enumerable;
configurable;
set;
runId = 1;
debug = false;
active = false;
deps;
#adm;
#property;
#descriptor;
#value;
#setterValue;
changed = false;
computed = true;
name;
constructor(property, descriptor, handler) {
this.enumerable = descriptor.enumerable;
this.configurable = descriptor.configurable;
this.#property = property;
this.#descriptor = descriptor;
this.#adm = handler.adm;
if (descriptor.set) {
this.set = (value) => {
this.#descriptor.set(value);
const prevValue = this.#setterValue;
this.#setterValue = value;
this.#report(prevValue, value);
};
}
}
subscriber() {
this.changed = true;
if (this.#adm.deps.get(this.#property)?.size === 0) {
return;
}
this.compute();
}
run() {
return this.#descriptor.get();
}
compute() {
const prev = this.#value;
this.#reader();
this.#report(prev, this.#value);
}
#report(prevValue, newValue) {
if (!Utils.isDeepEqual(prevValue, newValue)) {
this.#adm.report(this.#property, newValue);
}
if (Global.action)
return;
this.#adm.batch();
}
#reader() {
this.#value = Global.executor.execute(this);
}
get = () => {
if (!Global.action) {
this.#adm.batch();
}
if (!this.deps) {
this.#reader();
return this.#value;
}
if (this.deps?.size === 0) {
return this.run();
}
if (this.changed) {
this.changed = false;
this.#reader();
}
if (this.#adm.current?.has(this)) {
this.compute();
}
return this.#value;
};
}