Skip to content

Instantly share code, notes, and snippets.

@Heydon
Created July 23, 2018 14:09
Show Gist options
  • Star 41 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save Heydon/9de1a8b55dd1448281fad013503a5b7a to your computer and use it in GitHub Desktop.
Save Heydon/9de1a8b55dd1448281fad013503a5b7a to your computer and use it in GitHub Desktop.
function Mutilator(data, name, context) {
this.n = name || `mutilation-${+new Date()}`;
this.d = data;
this.c = context || window;
this.isArr = function(p) {
return this.d[p].constructor == Array;
};
this.dispatch = function(p, v, t) {
this.c.dispatchEvent(
new CustomEvent(this.n, {
detail: {
prop: p,
val: v,
type: t
}
})
);
};
}
Mutilator.prototype = {
change: function(p, v) {
this.d[p] = v;
this.dispatch(p, v, "change");
},
add: function(p, v) {
this.isArr(p) ? this.d[p].push(v) : (this.d[p] = [this.d[p], v]);
this.dispatch(p, v, "add");
},
remove: function(p, v) {
!this.isArr(p) ? delete this.d[p] : this.d[p].splice(v, 1);
this.dispatch(p, p[v], "remove");
},
recoil: function(f, r) {
this.c.addEventListener(this.n, e => {
if (!r || r.some(p => e.detail.prop.indexOf(p) > -1)) {
return f(e, this.d);
}
});
}
};
export default Mutilator;
@Heydon
Copy link
Author

Heydon commented Jul 24, 2018

Here's a version that just uses getters/setters:

function mutilator(obj, name = "mutilated", context = window) {
  const mutilated = {};
  for (let prop in obj) {
    let ref = `m-${prop}`;
    mutilated[ref] = obj[prop];
    Object.defineProperty(mutilated, prop, {
      set: function(v) {
        this[ref] = v;
        context.dispatchEvent(
          new CustomEvent(`${name}:${prop}`, {
            detail: { prop: prop, value: v }
          })
        );
      },
      get: function() {
        return this[ref];
      }
    });
  }
  return mutilated;
}

Initialize

const mutable = mutilator({
  string: 'foo'
  num: 6
})

Listening to events

If you set mutable.string = 'bar', the event mutilated:string is emitted (on window by default).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment