ethstats-server/web-app/.meteor/local/build/programs/web.browser/packages/reactive-dict.js
2015-08-14 19:22:53 +02:00

267 lines
21 KiB
JavaScript

//////////////////////////////////////////////////////////////////////////
// //
// This is a generated file. You can view the original //
// source in your browser if your browser supports source maps. //
// //
// If you are using Chrome, open the Developer Tools and click the gear //
// icon in its lower right corner. In the General Settings panel, turn //
// on 'Enable source maps'. //
// //
// If you are using Firefox 23, go to `about:config` and set the //
// `devtools.debugger.source-maps-enabled` preference to true. //
// (The preference should be on by default in Firefox 24; versions //
// older than 23 do not support source maps.) //
// //
//////////////////////////////////////////////////////////////////////////
(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;
/* Package-scope variables */
var ReactiveDict;
(function () {
//////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/reactive-dict/reactive-dict.js //
// //
//////////////////////////////////////////////////////////////////////////////////////////
//
// XXX come up with a serialization method which canonicalizes object key // 1
// order, which would allow us to use objects as values for equals. // 2
var stringify = function (value) { // 3
if (value === undefined) // 4
return 'undefined'; // 5
return EJSON.stringify(value); // 6
}; // 7
var parse = function (serialized) { // 8
if (serialized === undefined || serialized === 'undefined') // 9
return undefined; // 10
return EJSON.parse(serialized); // 11
}; // 12
// 13
// XXX COMPAT WITH 0.9.1 : accept migrationData instead of dictName // 14
ReactiveDict = function (dictName) { // 15
// this.keys: key -> value // 16
if (dictName) { // 17
if (typeof dictName === 'string') { // 18
// the normal case, argument is a string name. // 19
// _registerDictForMigrate will throw an error on duplicate name. // 20
ReactiveDict._registerDictForMigrate(dictName, this); // 21
this.keys = ReactiveDict._loadMigratedDict(dictName) || {}; // 22
} else if (typeof dictName === 'object') { // 23
// back-compat case: dictName is actually migrationData // 24
this.keys = dictName; // 25
} else { // 26
throw new Error("Invalid ReactiveDict argument: " + dictName); // 27
} // 28
} else { // 29
// no name given; no migration will be performed // 30
this.keys = {}; // 31
} // 32
// 33
this.keyDeps = {}; // key -> Dependency // 34
this.keyValueDeps = {}; // key -> Dependency // 35
}; // 36
// 37
_.extend(ReactiveDict.prototype, { // 38
// set() began as a key/value method, but we are now overloading it // 39
// to take an object of key/value pairs, similar to backbone // 40
// http://backbonejs.org/#Model-set // 41
// 42
set: function (keyOrObject, value) { // 43
var self = this; // 44
// 45
if ((typeof keyOrObject === 'object') && (value === undefined)) { // 46
self._setObject(keyOrObject); // 47
return; // 48
} // 49
// the input isn't an object, so it must be a key // 50
// and we resume with the rest of the function // 51
var key = keyOrObject; // 52
// 53
value = stringify(value); // 54
// 55
var oldSerializedValue = 'undefined'; // 56
if (_.has(self.keys, key)) oldSerializedValue = self.keys[key]; // 57
if (value === oldSerializedValue) // 58
return; // 59
self.keys[key] = value; // 60
// 61
var changed = function (v) { // 62
v && v.changed(); // 63
}; // 64
// 65
changed(self.keyDeps[key]); // 66
if (self.keyValueDeps[key]) { // 67
changed(self.keyValueDeps[key][oldSerializedValue]); // 68
changed(self.keyValueDeps[key][value]); // 69
} // 70
}, // 71
// 72
setDefault: function (key, value) { // 73
var self = this; // 74
// for now, explicitly check for undefined, since there is no // 75
// ReactiveDict.clear(). Later we might have a ReactiveDict.clear(), in which case // 76
// we should check if it has the key. // 77
if (self.keys[key] === undefined) { // 78
self.set(key, value); // 79
} // 80
}, // 81
// 82
get: function (key) { // 83
var self = this; // 84
self._ensureKey(key); // 85
self.keyDeps[key].depend(); // 86
return parse(self.keys[key]); // 87
}, // 88
// 89
equals: function (key, value) { // 90
var self = this; // 91
// 92
// Mongo.ObjectID is in the 'mongo' package // 93
var ObjectID = null; // 94
if (typeof Mongo !== 'undefined') { // 95
ObjectID = Mongo.ObjectID; // 96
} // 97
// 98
// We don't allow objects (or arrays that might include objects) for // 99
// .equals, because JSON.stringify doesn't canonicalize object key // 100
// order. (We can make equals have the right return value by parsing the // 101
// current value and using EJSON.equals, but we won't have a canonical // 102
// element of keyValueDeps[key] to store the dependency.) You can still use // 103
// "EJSON.equals(reactiveDict.get(key), value)". // 104
// // 105
// XXX we could allow arrays as long as we recursively check that there // 106
// are no objects // 107
if (typeof value !== 'string' && // 108
typeof value !== 'number' && // 109
typeof value !== 'boolean' && // 110
typeof value !== 'undefined' && // 111
!(value instanceof Date) && // 112
!(ObjectID && value instanceof ObjectID) && // 113
value !== null) // 114
throw new Error("ReactiveDict.equals: value must be scalar"); // 115
var serializedValue = stringify(value); // 116
// 117
if (Tracker.active) { // 118
self._ensureKey(key); // 119
// 120
if (! _.has(self.keyValueDeps[key], serializedValue)) // 121
self.keyValueDeps[key][serializedValue] = new Tracker.Dependency; // 122
// 123
var isNew = self.keyValueDeps[key][serializedValue].depend(); // 124
if (isNew) { // 125
Tracker.onInvalidate(function () { // 126
// clean up [key][serializedValue] if it's now empty, so we don't // 127
// use O(n) memory for n = values seen ever // 128
if (! self.keyValueDeps[key][serializedValue].hasDependents()) // 129
delete self.keyValueDeps[key][serializedValue]; // 130
}); // 131
} // 132
} // 133
// 134
var oldValue = undefined; // 135
if (_.has(self.keys, key)) oldValue = parse(self.keys[key]); // 136
return EJSON.equals(oldValue, value); // 137
}, // 138
// 139
_setObject: function (object) { // 140
var self = this; // 141
// 142
_.each(object, function (value, key){ // 143
self.set(key, value); // 144
}); // 145
}, // 146
// 147
_ensureKey: function (key) { // 148
var self = this; // 149
if (!(key in self.keyDeps)) { // 150
self.keyDeps[key] = new Tracker.Dependency; // 151
self.keyValueDeps[key] = {}; // 152
} // 153
}, // 154
// 155
// Get a JSON value that can be passed to the constructor to // 156
// create a new ReactiveDict with the same contents as this one // 157
_getMigrationData: function () { // 158
// XXX sanitize and make sure it's JSONible? // 159
return this.keys; // 160
} // 161
}); // 162
// 163
//////////////////////////////////////////////////////////////////////////////////////////
}).call(this);
(function () {
//////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/reactive-dict/migration.js //
// //
//////////////////////////////////////////////////////////////////////////////////////////
//
ReactiveDict._migratedDictData = {}; // name -> data // 1
ReactiveDict._dictsToMigrate = {}; // name -> ReactiveDict // 2
// 3
ReactiveDict._loadMigratedDict = function (dictName) { // 4
if (_.has(ReactiveDict._migratedDictData, dictName)) // 5
return ReactiveDict._migratedDictData[dictName]; // 6
// 7
return null; // 8
}; // 9
// 10
ReactiveDict._registerDictForMigrate = function (dictName, dict) { // 11
if (_.has(ReactiveDict._dictsToMigrate, dictName)) // 12
throw new Error("Duplicate ReactiveDict name: " + dictName); // 13
// 14
ReactiveDict._dictsToMigrate[dictName] = dict; // 15
}; // 16
// 17
if (Meteor.isClient && Package.reload) { // 18
// Put old migrated data into ReactiveDict._migratedDictData, // 19
// where it can be accessed by ReactiveDict._loadMigratedDict. // 20
var migrationData = Package.reload.Reload._migrationData('reactive-dict'); // 21
if (migrationData && migrationData.dicts) // 22
ReactiveDict._migratedDictData = migrationData.dicts; // 23
// 24
// On migration, assemble the data from all the dicts that have been // 25
// registered. // 26
Package.reload.Reload._onMigrate('reactive-dict', function () { // 27
var dictsToMigrate = ReactiveDict._dictsToMigrate; // 28
var dataToMigrate = {}; // 29
// 30
for (var dictName in dictsToMigrate) // 31
dataToMigrate[dictName] = dictsToMigrate[dictName]._getMigrationData(); // 32
// 33
return [true, {dicts: dataToMigrate}]; // 34
}); // 35
} // 36
// 37
//////////////////////////////////////////////////////////////////////////////////////////
}).call(this);
/* Exports */
if (typeof Package === 'undefined') Package = {};
Package['reactive-dict'] = {
ReactiveDict: ReactiveDict
};
})();