@livelike/react-native
Version:
LiveLike React Native package
49 lines (46 loc) • 1.37 kB
text/typescript
export type LLStoreUnsubscriber = () => void;
export type LLStoreListener<TValue> = (value: TValue) => void;
export type LLStore<TValue> = {
value: TValue;
get: () => TValue;
set: (value: TValue) => void;
notify: () => void;
listeners: LLStoreListener<TValue>[];
subscribe: (cb: LLStoreListener<TValue>) => LLStoreUnsubscriber;
};
export function createStore<StoreValue>(initialValue: StoreValue) {
const store = {
value: initialValue,
listeners: [],
set: (updateValue: StoreValue) => {
store.value = updateValue;
store.notify();
},
get: () => {
return store.value;
},
notify: () => {
if (store.listeners.length) {
const newValue = store.get();
try {
store.listeners.forEach((cb) => cb(newValue));
} catch (error) {
console.error('Error while calling banner subscribers', error);
}
}
},
subscribe: (cb: LLStoreListener<StoreValue>) => {
const cbIndex = store.listeners.findIndex((_cb) => _cb === cb);
if (cbIndex < 0) {
store.listeners = [...store.listeners, cb];
} else {
store.listeners = [...store.listeners];
store.listeners.splice(cbIndex, 1, cb);
}
return () => {
store.listeners = store.listeners.filter((_cb) => _cb !== cb);
};
},
};
return store;
}