Various updates.

This commit is contained in:
Julien Fontanet 2015-02-10 17:12:10 +01:00
parent ce53fe5e31
commit f2323a9d19
2 changed files with 67 additions and 37 deletions

View File

@ -44,6 +44,12 @@ Collection.prototype.get = function (key) {
return this._data[key]; return this._data[key];
}; };
// Find the first entry in an index for a given value.
Collection.prototype.find = function (field, value) {
return this.where(field, value)[0];
};
// Find all entries in an index for a given value.
Collection.prototype.where = function (field, value) { Collection.prototype.where = function (field, value) {
var index = this._indexes[field]; var index = this._indexes[field];
@ -51,7 +57,7 @@ Collection.prototype.where = function (field, value) {
throw new Error('no such index'); throw new Error('no such index');
} }
return index[value]; return index[value] || [];
}; };
function unsetItemFromIndex(index, field) { function unsetItemFromIndex(index, field) {

View File

@ -201,29 +201,16 @@ function Xo(opts) {
this._auth = opts.auth; this._auth = opts.auth;
this._backOff = fibonacci(1e3); this._backOff = fibonacci(1e3);
this.objects = createCollection(objectsOptions); this.objects = createCollection(objectsOptions);
this.status = 'disconnected';
this.user = null; this.user = null;
// Promise representing the connection status. // Promise representing the connection status.
this._connection = null; this._connection = null;
this._onConnection = function () {
self._connection = self._api.call('session.signInWithPassword', {
email: self._auth.email,
password: self._auth.password,
}).then(function (user) {
self.user = user;
return self._api.call('xo.getAllObjects');
}).then(function (objects) {
self.objects.setMultiple(objects);
});
return self._connection;
};
self._api.on('disconnected', function () { self._api.on('disconnected', function () {
self._connection = null; self._connection = null;
self.objects.clear(); self.objects.clear();
self.status = 'disconnected';
}); });
self._api.on('notification', function (notification) { self._api.on('notification', function (notification) {
@ -241,30 +228,67 @@ function Xo(opts) {
}); });
} }
assign(Xo.prototype, { function tryConnect() {
connect: function () { /* jshint validthis: true */
this.status = 'connecting';
return this._api.connect().bind(this).catch(function () {
return Bluebird.delay(this._backOff.next().value).then(tryConnect);
});
}
function onSuccessfulConnection() {
/* jshint validthis: true */
// FIXME: session.signIn() should work with both token and password.
return this._api.call(
this._auth.token ?
'session.signInWithToken' :
'session.signInWithPassword',
this._auth
).bind(this).then(function (user) {
this.user = user;
this.status = 'connected';
this._api.call('xo.getAllObjects').bind(this).then(function (objects) {
this.objects.setMultiple(objects);
});
});
}
function onFailedConnection() {
/* jshint validthis: true */
this.status = 'disconnected';
}
Xo.prototype.connect = function () {
if (this._connection) { if (this._connection) {
return this._connection; return this._connection;
} }
var self = this; this._connection = tryConnect.call(this).then(
return this._api.connect().then(this._onConnection).catch(function () { onSuccessfulConnection, onFailedConnection
return Bluebird.delay(self._backOff.next().value).then(function () { );
return self.connect(); return this._connection;
}); };
});
},
call: function (method, params) {
var self = this;
return this._connect().then(function () { Xo.prototype.call = function (method, params) {
return self._api.call(method, params).catch(ConnectionLost, function () { // TODO: prevent session.*() from being because it may interfere
// with this class session management.
return this.connect().then(function () {
var self = this;
return this._api.call(method, params).catch(ConnectionLost, function () {
// Retry automatically. // Retry automatically.
return self.call(method, params); return self.call(method, params);
}); });
}); });
}, };
});
Xo.prototype.close = function () {
this._api.close();
};
exports.Xo = Xo; exports.Xo = Xo;