This repository has been archived by the owner on Oct 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathuse-store.ts
60 lines (53 loc) · 1.94 KB
/
use-store.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import { PublicSubject } from '../../services/stores/common/types';
import { useGlobalStore } from '../../services/stores/global';
import { useWhoIsOnlineStore } from '../../services/stores/who-is-online';
import { Store, StoreType } from '../types/stores.types';
const stores = {
[StoreType.GLOBAL]: useGlobalStore,
[StoreType.WHO_IS_ONLINE]: useWhoIsOnlineStore,
};
/**
* @function subscribe
* @description Subscribes to a subject and either update the value of the property each time there is a change, or call the callback that provides a custom behavior to the subscription
* @param name The name of the property to be updated in case there isn't a callback
* @param subject The subject to be subscribed
* @param callback The callback to be called each time there is a change
*/
function subscribeTo<T>(
name: string,
subject: PublicSubject<T>,
callback?: (value: T) => void,
): void {
subject.subscribe(this, () => {
if (callback) {
callback(subject.value);
} else {
this[name] = subject.value;
}
if (this.requestUpdate) this.requestUpdate();
});
this.unsubscribeFrom.push(subject.unsubscribe);
}
/**
* @function useGlobalStore
* @description Returns a proxy of the global store data and a subscribe function to be used in the components
*/
export function useStore<T extends StoreType>(name: T): Store<T> {
// @TODO - Improve types to get better sugestions when writing code
const storeData = stores[name as StoreType]();
const bindedSubscribeTo = subscribeTo.bind(this);
const proxy = new Proxy(storeData, {
get(store: Store<T>, valueName: string) {
return {
subscribe<K extends Store<T>>(callback?: (value: K) => void) {
bindedSubscribeTo(valueName, store[valueName], callback);
},
subject: store[valueName] as typeof storeData,
publish(newValue: keyof Store<T>) {
this.subject.value = newValue;
},
};
},
});
return proxy;
}