-
-
Save benjamingr/8098901205a0eb5bfd6a664c584ebc6c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Reactor { | |
constructor() { | |
// this keeps the current function we're reacting to | |
this.reaction = null; | |
} | |
// observe a single property | |
_observeProperty(obj, prop, initialValue = undefined) { | |
let backing = initialValue; | |
let dependents = []; | |
Object.defineProperty(obj, prop, { | |
get: () => { | |
if (this.reaction) { | |
dependents.push(this.reaction); | |
} | |
return backing; | |
}, | |
set(value) { | |
backing = value; | |
for(const dependent of dependents) { | |
setTimeout(dependent); /// <- ONLY LINE THAT I HAD TO CHANGE IS THIS ONE | |
} | |
} | |
}); | |
} | |
// observe a whole object | |
_observeObject(obj) { | |
for(const p of Object.keys(obj)) { | |
this.observe(obj, p, obj[p]); | |
} | |
return obj; | |
} | |
// convenience | |
observe(obj, prop, initialValue = undefined) { | |
if (typeof prop === 'undefined') return this._observeObject(obj); | |
return this._observeProperty(obj, prop, initialValue); | |
} | |
// computed is just observe + autorun, we should fix the setter | |
computed(obj, prop, fn) { | |
this._observeProperty(obj, prop, fn()); | |
this.autorun(() => { | |
obj[prop] = fn(); | |
}); | |
} | |
// see how simple this is - we just see what getters are called (by setting this.reaction) and telling them to | |
// re-run this later | |
autorun(fn) { | |
this.reaction = fn; // can't nest autoruns because that's lame | |
try { | |
return fn(); // get initial depenedents | |
} finally { | |
this.reaction = null; | |
} | |
} | |
} | |
let r = new Reactor(); | |
var o = r.observe({ | |
a: 3, | |
b: 5, | |
r: 'foo' | |
}); | |
r.computed(o, 'full', () => o.a + o.b); | |
//r.observe(o, 'r', 3); | |
r.autorun(() => console.log(o.full)); | |
o.a = 1; | |
o.a = 2; | |
o.a = 3; | |
o.b = 4; | |
/* | |
~/Desktop $ node magic.js | |
8 | |
6 | |
7 | |
8 | |
7 | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Reactor { | |
constructor() { | |
// this keeps the current function we're reacting to | |
this.reaction = null; | |
} | |
// observe a single property | |
_observeProperty(obj, prop, initialValue = undefined) { | |
let backing = initialValue; | |
let dependents = []; | |
Object.defineProperty(obj, prop, { | |
get: () => { | |
if (this.reaction) { | |
dependents.push(this.reaction); | |
} | |
return backing; | |
}, | |
set(value) { | |
backing = value; | |
for(const dependent of dependents) { | |
dependent(); | |
} | |
} | |
}); | |
} | |
// observe a whole object | |
_observeObject(obj) { | |
for(const p of Object.keys(obj)) { | |
this.observe(obj, p, obj[p]); | |
} | |
return obj; | |
} | |
// convenience | |
observe(obj, prop, initialValue = undefined) { | |
if (typeof prop === 'undefined') return this._observeObject(obj); | |
return this._observeProperty(obj, prop, initialValue); | |
} | |
// computed is just observe + autorun, we should fix the setter | |
computed(obj, prop, fn) { | |
this._observeProperty(obj, prop, fn()); | |
this.autorun(() => { | |
obj[prop] = fn(); | |
}); | |
} | |
// see how simple this is - we just see what getters are called (by setting this.reaction) and telling them to | |
// re-run this later | |
autorun(fn) { | |
this.reaction = fn; // can't nest autoruns because that's lame | |
try { | |
return fn(); // get initial depenedents | |
} finally { | |
this.reaction = null; | |
} | |
} | |
} | |
let r = new Reactor(); | |
var o = r.observe({ | |
a: 3, | |
b: 5, | |
r: 'foo' | |
}); | |
r.computed(o, 'full', () => o.a + o.b); | |
//r.observe(o, 'r', 3); | |
r.autorun(() => console.log(o.full)); | |
o.a = 1; | |
o.a = 2; | |
o.a = 3; | |
o.b = 4; | |
/* | |
~/Desktop $ node magic.js | |
8 | |
6 | |
7 | |
8 | |
7 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://stackblitz.com/edit/react-acpgu5?file=mobx-proxy.js