Skip to content

Instantly share code, notes, and snippets.

@IanSSenne
Created November 25, 2019 02:24
Show Gist options
  • Save IanSSenne/af9c75efe4abc205cf6322ab88fad612 to your computer and use it in GitHub Desktop.
Save IanSSenne/af9c75efe4abc205cf6322ab88fad612 to your computer and use it in GitHub Desktop.
const isObserve = Symbol("is-obObjserve");
const dispatch = Symbol("observe-dispatch");
const psym = Symbol("observe-data");
const observeWatch = Symbol("observe-watch");
export default class Observe {
constructor(obj) {
this[psym] = {};
this[psym]._raw = obj;
this[psym]._watchers = [];
const keys = Object.keys(obj);
const proto = Object.getPrototypeOf(obj);
const protokeys = Object.getOwnPropertyNames(proto);
for (let i = 0; i < protokeys.length; i++) {
Object.defineProperty(this, protokeys[i], {
value() {
const result = proto[protokeys[i]].apply(this[psym]._raw, Array.from(arguments));
this[dispatch]("update", { object: this[psym]._raw, updateSource: "function" });
return result;
}
})
}
for (let i = 0; i < keys.length; i++) {
const current = keys[i];
Object.defineProperty(this, current, {
get() {
if (typeof this[psym]._raw[current] === "object") {
if (!this[psym]._raw[current][isObserve]) {
this[psym]._raw[current] = new Observe(this[psym]._raw[current]);
this[psym]._raw[current].watch((event) => {
this[dispatch](event);
});
}
}
return this[psym]._raw[current];
},
set(v) {
const last = this[psym]._raw[current];
this[psym]._raw[current] = v;
this[dispatch]("update", { object: this[psym]._raw, attribute: current, old: last, new: v, updateSource: "setter" });
return this[psym]._raw[current];
}
});
}
}
[isObserve] = true;
[dispatch](eventType, data) {
let event = eventType;
if (eventType.constructor != CustomEvent) {
event = Object.assign(new CustomEvent(eventType), data);
}
for (let i = 0; i < this[psym]._watchers.length; i++) {
this[psym]._watchers[i](event);
}
}
[observeWatch](cb) {
this[psym]._watchers.push(cb);
}
static watch(observable, cb) {
observable[observeWatch](cb);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment