freak.js
function construct(target) {
    mixin(target, {
      values: obj,
      parent: parent || null,
      root: root || target,
      prop: prop === undefined ? null : prop,
      // .on(event[, prop], callback)
      on: on,
      // .off(event[, prop][, callback])
      off: off,
      // .trigger(event[, prop])
      trigger: trigger,
      toJSON: toJSON,
      // internal: dependency tracking
      deps: deps
    });

    // Wrap mutating array method to update
    // state and notify listeners
    function wrapMutatingArrayMethod(method, func) {
      return function() {
        var result = [][method].apply(obj, arguments);
        this.len = this.values.length;
        cache = {};
        children = {};
        func.apply(this, arguments);
        target.parent.trigger('update', target.prop);
        return result;
      };
    }

    // Wrap callback of an array method to
    // provide this content to the currently processed item
    function proxyArrayMethod(method) {
      return function(callback) {
        return [][method].apply(
          obj,
          [function(el, i) {
            return callback.apply(target(i), [].slice.call(arguments));
          }].concat([].slice.call(arguments, 1))
        );
      };
    }

    if (Array.isArray(obj)) {
      mixin(target, {
        // Function prototype already contains length
        // `len` specifies array length
        len: obj.length,

        pop: wrapMutatingArrayMethod('pop', function() {
          trigger('delete', this.len, 1);
        }),

        push: wrapMutatingArrayMethod('push', function() {
          trigger('insert', this.len - 1, 1);
        }),

        reverse: wrapMutatingArrayMethod('reverse', function() {
          trigger('delete', 0, this.len);
          trigger('insert', 0, this.len);
        }),

        shift: wrapMutatingArrayMethod('shift', function() {
          trigger('delete', 0, 1);
        }),

        unshift: wrapMutatingArrayMethod('unshift', function() {
          trigger('insert', 0, 1);
        }),

        sort: wrapMutatingArrayMethod('sort', function() {
          trigger('delete', 0, this.len);
          trigger('insert', 0, this.len);
        }),

        splice: wrapMutatingArrayMethod('splice', function() {
          if (arguments[1]) {
            trigger('delete', arguments[0], arguments[1]);
          }
          if (arguments.length > 2) {
            trigger('insert', arguments[0], arguments.length - 2);
          }
        })

      });

      ['forEach', 'every', 'some', 'filter', 'map', 'reduce', 'reduceRight']
        .forEach(function(method) {
          target[method] = proxyArrayMethod(method);
        });
    }
  }
function construct(target) {
    mixin(target, {
      values: obj,
      parent: parent || null,
      root: root || target,
      prop: prop === undefined ? null : prop,
      // .on(event[, prop], callback)
      on: on,
      // .off(event[, prop][, callback])
      off: off,
      // .trigger(event[, prop])
      trigger: trigger,
      toJSON: toJSON,
      // internal: dependency tracking
      deps: deps
    });

    // Wrap mutating array method to update
    // state and notify listeners
    function wrapMutatingArrayMethod(method, func) {
      return function() {
        var result = [][method].apply(obj, arguments);
        this.len = this.values.length;
        cache = {};
        children = {};
        func.apply(this, arguments);
        target.parent.trigger('update', target.prop);
        return result;
      };
    }

    // Wrap callback of an array method to
    // provide this content to the currently processed item
    function proxyArrayMethod(method) {
      return function(callback) {
        return [][method].apply(
          obj,
          [function(el, i) {
            return callback.apply(target(i), [].slice.call(arguments));
          }].concat([].slice.call(arguments, 1))
        );
      };
    }

    if (Array.isArray(obj)) {
      mixin(target, {
        // Function prototype already contains length
        // `len` specifies array length
        len: obj.length,

        pop: wrapMutatingArrayMethod('pop', function() {
          trigger('delete', this.len, 1);
        }),

        push: wrapMutatingArrayMethod('push', function() {
          trigger('insert', this.len - 1, 1);
        }),

        reverse: wrapMutatingArrayMethod('reverse', function() {
          trigger('delete', 0, this.len);
          trigger('insert', 0, this.len);
        }),

        shift: wrapMutatingArrayMethod('shift', function() {
          trigger('delete', 0, 1);
        }),

        unshift: wrapMutatingArrayMethod('unshift', function() {
          trigger('insert', 0, 1);
        }),

        sort: wrapMutatingArrayMethod('sort', function() {
          trigger('delete', 0, this.len);
          trigger('insert', 0, this.len);
        }),

        splice: wrapMutatingArrayMethod('splice', function() {
          if (arguments[1]) {
            trigger('delete', arguments[0], arguments[1]);
          }
          if (arguments.length > 2) {
            trigger('insert', arguments[0], arguments.length - 2);
          }
        })

      });

      ['forEach', 'every', 'some', 'filter', 'map', 'reduce', 'reduceRight']
        .forEach(function(method) {
          target[method] = proxyArrayMethod(method);
        });
    }
  }
