client/tcpclient.js
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))
		}
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))
		}
/*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);
},