Last active
March 21, 2016 18:50
-
-
Save Aeon/9560807 to your computer and use it in GitHub Desktop.
faye adapter for ember-data
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require('config/adapters/faye-adapter'); | |
export default DS.FayeAdapter.extend(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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'); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What is records in "didFindAll: function(klass, records, data)"?