Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link
Owner Author

Heydon commented Jul 23, 2018

Working on a small 1D object reactive store, with array methods. Uses CustomEvent.

You mutilate the data, then recoil in horror.

For recoil functions, you can set which property changes are relevant. E.g. you can listen to just the list and string properties:

const mutilator = new Mutilator({
  string: 'foo',
  list: [1,2,3],
  ignored: 'bla'
})

mutilator.recoil((e, d) => {
   console.log(e.detail.type) // the type of mutilation (change, add, or remove)
   console.log(e.detail.prop) // which property was changed
   console.log(e.detail.val) // the new value for the changed property
}, ['list', 'string'])
@Heydon

This comment has been minimized.

Copy link
Owner 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
You can’t perform that action at this time.