UNPKG

svelte-asyncable

Version:

Super tiny, declarative, optimistic, async store for SvelteJS.

85 lines (74 loc) 2.23 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('svelte/store')) : typeof define === 'function' && define.amd ? define(['exports', 'svelte/store'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.asyncable = {}, global.store)); }(this, (function (exports, store) { 'use strict'; function asyncable(getter, setter = () => {}, stores = []) { let resolve; const initial = new Promise((res) => (resolve = res)); const derived$ = store.derived(stores, (values) => values); const store$ = store.writable(initial, (set) => { return derived$.subscribe(async (values = []) => { let value = getter(...values); if (value === undefined) return; value = Promise.resolve(value); set(value); resolve(value); }); }); async function set(newValue, oldValue) { if (newValue === oldValue) return; store$.set(Promise.resolve(newValue)); try { await setter(newValue, oldValue); } catch (err) { store$.set(Promise.resolve(oldValue)); throw err; } } return { subscribe: store$.subscribe, async update(reducer) { if (!setter) return; let oldValue; let newValue; try { oldValue = await store.get(store$); newValue = await reducer(shallowCopy(oldValue)); } finally { await set(newValue, oldValue); } }, async set(newValue) { if (!setter) return; let oldValue; try { oldValue = await store.get(store$); newValue = await newValue; } finally { await set(newValue, oldValue); } }, get() { return store.get(store$); }, }; } function syncable(stores, initialValue) { return store.derived( stores, ($values, set) => (Array.isArray(stores) ? Promise.allSettled : Promise.resolve) .call(Promise, $values) .then(set), initialValue ); } function shallowCopy(value) { if (typeof value !== 'object' || value === null) return value; return Array.isArray(value) ? [...value] : { ...value }; } exports.asyncable = asyncable; exports.syncable = syncable; Object.defineProperty(exports, '__esModule', { value: true }); })));