1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/rocketchat_ynh.git synced 2024-09-03 20:16:25 +02:00
rocketchat_ynh/sources/programs/server/packages/reactive-dict.js
2016-04-29 16:32:48 +02:00

291 lines
30 KiB
JavaScript

(function () {
/* Imports */
var Meteor = Package.meteor.Meteor;
var _ = Package.underscore._;
var Tracker = Package.tracker.Tracker;
var Deps = Package.tracker.Deps;
var EJSON = Package.ejson.EJSON;
var ECMAScript = Package.ecmascript.ECMAScript;
var babelHelpers = Package['babel-runtime'].babelHelpers;
var Symbol = Package['ecmascript-runtime'].Symbol;
var Map = Package['ecmascript-runtime'].Map;
var Set = Package['ecmascript-runtime'].Set;
var Promise = Package.promise.Promise;
/* Package-scope variables */
var ReactiveDict;
(function(){
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/reactive-dict/reactive-dict.js //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// XXX come up with a serialization method which canonicalizes object key //
// order, which would allow us to use objects as values for equals. //
var stringify = function (value) { // 3
if (value === undefined) return 'undefined'; // 4
return EJSON.stringify(value); // 6
}; //
var parse = function (serialized) { // 8
if (serialized === undefined || serialized === 'undefined') return undefined; // 9
return EJSON.parse(serialized); // 11
}; //
//
var changed = function (v) { // 14
v && v.changed(); // 15
}; //
//
// XXX COMPAT WITH 0.9.1 : accept migrationData instead of dictName //
ReactiveDict = function (dictName) { // 19
// this.keys: key -> value //
if (dictName) { // 21
if (typeof dictName === 'string') { // 22
// the normal case, argument is a string name. //
// _registerDictForMigrate will throw an error on duplicate name. //
ReactiveDict._registerDictForMigrate(dictName, this); // 25
this.keys = ReactiveDict._loadMigratedDict(dictName) || {}; // 26
this.name = dictName; // 27
} else if (typeof dictName === 'object') { //
// back-compat case: dictName is actually migrationData //
this.keys = dictName; // 30
} else { //
throw new Error("Invalid ReactiveDict argument: " + dictName); // 32
} //
} else { //
// no name given; no migration will be performed //
this.keys = {}; // 36
} //
//
this.allDeps = new Tracker.Dependency(); // 39
this.keyDeps = {}; // key -> Dependency // 40
this.keyValueDeps = {}; // key -> Dependency // 41
}; //
//
_.extend(ReactiveDict.prototype, { // 44
// set() began as a key/value method, but we are now overloading it //
// to take an object of key/value pairs, similar to backbone //
// http://backbonejs.org/#Model-set //
//
set: function (keyOrObject, value) { // 49
var self = this; // 50
//
if (typeof keyOrObject === 'object' && value === undefined) { // 52
// Called as `dict.set({...})` //
self._setObject(keyOrObject); // 54
return; // 55
} //
// the input isn't an object, so it must be a key //
// and we resume with the rest of the function //
var key = keyOrObject; // 59
//
value = stringify(value); // 61
//
var keyExisted = _.has(self.keys, key); // 63
var oldSerializedValue = keyExisted ? self.keys[key] : 'undefined'; // 64
var isNewValue = value !== oldSerializedValue; // 65
//
self.keys[key] = value; // 67
//
if (isNewValue || !keyExisted) { // 69
self.allDeps.changed(); // 70
} //
//
if (isNewValue) { // 73
changed(self.keyDeps[key]); // 74
if (self.keyValueDeps[key]) { // 75
changed(self.keyValueDeps[key][oldSerializedValue]); // 76
changed(self.keyValueDeps[key][value]); // 77
} //
} //
}, //
//
setDefault: function (key, value) { // 82
var self = this; // 83
if (!_.has(self.keys, key)) { // 84
self.set(key, value); // 85
} //
}, //
//
get: function (key) { // 89
var self = this; // 90
self._ensureKey(key); // 91
self.keyDeps[key].depend(); // 92
return parse(self.keys[key]); // 93
}, //
//
equals: function (key, value) { // 96
var self = this; // 97
//
// Mongo.ObjectID is in the 'mongo' package //
var ObjectID = null; // 100
if (Package.mongo) { // 101
ObjectID = Package.mongo.Mongo.ObjectID; // 102
} //
//
// We don't allow objects (or arrays that might include objects) for //
// .equals, because JSON.stringify doesn't canonicalize object key //
// order. (We can make equals have the right return value by parsing the //
// current value and using EJSON.equals, but we won't have a canonical //
// element of keyValueDeps[key] to store the dependency.) You can still use //
// "EJSON.equals(reactiveDict.get(key), value)". //
// //
// XXX we could allow arrays as long as we recursively check that there //
// are no objects //
if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean' && typeof value !== 'undefined' && !(value instanceof Date) && !(ObjectID && value instanceof ObjectID) && value !== null) {
throw new Error("ReactiveDict.equals: value must be scalar"); // 121
} //
var serializedValue = stringify(value); // 123
//
if (Tracker.active) { // 125
self._ensureKey(key); // 126
//
if (!_.has(self.keyValueDeps[key], serializedValue)) self.keyValueDeps[key][serializedValue] = new Tracker.Dependency();
//
var isNew = self.keyValueDeps[key][serializedValue].depend(); // 131
if (isNew) { // 132
Tracker.onInvalidate(function () { // 133
// clean up [key][serializedValue] if it's now empty, so we don't //
// use O(n) memory for n = values seen ever //
if (!self.keyValueDeps[key][serializedValue].hasDependents()) delete self.keyValueDeps[key][serializedValue];
}); //
} //
} //
//
var oldValue = undefined; // 142
if (_.has(self.keys, key)) oldValue = parse(self.keys[key]); // 143
return EJSON.equals(oldValue, value); // 144
}, //
//
all: function () { // 147
this.allDeps.depend(); // 148
var ret = {}; // 149
_.each(this.keys, function (value, key) { // 150
ret[key] = parse(value); // 151
}); //
return ret; // 153
}, //
//
clear: function () { // 156
var self = this; // 157
//
var oldKeys = self.keys; // 159
self.keys = {}; // 160
//
self.allDeps.changed(); // 162
//
_.each(oldKeys, function (value, key) { // 164
changed(self.keyDeps[key]); // 165
changed(self.keyValueDeps[key][value]); // 166
changed(self.keyValueDeps[key]['undefined']); // 167
}); //
}, //
//
'delete': function (key) { // 172
var self = this; // 173
var didRemove = false; // 174
//
if (_.has(self.keys, key)) { // 176
var oldValue = self.keys[key]; // 177
delete self.keys[key]; // 178
changed(self.keyDeps[key]); // 179
if (self.keyValueDeps[key]) { // 180
changed(self.keyValueDeps[key][oldValue]); // 181
changed(self.keyValueDeps[key]['undefined']); // 182
} //
self.allDeps.changed(); // 184
didRemove = true; // 185
} //
//
return didRemove; // 188
}, //
//
_setObject: function (object) { // 191
var self = this; // 192
//
_.each(object, function (value, key) { // 194
self.set(key, value); // 195
}); //
}, //
//
_ensureKey: function (key) { // 199
var self = this; // 200
if (!(key in self.keyDeps)) { // 201
self.keyDeps[key] = new Tracker.Dependency(); // 202
self.keyValueDeps[key] = {}; // 203
} //
}, //
//
// Get a JSON value that can be passed to the constructor to //
// create a new ReactiveDict with the same contents as this one //
_getMigrationData: function () { // 209
// XXX sanitize and make sure it's JSONible? //
return this.keys; // 211
} //
}); //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}).call(this);
(function(){
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/reactive-dict/migration.js //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
ReactiveDict._migratedDictData = {}; // name -> data // 1
ReactiveDict._dictsToMigrate = {}; // name -> ReactiveDict // 2
//
ReactiveDict._loadMigratedDict = function (dictName) { // 4
if (_.has(ReactiveDict._migratedDictData, dictName)) return ReactiveDict._migratedDictData[dictName]; // 5
//
return null; // 8
}; //
//
ReactiveDict._registerDictForMigrate = function (dictName, dict) { // 11
if (_.has(ReactiveDict._dictsToMigrate, dictName)) throw new Error("Duplicate ReactiveDict name: " + dictName);
//
ReactiveDict._dictsToMigrate[dictName] = dict; // 15
}; //
//
if (Meteor.isClient && Package.reload) { // 18
// Put old migrated data into ReactiveDict._migratedDictData, //
// where it can be accessed by ReactiveDict._loadMigratedDict. //
var migrationData = Package.reload.Reload._migrationData('reactive-dict'); // 21
if (migrationData && migrationData.dicts) ReactiveDict._migratedDictData = migrationData.dicts; // 22
//
// On migration, assemble the data from all the dicts that have been //
// registered. //
Package.reload.Reload._onMigrate('reactive-dict', function () { // 27
var dictsToMigrate = ReactiveDict._dictsToMigrate; // 28
var dataToMigrate = {}; // 29
//
for (var dictName in babelHelpers.sanitizeForInObject(dictsToMigrate)) dataToMigrate[dictName] = dictsToMigrate[dictName]._getMigrationData();
//
return [true, { dicts: dataToMigrate }]; // 34
}); //
} //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}).call(this);
/* Exports */
if (typeof Package === 'undefined') Package = {};
Package['reactive-dict'] = {
ReactiveDict: ReactiveDict
};
})();
//# sourceMappingURL=reactive-dict.js.map