clean_sync.client library
A library for data subscription and synchronization in single page applications.
Functions
num handleDiff(List<Map> diff, Subscription subscription, String author) #
num handleDiff(List<Map> diff, Subscription subscription, String author) { logger.fine('handleDiff: subscription: $subscription, author: $author,' 'diffSize: ${diff.length}, diff: $diff'); subscription.updateLock = true; DataSet collection = subscription.collection; var version = subscription._version; num res = -1; try { diff.forEach((Map change) { var _records = collection.findBy("_id", change["_id"]); DataMap record = _records.isNotEmpty? _records.first : null; String action = change["action"]; logger.finer('handling change $change'); // it can happen, that we get too old changes if (!change.containsKey('version')){ logger.warning('change does not contain "version" field. If not testing, ' 'this is probably bug. (change: $change)'); change['version'] = 0; } else if (version == null) { logger.warning('Subscription $subscription version is null. If not testing, ' 'this is probably bug.'); } else if(change['version'] <= version) { return; } if (action == "add") { res = max(res, change['version']); if (record == null) { logger.finer('aplying changes (add)'); collection.add(change["data"]); } else { logger.finer('add discarded; same id already present'); assert(author == change['author']); } } else if (action == "change" ) { // 1. the change may be for item that is currently not present in the collection; // 2. the field may be 'locked', because it was changed on user's machine, and // this change was not yet confirmed from server if (record != null) { if(!subscription._sentItems.containsKey(record['_id']) && !subscription._modifiedItems.changedItems.containsKey('_id')) { logger.finer('aplying changes (change)'); res = max(res, change['version']); applyChange(change["data"], record); } else { logger.finer('discarding diff'); throw "stop"; } } } else if (action == "remove" ) { logger.finer('aplying changes (remove'); res = max(res, change['version']); collection.remove(record); } logger.finest('applying finished: $subscription ${subscription.collection} ${subscription._version}'); }); } catch (e) { if (e is Exception) { throw e; } } logger.fine('handleDiff ends'); // destroyStructure(diff); subscription.updateLock = false; return res; }
void destroyStructure(s) #
void destroyStructure(s){ if (s is Map) { destroyMap(s); } else if (s is Iterable) { destroyIterable(s); } else {} }
void destroyIterable(l) #
void destroyIterable(var l) { l.forEach((v){ destroyStructure(v); }); for (var v in new List.from(l)) { l.remove(v); } }
void destroyMap(Map m) #
void destroyMap(Map m) { m.forEach((k,v){ destroyStructure(v); }); for (var k in new List.from(m.keys)) { m.remove(k); } }
bool applyChange(source, target) #
bool applyChange (source, target) { if (source is Map && target is Map) { _applyChangeMap(source, target); return true; } if (source is List && target is List) { _applyChangeList(source, target); return true; } if(source == target) { return true; } return false; }
void handleData(List<Map> data, Subscription subscription, String author) #
void handleData(List<Map> data, Subscription subscription, String author) { logger.fine('handleData: ${data}'); var collection = subscription.collection; subscription.updateLock = true; collection.clear(); collection.addAll(data); subscription.updateLock = false; }