mirror of
https://github.com/YunoHost-Apps/rocketchat_ynh.git
synced 2024-09-03 20:16:25 +02:00
291 lines
30 KiB
JavaScript
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
|