UNPKG

@thepassle/app-tools

Version:

Collection of tools I regularly use to build apps. Maybe they're useful to somebody else. Maybe not. Most of these are thin wrappers around native API's, like the native `<dialog>` element, `fetch` API, and `URLPattern`.

83 lines (71 loc) 2.08 kB
import { when } from './index.js'; export function createService(defaults) { return class Service { constructor(host, promise) { (this.host = host).addController(this); this.promise = promise; this.state = 'initialized'; } setPromise(promise) { this.promise = promise; } setError(msg) { this.errorMessage = msg; this.state = 'error'; this.host.requestUpdate(); } request(params) { this.state = 'pending'; this.host.requestUpdate(); return this.promise(params) .then(data => { this.state = 'success'; this.data = data; this.host.requestUpdate(); return data; }) .catch(e => { this.errorMessage = e?.message; this.state = 'error'; this.host.requestUpdate(); throw e; }); } /** * Use states individually, useful if you may need to render stuff in different locations */ initialized(templateFn) { return when(this.state === 'initialized', templateFn || defaults.initialized); } pending(templateFn) { return when(this.state === 'pending', templateFn || defaults.pending); } success(templateFn) { const template = templateFn || defaults.success; return when(this.state === 'success', () => template(this.data)); } error(templateFn) { const template = templateFn || defaults.error; return when(this.state === 'error', () => template(this.errorMessage)); } /** * Combined render method, if you want to just render everything in place */ render(templates) { const states = { ...defaults, ...templates, } switch(this.state) { case 'initialized': return states.initialized(); case 'pending': return states.pending(); case 'success': return states.success(this.data); case 'error': return states.error(this.errorMessage); } } } }