function construct ( target ) { mixin ( target , { values : obj , parent : parent || null , root : root || target , prop : prop === undefined ? null : prop , // .on(event[, prop], callback) on : on , // .off(event[, prop][, callback]) off : off , // .trigger(event[, prop]) trigger : trigger , toJSON : toJSON , // internal: dependency tracking deps : deps } ) ; // Wrap mutating array method to update // state and notify listeners function wrapMutatingArrayMethod ( method , func ) { return function ( ) { var result = [ ] [ method ] . apply ( obj , arguments ) ; this . len = this . values . length ; cache = { } ; children = { } ; func . apply ( this , arguments ) ; target . parent . trigger ( 'update' , target . prop ) ; return result ; } ; } // Wrap callback of an array method to // provide this content to the currently processed item function proxyArrayMethod ( method ) { return function ( callback ) { return [ ] [ method ] . apply ( obj , [ function ( el , i ) { return callback . apply ( target ( i ) , [ ] . slice . call ( arguments ) ) ; } ] . concat ( [ ] . slice . call ( arguments , 1 ) ) ) ; } ; } if ( Array . isArray ( obj ) ) { mixin ( target , { // Function prototype already contains length // `len` specifies array length len : obj . length , pop : wrapMutatingArrayMethod ( 'pop' , function ( ) { trigger ( 'delete' , this . len , 1 ) ; } ) , push : wrapMutatingArrayMethod ( 'push' , function ( ) { trigger ( 'insert' , this . len - 1 , 1 ) ; } ) , reverse : wrapMutatingArrayMethod ( 'reverse' , function ( ) { trigger ( 'delete' , 0 , this . len ) ; trigger ( 'insert' , 0 , this . len ) ; } ) , shift : wrapMutatingArrayMethod ( 'shift' , function ( ) { trigger ( 'delete' , 0 , 1 ) ; } ) , unshift : wrapMutatingArrayMethod ( 'unshift' , function ( ) { trigger ( 'insert' , 0 , 1 ) ; } ) , sort : wrapMutatingArrayMethod ( 'sort' , function ( ) { trigger ( 'delete' , 0 , this . len ) ; trigger ( 'insert' , 0 , this . len ) ; } ) , splice : wrapMutatingArrayMethod ( 'splice' , function ( ) { if ( arguments [ 1 ] ) { trigger ( 'delete' , arguments [ 0 ] , arguments [ 1 ] ) ; } if ( arguments . length > 2 ) { trigger ( 'insert' , arguments [ 0 ] , arguments . length - 2 ) ; } } ) } ) ; [ 'forEach' , 'every' , 'some' , 'filter' , 'map' , 'reduce' , 'reduceRight' ] . forEach ( function ( method ) { target [ method ] = proxyArrayMethod ( method ) ; } ) ; } }
Attach instance members
Attach instance members