Last active
February 9, 2020 15:56
-
-
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.
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
/* | |
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