react-magic-state
Version:
React state management without the hassle.
85 lines (84 loc) • 2.72 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const symbols = require("./symbols");
class Observer {
constructor(wrappedFunction) {
this._observations = new WeakMap();
this._reactions = new Set();
this._wrappedFunction = wrappedFunction;
Observer._all.add(this);
}
static get all() {
return this._all;
}
static get active() {
return this._activeObserver;
}
addReaction(reaction) {
this._reactions.add(reaction);
}
beginObservationPhase() {
if (Observer._activeObserver) {
if (Observer._activeObserver === this) {
//TODO: Write test
throw new Error("beginObservationPhase() called twice for the same observer.");
}
Observer._observerStack.push(Observer._activeObserver);
}
// Remove old observations
//TODO: Write test
this._observations = new WeakMap();
Observer._activeObserver = this;
}
createWrapper() {
const self = this;
const target = this._wrappedFunction;
const wrapper = function () {
self.beginObservationPhase();
try {
return Reflect.apply(target, this, arguments);
}
finally {
self.endObservationPhase();
}
};
return wrapper;
}
destroy() {
const wrapped = this._wrappedFunction;
const self = this;
Observer.all.delete(this);
delete self._observations;
delete self._reactions;
delete self._wrappedFunction;
delete wrapped[symbols.observer];
return wrapped;
}
endObservationPhase() {
if (Observer._activeObserver !== this) {
throw new Error("Unmatched beingObservationPhase()/endObservationPhase() calls.");
}
Observer._activeObserver = Observer._observerStack.pop();
}
getReactionsForChange(target, propKey) {
const observation = this._observations.get(target);
if (observation) {
if (observation.has(propKey)) {
return this._reactions;
}
}
return null;
}
hasReaction(reaction) {
return this._reactions.has(reaction);
}
registerAccess(target, propKey) {
if (!this._observations.has(target)) {
this._observations.set(target, new Set());
}
this._observations.get(target).add(propKey);
}
}
exports.Observer = Observer;
Observer._observerStack = new Array();
Observer._all = new Set();