120 lines
3.6 KiB
Plaintext
120 lines
3.6 KiB
Plaintext
import { Store } from "./store.js";
|
|
import { __storeToDerived, __derivedToStore } from "./scheduler.js";
|
|
class Derived {
|
|
constructor(options) {
|
|
this.listeners = /* @__PURE__ */ new Set();
|
|
this._subscriptions = [];
|
|
this.lastSeenDepValues = [];
|
|
this.getDepVals = () => {
|
|
const prevDepVals = [];
|
|
const currDepVals = [];
|
|
for (const dep of this.options.deps) {
|
|
prevDepVals.push(dep.prevState);
|
|
currDepVals.push(dep.state);
|
|
}
|
|
this.lastSeenDepValues = currDepVals;
|
|
return {
|
|
prevDepVals,
|
|
currDepVals,
|
|
prevVal: this.prevState ?? void 0
|
|
};
|
|
};
|
|
this.recompute = () => {
|
|
var _a, _b;
|
|
this.prevState = this.state;
|
|
const { prevDepVals, currDepVals, prevVal } = this.getDepVals();
|
|
this.state = this.options.fn({
|
|
prevDepVals,
|
|
currDepVals,
|
|
prevVal
|
|
});
|
|
(_b = (_a = this.options).onUpdate) == null ? void 0 : _b.call(_a);
|
|
};
|
|
this.checkIfRecalculationNeededDeeply = () => {
|
|
for (const dep of this.options.deps) {
|
|
if (dep instanceof Derived) {
|
|
dep.checkIfRecalculationNeededDeeply();
|
|
}
|
|
}
|
|
let shouldRecompute = false;
|
|
const lastSeenDepValues = this.lastSeenDepValues;
|
|
const { currDepVals } = this.getDepVals();
|
|
for (let i = 0; i < currDepVals.length; i++) {
|
|
if (currDepVals[i] !== lastSeenDepValues[i]) {
|
|
shouldRecompute = true;
|
|
break;
|
|
}
|
|
}
|
|
if (shouldRecompute) {
|
|
this.recompute();
|
|
}
|
|
};
|
|
this.mount = () => {
|
|
this.registerOnGraph();
|
|
this.checkIfRecalculationNeededDeeply();
|
|
return () => {
|
|
this.unregisterFromGraph();
|
|
for (const cleanup of this._subscriptions) {
|
|
cleanup();
|
|
}
|
|
};
|
|
};
|
|
this.subscribe = (listener) => {
|
|
var _a, _b;
|
|
this.listeners.add(listener);
|
|
const unsub = (_b = (_a = this.options).onSubscribe) == null ? void 0 : _b.call(_a, listener, this);
|
|
return () => {
|
|
this.listeners.delete(listener);
|
|
unsub == null ? void 0 : unsub();
|
|
};
|
|
};
|
|
this.options = options;
|
|
this.state = options.fn({
|
|
prevDepVals: void 0,
|
|
prevVal: void 0,
|
|
currDepVals: this.getDepVals().currDepVals
|
|
});
|
|
}
|
|
registerOnGraph(deps = this.options.deps) {
|
|
for (const dep of deps) {
|
|
if (dep instanceof Derived) {
|
|
dep.registerOnGraph();
|
|
this.registerOnGraph(dep.options.deps);
|
|
} else if (dep instanceof Store) {
|
|
let relatedLinkedDerivedVals = __storeToDerived.get(dep);
|
|
if (!relatedLinkedDerivedVals) {
|
|
relatedLinkedDerivedVals = /* @__PURE__ */ new Set();
|
|
__storeToDerived.set(dep, relatedLinkedDerivedVals);
|
|
}
|
|
relatedLinkedDerivedVals.add(this);
|
|
let relatedStores = __derivedToStore.get(this);
|
|
if (!relatedStores) {
|
|
relatedStores = /* @__PURE__ */ new Set();
|
|
__derivedToStore.set(this, relatedStores);
|
|
}
|
|
relatedStores.add(dep);
|
|
}
|
|
}
|
|
}
|
|
unregisterFromGraph(deps = this.options.deps) {
|
|
for (const dep of deps) {
|
|
if (dep instanceof Derived) {
|
|
this.unregisterFromGraph(dep.options.deps);
|
|
} else if (dep instanceof Store) {
|
|
const relatedLinkedDerivedVals = __storeToDerived.get(dep);
|
|
if (relatedLinkedDerivedVals) {
|
|
relatedLinkedDerivedVals.delete(this);
|
|
}
|
|
const relatedStores = __derivedToStore.get(this);
|
|
if (relatedStores) {
|
|
relatedStores.delete(dep);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
export {
|
|
Derived
|
|
};
|
|
//# sourceMappingURL=derived.js.map
|