Skip to content

Instantly share code, notes, and snippets.

@Aeon
Last active March 21, 2016 18:50
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Aeon/9560807 to your computer and use it in GitHub Desktop.
Save Aeon/9560807 to your computer and use it in GitHub Desktop.
faye adapter for ember-data
require('config/adapters/faye-adapter');
export default DS.FayeAdapter.extend();
var get = Ember.get;
DS.FayeAdapter = DS.Adapter.extend({
defaultSerializer: '-rest',
find: function(record, id) {
var url = this.buildURL(record.constructor, id),
self = this;
return this.fayeRequest(url).then(function(data) {
self.didFind(record, id, data);
return record;
});
},
didFind: function(record, id, data) {
var rootKey = get(record.constructor, 'rootKey'),
dataToLoad = rootKey ? get(data, rootKey) : data;
record.load(id, dataToLoad);
},
findAll: function(klass, records) {
var url = this.buildURL(klass),
self = this;
return this.fayeRequest(url).then(function(data) {
self.didFindAll(klass, records, data);
return records;
});
},
didFindAll: function(klass, records, data) {
var collectionKey = get(klass, 'collectionKey'),
dataToLoad = collectionKey ? get(data, collectionKey) : data;
records.load(klass, dataToLoad);
},
findQuery: function(klass, records, params) {
var url = this.buildURL(klass),
self = this;
return this.fayeRequest(url, params).then(function(data) {
self.didFindQuery(klass, records, params, data);
return records;
});
},
didFindQuery: function(klass, records, params, data) {
var collectionKey = get(klass, 'collectionKey'),
dataToLoad = collectionKey ? get(data, collectionKey) : data;
records.load(klass, dataToLoad);
},
createRecord: function(record) {
var url = this.buildURL(record.constructor),
self = this;
return this.fayeRequest(url, {'action': 'POST', 'record': record.toJSON()}).then(
function(data) {
self.didCreateRecord(record, data);
return record;
}
);
},
didCreateRecord: function(record, data) {
var rootKey = get(record.constructor, 'rootKey'),
primaryKey = get(record.constructor, 'primaryKey'),
dataToLoad = rootKey ? get(data, rootKey) : data;
record.load(dataToLoad[primaryKey], dataToLoad);
record.didCreateRecord();
},
saveRecord: function(record) {
var primaryKey = get(record.constructor, 'primaryKey'),
url = this.buildURL(record.constructor, get(record, primaryKey)),
self = this;
return this.fayeRequest(url, {'action': 'PUT', 'record': record.toJSON()}).then(
function(data) { // TODO: Some APIs may or may not return data
self.didSaveRecord(record, data);
return record;
}
);
},
didSaveRecord: function(record, data) {
record.didSaveRecord();
},
deleteRecord: function(record) {
var primaryKey = get(record.constructor, 'primaryKey'),
url = this.buildURL(record.constructor, get(record, primaryKey)),
self = this;
return this.fayeRequest(url, {'action': 'DELETE', 'record': record.toJSON()}).then(
function(data) { // TODO: Some APIs may or may not return data
self.didDeleteRecord(record, data);
}
);
},
didDeleteRecord: function(record, data) {
record.didDeleteRecord();
},
fayeRequest: function(url, data) {
var faye = get('faye');
return new Ember.RSVP.Promise(function(resolve, reject) {
var promiseId = new Date().getTime() + Math.random();
var promiseSubscription = faye.subscribe(
'/clients/' + faye.client + '/' + promiseId,
function(message) {
console.info("Got promise resolution!");
promiseSubscription.cancel();
if(message.data.status == 200) {
resolve(message.data.data);
} else {
reject(new Error("Faye request failed with status " + message.data.status + '; response was ' + message.data.data));
}
}
);
faye.publish(url, data, {promise: promiseId});
});
},
buildURL: function(klass, id) {
var urlRoot = '/' + get(klass, 'url');
var urlSuffix = get(klass, 'urlSuffix') || '';
if (!urlRoot) { throw new Error('Ember.FayeAdapter requires a `url` property to be specified'); }
if (!Ember.isEmpty(id)) {
return urlRoot + "/" + id + urlSuffix;
} else {
return urlRoot + urlSuffix;
}
}
});
// based on http://livsey.org/blog/2013/02/10/integrating-pusher-with-ember/
App.Faye = Ember.Object.extend({
init: function() {
var _this = this;
this.service = new Faye.Client('http://localhost:9292/faye');
// TODO: review http://faye.jcoglan.com/security/authentication.html and come up with a better solution
this.client = 'web';
this.service.on('transport:down', function() {
// the client is offline
console.log('Server connection is down');
});
this.service.on('transport:up', function() {
// the client is online
console.log('Server connection is up');
});
this.service.subscribe('/clients/' + this.client, function(message) { console.warn("Got personal message!"); });
this.service.addExtension({
incoming: function(message, callback) {
console.info('faye-in: ', message);
if(message.data && message.data.eventName && message.data.data) {
console.info("Got event!");
router = _this.get("container").lookup("router:main");
try {
router.send(message.data.eventName, message.data.data);
} catch (e) {
unhandled = e.message.match(/Nothing handled the event/);
if (!unhandled) { throw e };
}
}
callback(message);
},
outgoing: function(message, callback) {
console.info("faye-out:", message);
callback(message);
}
});
},
subscribe: function(channel, handler) {
return this.service.subscribe(channel, handler);
},
publish: function(channel, message, meta) {
meta = meta != undefined ? meta : {};
var payload = $.extend(meta, {
client: this.client,
data: message
});
return this.service.publish(channel, payload);
}
});
Ember.ControllerMixin.reopen({
faye: null
});
Ember.Application.initializer({
name: "faye",
before: "store",
initialize: function(container, application) {
// use the same instance of Faye everywhere in the app
container.optionsForType('faye', { singleton: true });
// register 'faye:main' as our Faye object
container.register('faye:main', application.Faye);
// inject the Faye object into all controllers and routes
container.typeInjection('controller', 'faye', 'faye:main');
container.typeInjection('route', 'faye', 'faye:main');
application.inject('adapter', 'faye', 'faye:main');
}
});
@emorling
Copy link

What is records in "didFindAll: function(klass, records, data)"?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment