whole_func_string: function(e){
  		
  			//console.log('got block update for: ' + e.destinationSyncId)
  		
  			var cb = syncListenersBySyncId[e.destinationSyncId]
  			if(!cb){
  				console.log('ignored block for dead or missing sync listener: ' + e.destinationSyncId + ' ' + JSON.stringify(Object.keys(syncListenersBySyncId)))
  				return
  			}
  			_.assertFunction(cb.block);
  			
  			var json = {
  				endEditId: e.endEditId
  			}
  			
  			var r = fparse.makeSingleReader(e.edits)
  			var many = r.readInt()
  			var edits = []
  			//console.log('many edits: ' + many)
  			for(var i=0;i<many;++i){
  				var editId = r.readInt()
  				var op = r.readByte()
  				var edit = fp.readersByCode[op](r)
  				edits.push({op: op, edit: edit, editId: editId})
  			}
  			json.edits = edits
  			
  			var r = fparse.makeSingleReader(e.objects)
  			var many = r.readInt()
  			var objects = []
  			//console.log('many objects: ' + many)
  			for(var i=0;i<many;++i){
  				var id = r.readUuid()//readInt()
  				var buf = r.readData()
  				objects.push({id: id, edits: readObject(buf)})
  			}
  			json.objects = objects
  			
  			var r = fparse.makeSingleReader(e.viewObjects)
  			var many = r.readInt()
  			var viewObjects = []
  			//console.log('many view objects: ' + many)
  			for(var i=0;i<many;++i){
  				var id = r.readVarString()
  				var buf = r.readData()
  				viewObjects.push({id: id, edits: readObject(buf)})
  			}
  			json.viewObjects = viewObjects
  			
  			cb.block(json)
  			//_.errout('TODO: ' + JSON.stringify(e))
  		}
func_code_string: function(e){
  		
  			//console.log('got block update for: ' + e.destinationSyncId)
  		
  			var cb = syncListenersBySyncId[e.destinationSyncId]
  			if(!cb){
  				console.log('ignored block for dead or missing sync listener: ' + e.destinationSyncId + ' ' + JSON.stringify(Object.keys(syncListenersBySyncId)))
  				return
  			}
  			_.assertFunction(cb.block);
  			
  			var json = {
  				endEditId: e.endEditId
  			}
  			
  			var r = fparse.makeSingleReader(e.edits)
  			var many = r.readInt()
  			var edits = []
  			//console.log('many edits: ' + many)
  			for(var i=0;i<many;++i){
  				var editId = r.readInt()
  				var op = r.readByte()
  				var edit = fp.readersByCode[op](r)
  				edits.push({op: op, edit: edit, editId: editId})
  			}
  			json.edits = edits
  			
  			var r = fparse.makeSingleReader(e.objects)
  			var many = r.readInt()
  			var objects = []
  			//console.log('many objects: ' + many)
  			for(var i=0;i<many;++i){
  				var id = r.readUuid()//readInt()
  				var buf = r.readData()
  				objects.push({id: id, edits: readObject(buf)})
  			}
  			json.objects = objects
  			
  			var r = fparse.makeSingleReader(e.viewObjects)
  			var many = r.readInt()
  			var viewObjects = []
  			//console.log('many view objects: ' + many)
  			for(var i=0;i<many;++i){
  				var id = r.readVarString()
  				var buf = r.readData()
  				viewObjects.push({id: id, edits: readObject(buf)})
  			}
  			json.viewObjects = viewObjects
  			
  			cb.block(json)
  			//_.errout('TODO: ' + JSON.stringify(e))
  		}
func_documentation_string: /*newSyncId: function(e){
  _.assertInt(e.requestId)
  console.log('set newSyncId listener =============================')
  console.log('got new syncId: ' + JSON.stringify(e))
  var cb = getRequestCallback(e);
  syncListenersBySyncId[e.syncId] = syncListenersByRequestId[e.requestId]
  makeCbListenersBySyncId[e.syncId] = makeCbListenersByRequestId[e.requestId]
  _.assertFunction(syncListenersBySyncId[e.syncId].edit)
  _.assertFunction(syncListenersBySyncId[e.syncId].object)
  _.assertFunction(syncListenersBySyncId[e.syncId].make)
  _.assertFunction(syncListenersBySyncId[e.syncId].block)
  _.assertFunction(syncListenersBySyncId[e.syncId].versionTimestamps)
  delete syncListenersByRequestId[e.requestId]
  cb(e.syncId);
  },