2 lines
8.1 KiB
Plaintext
2 lines
8.1 KiB
Plaintext
)]}'
|
|
{"version":3,"sources":["reactive-dict/reactive-dict.js","reactive-dict/migration.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yE;AACA,mE;AACA,kC;AACA,0B;AACA,uB;AACA,gC;AACA,E;AACA,mC;AACA,6D;AACA,qB;AACA,iC;AACA,E;;AAEA,mE;AACA,oC;AACA,4B;AACA,iB;AACA,uC;AACA,oD;AACA,uE;AACA,2D;AACA,iE;AACA,8C;AACA,6D;AACA,2B;AACA,Y;AACA,oE;AACA,K;AACA,U;AACA,oD;AACA,mB;AACA,G;;AAEA,yC;AACA,8C;AACA,E;;AAEA,kC;AACA,qE;AACA,8D;AACA,qC;;AAEA,sC;AACA,oB;;AAEA,qE;AACA,mC;AACA,a;AACA,K;AACA,qD;AACA,kD;AACA,0B;;AAEA,6B;;AAEA,yC;AACA,mE;AACA,qC;AACA,a;AACA,2B;;AAEA,gC;AACA,uB;AACA,M;;AAEA,+B;AACA,iC;AACA,0D;AACA,6C;AACA,K;AACA,I;;AAEA,qC;AACA,oB;AACA,iE;AACA,uF;AACA,yC;AACA,uC;AACA,2B;AACA,K;AACA,I;;AAEA,uB;AACA,oB;AACA,yB;AACA,+B;AACA,iC;AACA,I;;AAEA,iC;AACA,oB;;AAEA,+C;AACA,wB;AACA,uC;AACA,gC;AACA,K;;AAEA,wE;AACA,sE;AACA,4E;AACA,0E;AACA,+E;AACA,oD;AACA,M;AACA,2E;AACA,qB;AACA,oC;AACA,oC;AACA,qC;AACA,uC;AACA,mC;AACA,mD;AACA,uB;AACA,mE;AACA,2C;;AAEA,yB;AACA,2B;;AAEA,2D;AACA,yE;;AAEA,mE;AACA,kB;AACA,0C;AACA,2E;AACA,qD;AACA,wE;AACA,2D;AACA,W;AACA,O;AACA,K;;AAEA,6B;AACA,gE;AACA,yC;AACA,I;;AAEA,iC;AACA,oB;;AAEA,yC;AACA,2B;AACA,O;AACA,I;;AAEA,8B;AACA,oB;AACA,iC;AACA,iD;AACA,kC;AACA,K;AACA,I;;AAEA,8D;AACA,iE;AACA,kC;AACA,gD;AACA,qB;AACA,G;AACA,G;;;;;;;;;;;;;;;;;;;ACjKA,oD;AACA,0D;;AAEA,sD;AACA,sD;AACA,oD;;AAEA,c;AACA,E;;AAEA,kE;AACA,oD;AACA,gE;;AAEA,gD;AACA,E;;AAEA,wC;AACA,+D;AACA,gE;AACA,4E;AACA,2C;AACA,yD;;AAEA,sE;AACA,gB;AACA,iE;AACA,sD;AACA,2B;;AAEA,wC;AACA,6E;;AAEA,0C;AACA,K;AACA,C","file":"/packages/reactive-dict.js","sourcesContent":["// XXX come up with a serialization method which canonicalizes object key\n// order, which would allow us to use objects as values for equals.\nvar stringify = function (value) {\n if (value === undefined)\n return 'undefined';\n return EJSON.stringify(value);\n};\nvar parse = function (serialized) {\n if (serialized === undefined || serialized === 'undefined')\n return undefined;\n return EJSON.parse(serialized);\n};\n\n// XXX COMPAT WITH 0.9.1 : accept migrationData instead of dictName\nReactiveDict = function (dictName) {\n // this.keys: key -> value\n if (dictName) {\n if (typeof dictName === 'string') {\n // the normal case, argument is a string name.\n // _registerDictForMigrate will throw an error on duplicate name.\n ReactiveDict._registerDictForMigrate(dictName, this);\n this.keys = ReactiveDict._loadMigratedDict(dictName) || {};\n } else if (typeof dictName === 'object') {\n // back-compat case: dictName is actually migrationData\n this.keys = dictName;\n } else {\n throw new Error(\"Invalid ReactiveDict argument: \" + dictName);\n }\n } else {\n // no name given; no migration will be performed\n this.keys = {};\n }\n\n this.keyDeps = {}; // key -> Dependency\n this.keyValueDeps = {}; // key -> Dependency\n};\n\n_.extend(ReactiveDict.prototype, {\n // set() began as a key/value method, but we are now overloading it\n // to take an object of key/value pairs, similar to backbone\n // http://backbonejs.org/#Model-set\n\n set: function (keyOrObject, value) {\n var self = this;\n\n if ((typeof keyOrObject === 'object') && (value === undefined)) {\n self._setObject(keyOrObject);\n return;\n }\n // the input isn't an object, so it must be a key\n // and we resume with the rest of the function\n var key = keyOrObject;\n\n value = stringify(value);\n\n var oldSerializedValue = 'undefined';\n if (_.has(self.keys, key)) oldSerializedValue = self.keys[key];\n if (value === oldSerializedValue)\n return;\n self.keys[key] = value;\n\n var changed = function (v) {\n v && v.changed();\n };\n\n changed(self.keyDeps[key]);\n if (self.keyValueDeps[key]) {\n changed(self.keyValueDeps[key][oldSerializedValue]);\n changed(self.keyValueDeps[key][value]);\n }\n },\n\n setDefault: function (key, value) {\n var self = this;\n // for now, explicitly check for undefined, since there is no\n // ReactiveDict.clear(). Later we might have a ReactiveDict.clear(), in which case\n // we should check if it has the key.\n if (self.keys[key] === undefined) {\n self.set(key, value);\n }\n },\n\n get: function (key) {\n var self = this;\n self._ensureKey(key);\n self.keyDeps[key].depend();\n return parse(self.keys[key]);\n },\n\n equals: function (key, value) {\n var self = this;\n\n // Mongo.ObjectID is in the 'mongo' package\n var ObjectID = null;\n if (typeof Mongo !== 'undefined') {\n ObjectID = Mongo.ObjectID;\n }\n\n // We don't allow objects (or arrays that might include objects) for\n // .equals, because JSON.stringify doesn't canonicalize object key\n // order. (We can make equals have the right return value by parsing the\n // current value and using EJSON.equals, but we won't have a canonical\n // element of keyValueDeps[key] to store the dependency.) You can still use\n // \"EJSON.equals(reactiveDict.get(key), value)\".\n //\n // XXX we could allow arrays as long as we recursively check that there\n // are no objects\n if (typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean' &&\n typeof value !== 'undefined' &&\n !(value instanceof Date) &&\n !(ObjectID && value instanceof ObjectID) &&\n value !== null)\n throw new Error(\"ReactiveDict.equals: value must be scalar\");\n var serializedValue = stringify(value);\n\n if (Tracker.active) {\n self._ensureKey(key);\n\n if (! _.has(self.keyValueDeps[key], serializedValue))\n self.keyValueDeps[key][serializedValue] = new Tracker.Dependency;\n\n var isNew = self.keyValueDeps[key][serializedValue].depend();\n if (isNew) {\n Tracker.onInvalidate(function () {\n // clean up [key][serializedValue] if it's now empty, so we don't\n // use O(n) memory for n = values seen ever\n if (! self.keyValueDeps[key][serializedValue].hasDependents())\n delete self.keyValueDeps[key][serializedValue];\n });\n }\n }\n\n var oldValue = undefined;\n if (_.has(self.keys, key)) oldValue = parse(self.keys[key]);\n return EJSON.equals(oldValue, value);\n },\n\n _setObject: function (object) {\n var self = this;\n\n _.each(object, function (value, key){\n self.set(key, value);\n });\n },\n\n _ensureKey: function (key) {\n var self = this;\n if (!(key in self.keyDeps)) {\n self.keyDeps[key] = new Tracker.Dependency;\n self.keyValueDeps[key] = {};\n }\n },\n\n // Get a JSON value that can be passed to the constructor to\n // create a new ReactiveDict with the same contents as this one\n _getMigrationData: function () {\n // XXX sanitize and make sure it's JSONible?\n return this.keys;\n }\n});\n","ReactiveDict._migratedDictData = {}; // name -> data\nReactiveDict._dictsToMigrate = {}; // name -> ReactiveDict\n\nReactiveDict._loadMigratedDict = function (dictName) {\n if (_.has(ReactiveDict._migratedDictData, dictName))\n return ReactiveDict._migratedDictData[dictName];\n\n return null;\n};\n\nReactiveDict._registerDictForMigrate = function (dictName, dict) {\n if (_.has(ReactiveDict._dictsToMigrate, dictName))\n throw new Error(\"Duplicate ReactiveDict name: \" + dictName);\n\n ReactiveDict._dictsToMigrate[dictName] = dict;\n};\n\nif (Meteor.isClient && Package.reload) {\n // Put old migrated data into ReactiveDict._migratedDictData,\n // where it can be accessed by ReactiveDict._loadMigratedDict.\n var migrationData = Package.reload.Reload._migrationData('reactive-dict');\n if (migrationData && migrationData.dicts)\n ReactiveDict._migratedDictData = migrationData.dicts;\n\n // On migration, assemble the data from all the dicts that have been\n // registered.\n Package.reload.Reload._onMigrate('reactive-dict', function () {\n var dictsToMigrate = ReactiveDict._dictsToMigrate;\n var dataToMigrate = {};\n\n for (var dictName in dictsToMigrate)\n dataToMigrate[dictName] = dictsToMigrate[dictName]._getMigrationData();\n\n return [true, {dicts: dataToMigrate}];\n });\n}\n"]} |