UNPKG

nanostores

Version:

A tiny (294 bytes) state manager for React/Preact/Vue/Svelte with many atomic tree-shakable stores

66 lines (58 loc) 1.74 kB
import { atom, nanostoresGlobal } from '../atom/index.js' import { onMount } from '../lifecycle/index.js' import { warn } from '../warn/index.js' let computedStore = (stores, cb, batched) => { if (!Array.isArray(stores)) stores = [stores] let previousArgs let currentEpoch let set = () => { if (currentEpoch === nanostoresGlobal.epoch) return currentEpoch = nanostoresGlobal.epoch let args = stores.map($store => $store.get()) if (!previousArgs || args.some((arg, i) => arg !== previousArgs[i])) { previousArgs = args let value = cb(...args) if (value && value.then && value.t) { if (process.env.NODE_ENV !== 'production') { warn( 'Use @nanostores/async for async computed. We will remove Promise support in computed() in Nano Stores 2.0' ) } value.then(asyncValue => { if (previousArgs === args) { // Prevent a stale set $computed.set(asyncValue) } }) } else { $computed.set(value) currentEpoch = nanostoresGlobal.epoch } } } let $computed = atom(undefined) let get = $computed.get $computed.get = () => { set() return get() } let timer let run = batched ? () => { clearTimeout(timer) timer = setTimeout(set) } : set onMount($computed, () => { let unbinds = stores.map($store => $store.listen(run)) set() return () => { for (let unbind of unbinds) unbind() } }) return $computed } /* @__NO_SIDE_EFFECTS__ */ export const computed = (stores, fn) => computedStore(stores, fn) /* @__NO_SIDE_EFFECTS__ */ export const batched = (stores, fn) => computedStore(stores, fn, true)