UNPKG

nanostores

Version:

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

93 lines (83 loc) 2.16 kB
import { clean } from '../clean-stores/index.js' let listenerQueue = [] let lqIndex = 0 const QUEUE_ITEMS_PER_LISTENER = 4 export let epoch = 0 export let atom = initialValue => { let listeners = [] let $atom = { get() { if (!$atom.lc) { $atom.listen(() => {})() } return $atom.value }, lc: 0, listen(listener) { $atom.lc = listeners.push(listener) return () => { for ( let i = lqIndex + QUEUE_ITEMS_PER_LISTENER; i < listenerQueue.length; ) { if (listenerQueue[i] === listener) { listenerQueue.splice(i, QUEUE_ITEMS_PER_LISTENER) } else { i += QUEUE_ITEMS_PER_LISTENER } } let index = listeners.indexOf(listener) if (~index) { listeners.splice(index, 1) if (!--$atom.lc) $atom.off() } } }, notify(oldValue, changedKey) { epoch++ let runListenerQueue = !listenerQueue.length for (let listener of listeners) { listenerQueue.push(listener, $atom.value, oldValue, changedKey) } if (runListenerQueue) { for ( lqIndex = 0; lqIndex < listenerQueue.length; lqIndex += QUEUE_ITEMS_PER_LISTENER ) { listenerQueue[lqIndex]( listenerQueue[lqIndex + 1], listenerQueue[lqIndex + 2], listenerQueue[lqIndex + 3] ) } listenerQueue.length = 0 } }, /* It will be called on last listener unsubscribing. We will redefine it in onMount and onStop. */ off() {}, set(newValue) { let oldValue = $atom.value if (oldValue !== newValue) { $atom.value = newValue $atom.notify(oldValue) } }, subscribe(listener) { let unbind = $atom.listen(listener) listener($atom.value) return unbind }, value: initialValue } if (process.env.NODE_ENV !== 'production') { $atom[clean] = () => { listeners = [] $atom.lc = 0 $atom.off() } } return $atom } export const readonlyType = store => store