// Create a mapped array which is kept in sync via observation.

var observingMapHandler = {
  add    ({name, object}) { result[name] = fn.call(ctxt, object[name]) },
  update({name, object}) { result[name] = fn.call(ctxt, object[name]) },
  delete ({name})         { delete result[name]; }
  splice({object, index, removed, addedCount}) {
    result.splice(
      index, 
      removed.length, 
        ...object.slice(index, index + addedCount).map(fn, ctxt)
    );
  }
};
    
function observingMap(a, fn, ctxt) {
  var result = a.map(fn, ctxt);

  function observer({type, name, object, index, removed, addedCount}) {
    switch(type) {
    case "update": case "add":
      result[name] = fn.call(ctxt, object[name]); 
      break;
    case "delete": 
      delete result[name]; 
      break;
    case "splice":
    }
  }

  Array.observe(a, recs => recs.forEach(observer), ['splice', 'update', 'delete']);
  return result;
}

// Order an array and keep it ordered as things change.
function observingOrder(a, order) {
  return observingMap(order, i => a[i]);
}

// Create an array of running totals, etc.
function runningMap(a, fn, init) {
  return a.map(v => init = fn(v, init));
}

function plus(a,b) { return a + b; }

// Create an array of running totals.
function runningTotal(a) {
  return runningMap(a, plus);
}

// Given a Boolean filter array, keep an array up to date.
function runningFilter(a, filter) {
  var result = a.filter((_, i) => filter[i]);

  function observer({type, name, object, index, oldvalue}) {
    var pos = runningTotal(filter);
    if (object[index]) {
      result.splice(pos, 0, a[index]);
    } else {
      result.splice(pos, 1);
    }
  }

  Object.observe(filter, recs => recs.forEach(observer), ['update']);
  return result;
}

var a = [3,2,1];
function double(x) { return x*2; }

var result = observingMap(a, double);

//a.sort();
delete a[1];
console.dir(a);

setTimeout(function() {
  console.log("result is", result);
}, 500);

export {
  observingMap,
  observingOrder
};

@@ -1,106 +1,408 @@
-// Create a mapped array which is kept in sync via observation.%0A%0Avar observingMapHandler =
+import %7BobserveObject%7D from './Obj';%0A%0Avar %7Bobserve%7D = Array;%0Avar %7Bkeys%7D = Object;%0A%0A// Observe an array based on a handlers object.%0Afunction observeArray(a, handlers) %7B%0A  return observe(a, handlers, keys(handlers));%0A%7D%0A%0A// Create a mapped array which is kept in sync via observation.%0A// Replace changed values, delete deleted values, and mirror splices.%0Afunction observingMap(a, fn, ctxt)
  %7B%0A
+%0A
   
-add    
+function add
 (%7Bna
@@ -464,83 +464,56 @@
 %5D) %7D
-,%0A  update(%7Bname, object%7D) %7B result%5Bname%5D = fn.call(ctxt, object%5Bname%5D) %7D,%0A
+%0A%0A  var handler = %7B%0A    add,%0A    update: add,%0A  
   de
@@ -525,24 +525,16 @@
 (%7Bname%7D)
-        
  %7B delet
@@ -551,16 +551,18 @@
 ame%5D; %7D%0A
+  
   splice
@@ -610,572 +610,220 @@
     
-result.splice(%0A      index, %0A      removed.length, %0A        ...object.slice(index, index + addedCount).map(fn, ctxt)%0A    );%0A  %7D%0A%7D;%0A    %0Afunction observingMap(a, fn, ctxt) %7B%0A  var result = a.map(fn, ctxt);%0A%0A  function observer(%7Btype, name, object, index, removed, addedCount%7D) %7B%0A    switch(type) %7B%0A    case %22update%22: case %22add%22:%0A      result%5Bname%5D = fn.call(ctxt, object%5Bname%5D); %0A      break;%0A    case %22delete%22: %0A      delete result%5Bname%5D; %0A      break;%0A    case %22splice%22:%0A    %7D%0A  %7D%0A%0A  Array.observe(a, recs =%3E recs.forEach(observer), %5B'splice', 'update', 'delete'%5D
+  var added = ...object.slice(index, index + addedCount).map(fn, ctxt);%0A      result.splice(index, removed.length, added);%0A    %7D%0A  %7D;%0A    %0A  var result = a.map(fn, ctxt);%0A  observe(a, makeObserverHandler(handler)
 );%0A 
@@ -1115,16 +1115,17 @@
  plus(a,
+ 
 b) %7B ret
@@ -1295,29 +1295,86 @@
 o date.%0A
-function runn
+// When a value changes, splice the element in or out.%0Afunction observ
 ingFilte
@@ -1441,67 +1441,56 @@
 %0A%0A  
-function observer(%7Btype, name, object, index, oldvalue
+var handlers = %7B%0A    update(%7Bname, object
 %7D) %7B%0A
+  
     
@@ -1525,16 +1525,18 @@
 r);%0A    
+  
 if (obje
@@ -1542,23 +1542,16 @@
 ect%5B
-index%5D) %7B%0A     
+name%5D) %7B
  res
@@ -1575,35 +1575,30 @@
 , a%5B
-index
+name
 %5D);
+ %7D
 %0A    
-%7D
+ 
  else %7B
-%0A     
  res
@@ -1620,36 +1620,32 @@
  1);
-%0A   
  %7D%0A  %7D
+;
 %0A%0A  
-Object.
 observe
+Object
 (fil
@@ -1653,50 +1653,38 @@
 er, 
-recs =%3E recs.forEach(observer), %5B'update'%5D
+makeObserverHandlers(handlers)
 );%0A 

Tweak Arr.js stuff.