Skip to content

Instantly share code, notes, and snippets.

@SaulDoesCode
Last active February 9, 2020 15:56
Show Gist options
  • Save SaulDoesCode/e1d48e9959fc86808a2ad7bac828b60f to your computer and use it in GitHub Desktop.
Save SaulDoesCode/e1d48e9959fc86808a2ad7bac828b60f to your computer and use it in GitHub Desktop.
HTTP CLIENT: proxy powered fetch wrapper inspired by wretch, simplifying browser side http. Haal dinge met hierdie gemaklike stuk javascript http gereedskap, vireenvoudig jou, programmeering nou! N.b werk slegs op nuwer webwerf besoekers.
/*
haal.post('https://abc.xyz/', {
body: {
token: 'moocow24',
action: 'update-condition',
data: '42'
}
})
// (haal['get/post/put/patch...'] / haal)(enpoint, options)['json/text/blob...']
.json((data, res) => console.log('Good: ', data)),
.error404(res => {
console.error(`-_(*_*)_- Well that didn't work`)
})
.errorData((res, err) => {
console.error(`the response was not json.`)
})
// haal(endpoint, options).error/`error${'ArbitraryCode'}`(res => {})
.error(res => {
console.log('something fishy here')
})
*/
const haal = new Proxy((endpoint, options) => {
if (endpoint != null && endpoint.constructor === Object) {
[options, endpoint] = [endpoint, options.endpoint]
}
if (typeof options.body === 'object') {
if (!options.headers) options.headers = {}
options.headers['Content-Type'] = 'application/json'
options.body = JSON.stringify(options.body)
}
let resError, res
const setRes = r => {notifier.emit.ready(res = r)}
const init = () => {
fetch(endpoint, options).then(setRes)
}
const whenReady = fn => (
res == null ? notifier.once.ready(fn) : fn(res),
methods
)
const notifier = haal.emitter()
const methods = new Proxy({
error(code, fn, handleType) {
if (fn == null && typeof code === 'function') [fn, code] = [code, null]
if (typeof handleType === 'function') [handleType, fn] = [fn, handleType]
if (typeof code === 'string') code = code.length ? code.trim() : null
whenReady(res => {
if (!res.ok && (!code || (code == res.status))) {
typeof res[handleType] === 'function' ?
res[handleType]().then(d => fn(d, res, resError)) : fn(res, resError)
}
})
return methods
},
res: (fn, ok) => (whenReady(fn, ok), methods),
restype: (type, fn) => (
whenReady(res => res.ok && res[type]().then(
data => fn(data, res),
err => resError = err
)),
methods
)
}, {
get: (m, key) => Reflect.has(m, key) ?
m[key] :
key in Response.prototype && typeof Response.prototype[key] === 'function' ?
m.restype.bind(null, key) :
key.substring(0, 5) === 'error' ?
m.error.bind(null, key.substring(-5)) :
key.toLowerCase().includes('error') ?
(hType => m.error.bind(null, key.substring(hType.length + 5), hType))(key.toLowerCase().split('error')[0])
: undefined
})
requestIdleCallback(init)
return methods
}, {
get: (h, key) => key in h ? Reflect.get(h, key) : (endpoint, options = {}) => {
if (endpoint != null && endpoint.constructor === Object) {
[options, endpoint] = [endpoint, options.endpoint]
}
options.method = key.toUpperCase()
return haal(endpoint, options)
}
})
haal.infinify = (fn, reflect = false) => new Proxy(fn, {
get: (fn, key) => reflect && key in fn ? Reflect.get(fn, key) : fn.bind(null, key)
})
haal.emitter = (host = {}, listeners = new Map()) => Object.assign(host, {
emit: haal.infinify((event, ...data) => requestIdleCallback(() => {
if (listeners.has(event)) for (const h of listeners.get(event)) h.apply(null, data)
})),
on: haal.infinify((event, handler) => {
if (!listeners.has(event)) listeners.set(event, new Set())
listeners.get(event).add(handler)
const manager = () => host.off(event, handler)
manager.off = manager
manager.on = () => (manager(), host.on(event, handler))
manager.once = () => (manager(), host.once(event, handler))
return manager
}),
once: haal.infinify((event, handler) => host.on(event, function h() {
handler(...arguments)
host.off(event, h)
})),
off: haal.infinify((event, handler) => {
if (listeners.has(event)) {
const ls = listeners.get(event)
ls.delete(handler)
if (!ls.size) listeners.delete(event)
}
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment