From f6aabffab3652bb9dbf2efb370013d2941a51d95 Mon Sep 17 00:00:00 2001
From: David Greenspan
Date: Mon, 25 Feb 2013 17:52:51 -0800
Subject: [PATCH] port all packages to new Deps (tests pass)
---
packages/accounts-base/accounts_client.js | 12 +-
packages/accounts-password/password_tests.js | 4 +-
.../login_buttons_dropdown.js | 8 +-
packages/deps/deps.js | 14 +-
packages/deps/deps_tests.js | 40 +-
packages/deps/package.js | 2 +-
packages/livedata/livedata_connection.js | 88 ++-
.../livedata/livedata_connection_tests.js | 10 +-
packages/meteor/timers.js | 2 +-
packages/minimongo/minimongo.js | 35 +-
packages/past/past.js | 6 +-
packages/session/session.js | 41 +-
packages/session/session_tests.js | 32 +-
packages/spark/spark.js | 22 +-
packages/spark/spark_tests.js | 500 +++++++++---------
packages/spiderable/spiderable.js | 2 +-
packages/stream/stream_client.js | 6 +-
packages/templating/templating_tests.js | 128 ++---
packages/test-helpers/onscreendiv.js | 4 +-
packages/test-helpers/reactivevar.js | 9 +-
packages/test-helpers/wrappedfrag.js | 2 +-
packages/test-in-browser/driver.js | 51 +-
22 files changed, 506 insertions(+), 512 deletions(-)
diff --git a/packages/accounts-base/accounts_client.js b/packages/accounts-base/accounts_client.js
index ba462f9f0a..1e260551c6 100644
--- a/packages/accounts-base/accounts_client.js
+++ b/packages/accounts-base/accounts_client.js
@@ -6,18 +6,18 @@
};
var loggingIn = false;
- var loggingInListeners = new Meteor.deps._ContextSet;
+ var loggingInVar = new Deps.Variable;
// This is mostly just called within this file, but Meteor.loginWithPassword
// also uses it to make loggingIn() be true during the beginPasswordExchange
// method call too.
Accounts._setLoggingIn = function (x) {
if (loggingIn !== x) {
loggingIn = x;
- loggingInListeners.invalidateAll();
+ loggingInVar.changed();
}
};
Meteor.loggingIn = function () {
- loggingInListeners.addCurrentContext();
+ loggingInVar.changed();
return loggingIn;
};
@@ -181,10 +181,10 @@
// XXX this can be simplified if we merge in
// https://github.com/meteor/meteor/pull/273
var loginServicesConfigured = false;
- var loginServicesConfiguredListeners = new Meteor.deps._ContextSet;
+ var loginServicesConfiguredVar = new Deps.Variable;
Meteor.subscribe("meteor.loginServiceConfiguration", function () {
loginServicesConfigured = true;
- loginServicesConfiguredListeners.invalidateAll();
+ loginServicesConfiguredVar.changed();
});
// A reactive function returning whether the
@@ -196,7 +196,7 @@
return true;
// not yet complete, save the context for invalidation once we are.
- loginServicesConfiguredListeners.addCurrentContext();
+ Deps.depend(loginServicesConfiguredVar);
return false;
};
})();
diff --git a/packages/accounts-password/password_tests.js b/packages/accounts-password/password_tests.js
index f5ad41eaf0..067774d0c1 100644
--- a/packages/accounts-password/password_tests.js
+++ b/packages/accounts-password/password_tests.js
@@ -54,7 +54,7 @@ if (Meteor.isClient) (function () {
// Set up a reactive context that only refreshes when Meteor.user() is
// invalidated.
var loaded = false;
- var handle = Meteor.autorun(function () {
+ var handle = Deps.autorun(function () {
if (Meteor.user() && Meteor.user().emails)
loaded = true;
});
@@ -66,7 +66,7 @@ if (Meteor.isClient) (function () {
// By the time of the login callback, the user should be loaded.
test.isTrue(Meteor.user().emails);
// Flushing should get us the autorun as well.
- Meteor.flush();
+ Deps.flush();
test.isTrue(loaded);
handle.stop();
}));
diff --git a/packages/accounts-ui-unstyled/login_buttons_dropdown.js b/packages/accounts-ui-unstyled/login_buttons_dropdown.js
index 5eee397499..12007dade9 100644
--- a/packages/accounts-ui-unstyled/login_buttons_dropdown.js
+++ b/packages/accounts-ui-unstyled/login_buttons_dropdown.js
@@ -7,7 +7,7 @@
Template._loginButtons.events({
'click #login-name-link, click #login-sign-in-link': function () {
loginButtonsSession.set('dropdownVisible', true);
- Meteor.flush();
+ Deps.flush();
correctDropdownZIndexes();
},
'click .login-close-text': function () {
@@ -85,7 +85,7 @@
loginButtonsSession.set('inSignupFlow', true);
loginButtonsSession.set('inForgotPasswordFlow', false);
// force the ui to update so that we have the approprate fields to fill in
- Meteor.flush();
+ Deps.flush();
// update new fields with appropriate defaults
if (username !== null)
@@ -121,7 +121,7 @@
loginButtonsSession.set('inSignupFlow', false);
loginButtonsSession.set('inForgotPasswordFlow', true);
// force the ui to update so that we have the approprate fields to fill in
- Meteor.flush();
+ Deps.flush();
// update new fields with appropriate defaults
if (email !== null)
@@ -141,7 +141,7 @@
loginButtonsSession.set('inSignupFlow', false);
loginButtonsSession.set('inForgotPasswordFlow', false);
// force the ui to update so that we have the approprate fields to fill in
- Meteor.flush();
+ Deps.flush();
if (document.getElementById('login-username'))
document.getElementById('login-username').value = username;
diff --git a/packages/deps/deps.js b/packages/deps/deps.js
index bed95aa7e8..a740ffd89e 100644
--- a/packages/deps/deps.js
+++ b/packages/deps/deps.js
@@ -27,7 +27,7 @@
this.invalidated = false;
};
- _.extend(Computation.prototype, {
+ _.extend(Deps.Computation.prototype, {
run: function (f) {
var previous = Deps.currentComputation;
Deps.currentComputation = this;
@@ -60,8 +60,10 @@
this._callbacks.push(f);
},
+ // Make this computation depend on v. Return true
+ // if this is a new dependency.
depend: function (v) {
- v._addDependent(this);
+ return v._addDependent(this);
}
});
@@ -69,7 +71,7 @@
this._dependentsById = {};
};
- _.extend(Variable.prototype, {
+ _.extend(Deps.Variable.prototype, {
// Adds `computation` to this set if it is not already
// present. Returns true if `computation` is a new member of the set.
_addDependent: function (computation) {
@@ -98,9 +100,13 @@
});
_.extend(Deps, {
+ // Make the current computation depend on v. Returns true
+ // if this is a new dependency. If there is no current
+ // computation, does nothing and returns false.
depend: function (v) {
if (Deps.active)
- v._addDependent(Deps.currentComputation);
+ return v._addDependent(Deps.currentComputation);
+ return false;
},
flush: function () {
diff --git a/packages/deps/deps_tests.js b/packages/deps/deps_tests.js
index 63e4e718ef..f04f2823bb 100644
--- a/packages/deps/deps_tests.js
+++ b/packages/deps/deps_tests.js
@@ -1,46 +1,46 @@
Tinytest.add('deps - autorun', function (test) {
- var listeners = new Meteor.deps._ContextSet;
+ var v = new Deps.Variable;
var x = 0;
- var handle = Meteor.autorun(function (handle) {
- listeners.addCurrentContext();
+ var handle = Deps.autorun(function (handle) {
+ Deps.depend(v);
++x;
});
test.equal(x, 1);
- Meteor.flush();
+ Deps.flush();
test.equal(x, 1);
- listeners.invalidateAll();
+ v.changed();
test.equal(x, 1);
- Meteor.flush();
+ Deps.flush();
test.equal(x, 2);
- listeners.invalidateAll();
+ v.changed();
test.equal(x, 2);
- Meteor.flush();
+ Deps.flush();
test.equal(x, 3);
- listeners.invalidateAll();
+ v.changed();
// Prevent the function from running further.
handle.stop();
- Meteor.flush();
+ Deps.flush();
test.equal(x, 3);
- listeners.invalidateAll();
- Meteor.flush();
+ v.changed();
+ Deps.flush();
test.equal(x, 3);
- Meteor.autorun(function (internalHandle) {
- listeners.addCurrentContext();
+ Deps.autorun(function (internalHandle) {
+ Deps.depend(v);
++x;
if (x == 6)
internalHandle.stop();
});
test.equal(x, 4);
- listeners.invalidateAll();
- Meteor.flush();
+ v.changed();
+ Deps.flush();
test.equal(x, 5);
- listeners.invalidateAll();
+ v.changed();
// Increment to 6 and stop.
- Meteor.flush();
+ Deps.flush();
test.equal(x, 6);
- listeners.invalidateAll();
- Meteor.flush();
+ v.changed();
+ Deps.flush();
// Still 6!
test.equal(x, 6);
});
diff --git a/packages/deps/package.js b/packages/deps/package.js
index a38a57f69e..2e13963124 100644
--- a/packages/deps/package.js
+++ b/packages/deps/package.js
@@ -9,7 +9,7 @@ Package.on_use(function (api, where) {
where = where || ['client', 'server'];
api.use('underscore', where);
- api.add_files(['deps.js', 'deps-utils.js'], where);
+ api.add_files(['deps.js'], where);
});
Package.on_test(function (api) {
diff --git a/packages/livedata/livedata_connection.js b/packages/livedata/livedata_connection.js
index 7bf2cfebe1..b10620df31 100644
--- a/packages/livedata/livedata_connection.js
+++ b/packages/livedata/livedata_connection.js
@@ -145,7 +145,8 @@ Meteor._LivedataConnection = function (url, options) {
// - id
// - name
// - params
- // - context (the Context in which Meteor.subscribe was called, if any)
+ // - computation (the Deps.Computation in which Meteor.subscribe was
+ // called, if any)
// - ready (has the 'ready' message been received?)
// - readyCallback (an optional callback to call when ready)
// - errorCallback (an optional callback to call if the sub terminates with
@@ -158,7 +159,7 @@ Meteor._LivedataConnection = function (url, options) {
// Reactive userId.
self._userId = null;
- self._userIdListeners = Meteor.deps && new Meteor.deps._ContextSet;
+ self._userIdVar = (typeof Deps !== "undefined") && new Deps.Variable;
// Block auto-reload while we're waiting for method responses.
if (!options.reloadWithOutstanding) {
@@ -426,10 +427,10 @@ _.extend(Meteor._LivedataConnection.prototype, {
}
// Is there an existing sub with the same name and param, run in an
- // invalidated Context? This can only happen if the context just got
- // invalidated and we haven't fully finished a round of Meteor.flush()
+ // invalidated Computation? This can only happen if the computation just got
+ // invalidated and we haven't fully finished a round of Deps.flush()
// yet. For example, this will happen with the pattern of:
- // Meteor.autorun(function () {
+ // Deps.autorun(function () {
// Meteor.subscribe("foo", Session.get("foo"));
// Meteor.subscribe("bar", Session.get("bar"));
// });
@@ -440,16 +441,16 @@ _.extend(Meteor._LivedataConnection.prototype, {
// being invalidated, we will require N matching subscribe calls to keep
// them all active.
var existing = _.find(self._subscriptions, function (sub) {
- return sub.context && sub.context.invalidated && sub.name === name &&
- EJSON.equals(sub.params, params);
+ return sub.computation && sub.computation.invalidated &&
+ sub.name === name && EJSON.equals(sub.params, params);
});
- var currentContext = Meteor.deps && Meteor.deps.Context.current;
+ var currentComputation = Deps.currentComputation;
var id;
if (existing) {
id = existing.id;
- // Substitute our current context (if any) for the one on the sub.
- existing.context = currentContext;
+ // Substitute our current computation (if any) for the one on the sub.
+ existing.computation = currentComputation;
if (callbacks.onReady) {
// If the sub is not already ready, replace any ready callback with the
@@ -472,9 +473,9 @@ _.extend(Meteor._LivedataConnection.prototype, {
id: id,
name: name,
params: params,
- context: currentContext,
+ computation: currentComputation,
ready: false,
- readyListeners: Meteor.deps && new Meteor.deps._ContextSet,
+ readyVar: (typeof Deps !== "undefined") && new Deps.Variable,
readyCallback: callbacks.onReady,
errorCallback: callbacks.onError
};
@@ -494,37 +495,34 @@ _.extend(Meteor._LivedataConnection.prototype, {
if (!_.has(self._subscriptions, id))
return false;
var record = self._subscriptions[id];
- record.readyListeners && record.readyListeners.addCurrentContext();
+ record.readyVar && Deps.depend(record.readyVar);
return record.ready;
}
};
- if (currentContext) {
- // We're in a reactive context, so we'd like to unsubscribe when the
- // context is invalidated... but not if some *OTHER* onInvalidate callback
- // on currentContext re-subscribes to the same subscription (eg, as part
- // of an autorun). Meteor.flush guarantees that it won't interleave calls
- // to currentContext's callbacks and unsubscribeContext's callbacks, so
- // this ensures that by the time unsubscribeContext's onInvalidate
- // callback is called, we've already re-run the autorun function (if this
- // was an autorun context).
- var unsubscribeContext = new Meteor.deps.Context;
- unsubscribeContext.onInvalidate(function () {
- // Did we already unsubscribe from this? Do nothing.
- if (!_.has(self._subscriptions, id))
- return;
- // Did we substitute a new context in for this constitute in the
- // "Substitute" block above? (eg, are we in an autorun and the re-run of
- // the function subscribed to this again?)
- if (self._subscriptions[id].context !== currentContext)
- return;
- // Nope, the only reason we are currently subscribed to this
- // subscription is that *THIS* subscribe call wanted it to be so, and
- // its context is invalidated, so it's time to unsubscribe.
- handle.stop();
- });
- currentContext.onInvalidate(function () {
- unsubscribeContext.invalidate();
+ if (currentComputation) {
+ // We're in a reactive computation, so we'd like to unsubscribe when the
+ // computation is invalidated... but not if some *OTHER* onInvalidate
+ // callback on currentComputation re-subscribes to the same subscription
+ // (eg, as part of a Deps.autorun). Use Deps.afterFlush to schedule
+ // this check to happen later in the flush cycle, after all of
+ // currentComputation's callbacks have been called, and therefore after
+ // the current Deps.autorun (if any) has been re-run.
+ currentComputation.onInvalidate(function () {
+ Deps.afterFlush(function () {
+ // Did we already unsubscribe from this? Do nothing.
+ if (!_.has(self._subscriptions, id))
+ return;
+ // Did we substitute a new computation in for this constitute in the
+ // "Substitute" block above? (eg, are we in an autorun and the re-run of
+ // the function subscribed to this again?)
+ if (self._subscriptions[id].computation !== currentComputation)
+ return;
+ // Nope, the only reason we are currently subscribed to this
+ // subscription is that *THIS* subscribe call wanted it to be so, and
+ // its computation is invalidated, so it's time to unsubscribe.
+ handle.stop();
+ });
});
}
@@ -785,19 +783,19 @@ _.extend(Meteor._LivedataConnection.prototype, {
///
userId: function () {
var self = this;
- if (self._userIdListeners)
- self._userIdListeners.addCurrentContext();
+ if (self._userIdVar)
+ Deps.depend(self._userIdVar);
return self._userId;
},
setUserId: function (userId) {
var self = this;
- // Avoid invalidating listeners if setUserId is called with current value.
+ // Avoid invalidating dependents if setUserId is called with current value.
if (self._userId === userId)
return;
self._userId = userId;
- if (self._userIdListeners)
- self._userIdListeners.invalidateAll();
+ if (self._userIdVar)
+ self._userIdVar.changed();
},
// Returns true if we are in a state after reconnect of waiting for subs to be
@@ -1116,7 +1114,7 @@ _.extend(Meteor._LivedataConnection.prototype, {
return;
subRecord.readyCallback && subRecord.readyCallback();
subRecord.ready = true;
- subRecord.readyListeners && subRecord.readyListeners.invalidateAll();
+ subRecord.readyVar && subRecord.readyVar.changed();
});
});
},
diff --git a/packages/livedata/livedata_connection_tests.js b/packages/livedata/livedata_connection_tests.js
index d3ae5187b2..5984ffa7ab 100644
--- a/packages/livedata/livedata_connection_tests.js
+++ b/packages/livedata/livedata_connection_tests.js
@@ -115,7 +115,7 @@ Tinytest.add("livedata stub - subscribe", function (test) {
test.equal(message, {msg: 'sub', name: 'my_data', params: []});
var reactivelyReady = false;
- var autorunHandle = Meteor.autorun(function () {
+ var autorunHandle = Deps.autorun(function () {
reactivelyReady = sub.ready();
});
test.isFalse(reactivelyReady);
@@ -123,7 +123,7 @@ Tinytest.add("livedata stub - subscribe", function (test) {
// get the sub satisfied. callback fires.
stream.receive({msg: 'ready', 'subs': [id]});
test.isTrue(callback_fired);
- Meteor.flush();
+ Deps.flush();
test.isTrue(reactivelyReady);
autorunHandle.stop();
@@ -165,7 +165,7 @@ Tinytest.add("livedata stub - reactive subscribe", function (test) {
// Subscribe to some subs.
var stopperHandle;
- var autorunHandle = Meteor.autorun(function () {
+ var autorunHandle = Deps.autorun(function () {
conn.subscribe("foo", rFoo.get(), onReady(rFoo.get()));
conn.subscribe("bar", rBar.get(), onReady(rBar.get()));
conn.subscribe("completer", onReady("completer"));
@@ -216,7 +216,7 @@ Tinytest.add("livedata stub - reactive subscribe", function (test) {
// subscription should *NOT* call its new onReady callback, because we only
// call at most one onReady for a given reactively-saved subscription.
rFoo.set("foo2");
- Meteor.flush();
+ Deps.flush();
test.length(stream.sent, 3);
message = JSON.parse(stream.sent.shift());
@@ -246,7 +246,7 @@ Tinytest.add("livedata stub - reactive subscribe", function (test) {
// Shut down the autorun. This should unsub us from all current subs at flush
// time.
autorunHandle.stop();
- Meteor.flush();
+ Deps.flush();
test.length(stream.sent, 4);
// The order of unsubs here is not important.
diff --git a/packages/meteor/timers.js b/packages/meteor/timers.js
index bdaa636ef8..ac70858e23 100644
--- a/packages/meteor/timers.js
+++ b/packages/meteor/timers.js
@@ -44,7 +44,7 @@ _.extend(Meteor, {
// won't be necessary once we clobber the global setTimeout
//
// XXX consider making this guarantee ordering of defer'd callbacks, like
- // Meteor._atFlush or Node's nextTick (in practice). Then tests can do:
+ // Deps.afterFlush or Node's nextTick (in practice). Then tests can do:
// callSomethingThatDefersSomeWork();
// Meteor.defer(expect(somethingThatValidatesThatTheWorkHappened));
defer: function (f) {
diff --git a/packages/minimongo/minimongo.js b/packages/minimongo/minimongo.js
index 30bd53b08c..5d5ff1e838 100644
--- a/packages/minimongo/minimongo.js
+++ b/packages/minimongo/minimongo.js
@@ -140,11 +140,11 @@ LocalCollection.Cursor.prototype.forEach = function (callback) {
self.db_objects = self._getRawObjects(true);
if (self.reactive)
- self._markAsReactive({
- addedBefore: true,
- removed: true,
- changed: true,
- movedBefore: true});
+ self._depend({
+ addedBefore: true,
+ removed: true,
+ changed: true,
+ movedBefore: true});
while (self.cursor_pos < self.db_objects.length)
callback(EJSON.clone(self.db_objects[self.cursor_pos++]));
@@ -172,7 +172,7 @@ LocalCollection.Cursor.prototype.count = function () {
var self = this;
if (self.reactive)
- self._markAsReactive({added: true, removed: true});
+ self._depend({added: true, removed: true});
if (self.db_objects === null)
self.db_objects = self._getRawObjects(true);
@@ -339,27 +339,28 @@ LocalCollection.Cursor.prototype._getRawObjects = function (ordered) {
// XXX Maybe we need a version of observe that just calls a callback if
// anything changed.
-LocalCollection.Cursor.prototype._markAsReactive = function (options) {
+LocalCollection.Cursor.prototype._depend = function (changers) {
var self = this;
- var context = Meteor.deps.Context.current;
+ if (Deps.active) {
+ var v = new Deps.Variable;
+ Deps.depend(v);
+ var notifyChange = _.bind(v.change, v);
- if (context) {
- var invalidate = _.bind(context.invalidate, context);
- var handle;
- var newOptions = {_suppress_initial: true};
+ var options = {_suppress_initial: true};
_.each(['added', 'changed', 'removed', 'addedBefore', 'movedBefore'],
function (fnName) {
- if (options[fnName])
- newOptions[fnName] = invalidate;
- });
- handle = self.observeChanges(newOptions);
+ if (changers[fnName])
+ options[fnName] = notifyChange;
+ });
+
+ var handle = self.observeChanges(options);
// XXX in many cases, the query will be immediately
// recreated. so we might want to let it linger for a little
// while and repurpose it if it comes back. this will save us
// work because we won't have to redo the initial find.
- context.onInvalidate(handle.stop);
+ Deps.currentComputation.onInvalidate(handle.stop);
}
};
diff --git a/packages/past/past.js b/packages/past/past.js
index 45b9b4fb66..ebc4fdbb6c 100644
--- a/packages/past/past.js
+++ b/packages/past/past.js
@@ -1,8 +1,8 @@
// Old under_score version of camelCase public API names.
Meteor.is_client = Meteor.isClient;
Meteor.is_server = Meteor.isServer;
-Meteor.deps.Context.prototype.on_invalidate =
- Meteor.deps.Context.prototype.onInvalidate;
+//Meteor.deps.Context.prototype.on_invalidate =
+// Meteor.deps.Context.prototype.onInvalidate;
// See also the "this.is_simulation" assignment in livedata/livedata_common.js
// and the retry_count and retry_time fields of self.current_status in
// stream/stream_client.js.
@@ -10,7 +10,7 @@ Meteor.deps.Context.prototype.on_invalidate =
// We used to require a special "autosubscribe" call to reactively subscribe to
// things. Now, it works with autorun.
-Meteor.autosubscribe = Meteor.autorun;
+Meteor.autosubscribe = Deps.autorun;
// Instead of the "random" package with Random.id(), we used to have this
// Meteor.uuid() implementing the RFC 4122 v4 UUID.
diff --git a/packages/session/session.js b/packages/session/session.js
index 226668cec0..9a42518a67 100644
--- a/packages/session/session.js
+++ b/packages/session/session.js
@@ -15,8 +15,8 @@
Session = _.extend({}, {
keys: {}, // key -> value
- keyDeps: {}, // key -> _ContextSet
- keyValueDeps: {}, // key -> value -> _ContextSet
+ keyVars: {}, // key -> Variable
+ keyValueVars: {}, // key -> value -> Variable
set: function (key, value) {
var self = this;
@@ -29,14 +29,14 @@
return;
self.keys[key] = value;
- var invalidateAll = function (cset) {
- cset && cset.invalidateAll();
+ var changed = function (v) {
+ v && v.changed();
};
- invalidateAll(self.keyDeps[key]);
- if (self.keyValueDeps[key]) {
- invalidateAll(self.keyValueDeps[key][oldSerializedValue]);
- invalidateAll(self.keyValueDeps[key][value]);
+ changed(self.keyVars[key]);
+ if (self.keyValueVars[key]) {
+ changed(self.keyValueVars[key][oldSerializedValue]);
+ changed(self.keyValueVars[key][value]);
}
},
@@ -53,19 +53,18 @@
get: function (key) {
var self = this;
self._ensureKey(key);
- self.keyDeps[key].addCurrentContext();
+ Deps.depend(self.keyVars[key]);
return parse(self.keys[key]);
},
equals: function (key, value) {
var self = this;
- var context = Meteor.deps.Context.current;
// 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 context.) You can still use
+ // element of keyValueVars[key] to store the dependency.) You can still use
// "EJSON.equals(Session.get(key), value)".
//
// XXX we could allow arrays as long as we recursively check that there
@@ -80,19 +79,19 @@
throw new Error("Session.equals: value must be scalar");
var serializedValue = stringify(value);
- if (context) {
+ if (Deps.active) {
self._ensureKey(key);
- if (! _.has(self.keyValueDeps[key], serializedValue))
- self.keyValueDeps[key][serializedValue] = new Meteor.deps._ContextSet;
+ if (! _.has(self.keyValueVars[key], serializedValue))
+ self.keyValueVars[key][serializedValue] = new Deps.Variable;
- var isNew = self.keyValueDeps[key][serializedValue].add(context);
+ var isNew = Deps.depend(self.keyValueVars[key][serializedValue]);
if (isNew) {
- context.onInvalidate(function () {
+ Deps.currentComputation.onInvalidate(function () {
// 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].isEmpty())
- delete self.keyValueDeps[key][serializedValue];
+ if (! self.keyValueVars[key][serializedValue].hasDependents())
+ delete self.keyValueVars[key][serializedValue];
});
}
}
@@ -104,9 +103,9 @@
_ensureKey: function (key) {
var self = this;
- if (!(key in self.keyDeps)) {
- self.keyDeps[key] = new Meteor.deps._ContextSet;
- self.keyValueDeps[key] = {};
+ if (!(key in self.keyVars)) {
+ self.keyVars[key] = new Deps.Variable;
+ self.keyValueVars[key] = {};
}
}
});
diff --git a/packages/session/session_tests.js b/packages/session/session_tests.js
index 97b00d9762..f35261ca3c 100644
--- a/packages/session/session_tests.js
+++ b/packages/session/session_tests.js
@@ -105,7 +105,7 @@
Tinytest.add('session - context invalidation for get', function (test) {
var xGetExecutions = 0;
- Meteor.autorun(function () {
+ Deps.autorun(function () {
++xGetExecutions;
Session.get('x');
});
@@ -113,44 +113,44 @@
Session.set('x', 1);
// Invalidation shouldn't happen until flush time.
test.equal(xGetExecutions, 1);
- Meteor.flush();
+ Deps.flush();
test.equal(xGetExecutions, 2);
// Setting to the same value doesn't re-run.
Session.set('x', 1);
- Meteor.flush();
+ Deps.flush();
test.equal(xGetExecutions, 2);
Session.set('x', '1');
- Meteor.flush();
+ Deps.flush();
test.equal(xGetExecutions, 3);
});
Tinytest.add('session - context invalidation for equals', function (test) {
var xEqualsExecutions = 0;
- Meteor.autorun(function () {
+ Deps.autorun(function () {
++xEqualsExecutions;
Session.equals('x', 5);
});
test.equal(xEqualsExecutions, 1);
Session.set('x', 1);
- Meteor.flush();
+ Deps.flush();
// Changing undefined -> 1 shouldn't affect equals(5).
test.equal(xEqualsExecutions, 1);
Session.set('x', 5);
// Invalidation shouldn't happen until flush time.
test.equal(xEqualsExecutions, 1);
- Meteor.flush();
+ Deps.flush();
test.equal(xEqualsExecutions, 2);
Session.set('x', 5);
- Meteor.flush();
+ Deps.flush();
// Setting to the same value doesn't re-run.
test.equal(xEqualsExecutions, 2);
Session.set('x', '5');
test.equal(xEqualsExecutions, 2);
- Meteor.flush();
+ Deps.flush();
test.equal(xEqualsExecutions, 3);
Session.set('x', 5);
test.equal(xEqualsExecutions, 3);
- Meteor.flush();
+ Deps.flush();
test.equal(xEqualsExecutions, 4);
});
@@ -159,27 +159,27 @@
function (test) {
// Make sure the special casing for equals undefined works.
var yEqualsExecutions = 0;
- Meteor.autorun(function () {
+ Deps.autorun(function () {
++yEqualsExecutions;
Session.equals('y', undefined);
});
test.equal(yEqualsExecutions, 1);
Session.set('y', undefined);
- Meteor.flush();
+ Deps.flush();
test.equal(yEqualsExecutions, 1);
Session.set('y', 5);
test.equal(yEqualsExecutions, 1);
- Meteor.flush();
+ Deps.flush();
test.equal(yEqualsExecutions, 2);
Session.set('y', 3);
- Meteor.flush();
+ Deps.flush();
test.equal(yEqualsExecutions, 2);
Session.set('y', 'undefined');
- Meteor.flush();
+ Deps.flush();
test.equal(yEqualsExecutions, 2);
Session.set('y', undefined);
test.equal(yEqualsExecutions, 2);
- Meteor.flush();
+ Deps.flush();
test.equal(yEqualsExecutions, 3);
});
}());
diff --git a/packages/spark/spark.js b/packages/spark/spark.js
index 48533e30fc..1b63319728 100644
--- a/packages/spark/spark.js
+++ b/packages/spark/spark.js
@@ -352,7 +352,7 @@ var scheduleOnscreenSetup = function (frag, landmarkRanges) {
finalized = true;
};
- Meteor._atFlush(function () {
+ Deps.afterFlush(function () {
if (finalized)
return;
@@ -807,7 +807,7 @@ Spark.attachEvents = withRenderer(function (eventMap, html, _renderer) {
var landmark = (landmarkRange && landmarkRange.landmark);
// Note that the handler can do arbitrary things, like call
- // Meteor.flush() or otherwise remove and finalize parts of
+ // Deps.flush() or otherwise remove and finalize parts of
// the DOM. We can't assume `range` is valid past this point,
// and we'll check the `finalized` flag at the top of the loop.
var returnValue = callback.call(eventData, event, landmark);
@@ -837,20 +837,20 @@ Spark.isolate = function (htmlFunc) {
var range;
var firstRun = true;
var retHtml;
- Meteor.autorun(function (handle) {
+ Deps.autorun(function (handle) {
if (firstRun) {
retHtml = renderer.annotate(
htmlFunc(), Spark._ANNOTATION_ISOLATE,
function (r) {
if (! r) {
- // annotation not used; kill our context
+ // annotation not used; kill this autorun
handle.stop();
} else {
range = r;
range.finalize = function () {
// Spark.finalize() was called on our range (presumably
// because it was removed from the document.) Kill
- // this context and stop rerunning.
+ // this autorun.
handle.stop();
};
}
@@ -976,7 +976,7 @@ Spark.list = function (cursor, itemFunc, elseFunc) {
};
var later = function (f) {
- Meteor._atFlush(function () {
+ Deps.afterFlush(function () {
if (! stopped)
withEventGuard(f);
});
@@ -1155,15 +1155,9 @@ Spark.createLandmark = function (options, htmlFunc) {
landmark = new Spark.Landmark;
if (options.created) {
// Run callback outside the current Spark.isolate's deps context.
- // XXX Can't call run() on null, so this is a hack. Running inside
- // a fresh context wouldn't be equivalent.
- var oldCx = Meteor.deps.Context.current;
- Meteor.deps.Context.current = null;
- try {
+ Deps.nonreactive(function () {
options.created.call(landmark);
- } finally {
- Meteor.deps.Context.current = oldCx;
- }
+ });
}
}
notes.landmark = landmark;
diff --git a/packages/spark/spark_tests.js b/packages/spark/spark_tests.js
index 6e3acdeaa2..d0c8a55952 100644
--- a/packages/spark/spark_tests.js
+++ b/packages/spark/spark_tests.js
@@ -163,7 +163,7 @@ Tinytest.add("spark - replace tag contents", function (test) {
return R.get();
});
R.set("three four five six");
- Meteor.flush();
+ Deps.flush();
test.equal(this.div.html(), "three four five six");
});
@@ -177,7 +177,7 @@ Tinytest.add("spark - replace tag contents", function (test) {
test.equal($(this.node()).find("#morphing td").text(), "HI!");
R.set("