Last active
August 29, 2015 14:09
-
-
Save mndvns/3b56303d252c85b6b04f to your computer and use it in GitHub Desktop.
This file contains 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
/** | |
* Module dependencies | |
*/ | |
var pkg = require('../package'); | |
var Emitter = require('emitter'); | |
var parseLinks = require('links-parser'); | |
// set the default api path to '/api' | |
var loc = window.location; | |
var base = loc.protocol + '//' + loc.host; | |
pkg.value('hyperHttpRoot', base + '/api'); | |
// list of headers to check for refreshes | |
pkg.value('hyperHttpRefreshHeaders', [ | |
'location', | |
'content-location' | |
]); | |
/** | |
* hyper backend http service | |
*/ | |
pkg.factory('hyperBackend', [ | |
'$http', | |
'$exceptionHandler', | |
'hyperHttpRoot', | |
'hyperHttpEmitter', | |
'hyperHttpRefreshHeaders', | |
'$cacheFactory', | |
function($http, $exceptionHandler, rootHref, emitter, refreshHeaders, $cache) { | |
var cache = $cache('hyperHttpCache'); | |
return { | |
root: root, | |
get: get, | |
submit: submit | |
}; | |
function root(fn) { | |
return get(rootHref, fn); | |
} | |
function get(href, fn) { | |
// strip any hashes | |
href = href.replace(/#.*/, ''); | |
return emitter(href, get(true)); | |
function get(recurse) { | |
return function(body) { | |
// The emitter just sent us a new response | |
// We want everyone to have thier own copies as well | |
if (body) return fn(null, angular.copy(body)); | |
$http | |
.get(href, {cache: cache}) | |
.success(function(body, status, headers) { | |
var links = {}; | |
try { | |
links = parseLinks(headers('link')); | |
} catch (e) { | |
$exceptionHandler(e); | |
} | |
if (recurse && | |
typeof body.href === 'string' && | |
href !== body.href) emitter(body.href, get()); | |
fn(null, body, links); | |
}) | |
.error(function(err, status) { | |
// Just return an empty body if it's not found | |
if (status === 404) return fn(); | |
$exceptionHandler(err); | |
}); | |
}; | |
} | |
}; | |
function submit(method, action, data, fn, disableRefresh) { | |
method = method.toUpperCase(); | |
var req = {method: method, url: action}; | |
if (method === 'GET') req.params = data; | |
else req.data = data; | |
$http(req) | |
.success(function(body, status, headers) { | |
var links = {}; | |
try { | |
links = parseLinks(headers('link')); | |
} catch (e) {} | |
fn(null, body, links); | |
if (method === 'GET') return; | |
if (!disableRefresh) emitter.refresh(action); | |
angular.forEach(refreshHeaders, function(header) { | |
var href = headers(header); | |
if (href) emitter.refresh(href); | |
}); | |
// http://tools.ietf.org/html/draft-nottingham-linked-cache-inv-03#section-3 | |
var invalidates = links.invalidates; | |
invalidates = typeof invalidates === 'string' ? [invalidates] : invalidates; | |
angular.forEach(invalidates || [], function(href) { | |
emitter.refresh(href); | |
}); | |
}) | |
.error(function(err) { | |
$exceptionHandler(err); | |
}); | |
}; | |
return root; | |
} | |
]); | |
pkg.factory('hyperHttpEmitter', [ | |
'$http', | |
'$exceptionHandler', | |
'$cacheFactory', | |
function($http, $exceptionHandler, $cache) { | |
var subs = new Emitter(); | |
var external = new Emitter(); | |
var cache; | |
function emitter(href, get) { | |
if (href.indexOf('/') === 0) href = base + href; | |
// Proxy the fn so it can be used more than once | |
function handle(err, body, links) { get(err, body, links); } | |
subs.on(href, handle); | |
get(); | |
if (subs.listeners(href).length === 1) external.emit('subscribe', href); | |
return function() { | |
subs.off(href, handle); | |
if (!subs.hasListeners(href)) external.emit('unsubscribe', href); | |
}; | |
}; | |
emitter.refresh = function (href) { | |
if (!cache) cache = $cache.get('hyperHttpCache'); | |
// bust the cache for everyone | |
cache.remove(href); | |
var req = { | |
headers: { | |
'cache-control': 'no-cache' | |
}, | |
cache: false | |
}; | |
$http.get(href, req) | |
.success(function(body, status, headers) { | |
subs.emit(href, body); | |
}) | |
.error(function(err) { | |
$exceptionHandler(err); | |
}); | |
}; | |
emitter.subscribe = function(fn) { | |
external.on('subscribe', fn); | |
}; | |
emitter.unsubscribe = function(fn) { | |
external.on('unsubscribe', fn); | |
}; | |
return emitter; | |
} | |
]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment