UNPKG

@snipsonian/observable-state

Version:

Observable-state snippets (redux-like)

50 lines (49 loc) 2.43 kB
import isArray from '@snipsonian/core/es/is/isArray'; import extendNotificationsToTrigger from './extendNotificationsToTrigger'; export default function createStateObserverManager() { let observerCounter = 0; const observerMap = {}; return { registerObserver: ({ observerName, notificationsToObserve, onNotify, }) => { observerCounter += 1; const observer = { id: observerCounter, observerName, notify: onNotify, }; observerMap[observer.id] = Object.assign(Object.assign({}, observer), { notificationsToObserve }); return observer; }, unRegisterObserver: (observer) => { delete observerMap[observer.id]; }, notifyObserversOfStateChanges: ({ notificationsToTrigger, triggerParentNotifications, }) => { if (isArray(notificationsToTrigger) && notificationsToTrigger.length > 0) { const uniqueObserversToNotify = extendNotificationsToTrigger({ notificationsToTrigger, triggerParentNotifications, }) .reduce((accumulator, notificationToTrigger) => { const matchingObservers = Object.values(observerMap) .filter((registeredObserver) => registeredObserver.notificationsToObserve.includes(notificationToTrigger)); matchingObservers.forEach((observer) => { const alreadyFoundObserver = accumulator .find((observerToNotify) => observerToNotify.id === observer.id); if (alreadyFoundObserver) { alreadyFoundObserver.notifications.push(notificationToTrigger); } else { accumulator.push(Object.assign(Object.assign({}, observer), { notifications: [notificationToTrigger] })); } }); return accumulator; }, []); if (uniqueObserversToNotify && uniqueObserversToNotify.length > 0) { uniqueObserversToNotify.forEach((observerToNotify) => { observerToNotify.notify({ notifications: observerToNotify.notifications }); }); } } }, }; }