| 44 | |
| 45 | /* @__NO_SIDE_EFFECTS__ */ |
| 46 | export const atom = initialValue => { |
| 47 | let listeners = [] |
| 48 | let $atom = { |
| 49 | get() { |
| 50 | if (!$atom.lc) { |
| 51 | $atom.listen(() => {})() |
| 52 | } |
| 53 | return $atom.value |
| 54 | }, |
| 55 | init: initialValue, |
| 56 | lc: 0, |
| 57 | listen(listener) { |
| 58 | $atom.lc = listeners.push(listener) |
| 59 | |
| 60 | return () => { |
| 61 | for ( |
| 62 | let i = lqIndex + QUEUE_ITEMS_PER_LISTENER; |
| 63 | i < listenerQueue.length; |
| 64 | ) { |
| 65 | if (listenerQueue[i] === listener) { |
| 66 | listenerQueue.splice(i, QUEUE_ITEMS_PER_LISTENER) |
| 67 | } else { |
| 68 | i += QUEUE_ITEMS_PER_LISTENER |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | let index = listeners.indexOf(listener) |
| 73 | if (~index) { |
| 74 | listeners.splice(index, 1) |
| 75 | if (!--$atom.lc) $atom.off() |
| 76 | } |
| 77 | } |
| 78 | }, |
| 79 | notify(oldValue, changedKey) { |
| 80 | nanostoresGlobal.epoch++ |
| 81 | let runListenerQueue = !listenerQueue.length && !batchSeen |
| 82 | for (let listener of listeners) { |
| 83 | if (batchSeen?.has(listener)) continue |
| 84 | batchSeen?.add(listener) |
| 85 | listenerQueue.push( |
| 86 | listener, |
| 87 | $atom, |
| 88 | oldValue, |
| 89 | batchSeen ? undefined : changedKey |
| 90 | ) |
| 91 | } |
| 92 | |
| 93 | if (runListenerQueue) { |
| 94 | drainQueue() |
| 95 | } |
| 96 | }, |
| 97 | /* It will be called on last listener unsubscribing. |
| 98 | We will redefine it in onMount and onStop. */ |
| 99 | off() {}, |
| 100 | set(newValue) { |
| 101 | let oldValue = $atom.value |
| 102 | if (oldValue !== newValue) { |
| 103 | $atom.value = newValue |