mirror of
https://github.com/myfatemi04/wheelshare-frontend.git
synced 2025-04-21 11:20:17 -04:00
add store
This commit is contained in:
parent
445a8b7f80
commit
61a526dfeb
|
@ -17,6 +17,8 @@ export default function PoolMap() {
|
|||
<GoogleMap
|
||||
mapContainerStyle={{ width: '400px', height: '400px' }}
|
||||
center={center}
|
||||
onLoad={() => console.log('Loaded Base Map')}
|
||||
onTilesLoaded={() => console.log('Loaded Tile Map')}
|
||||
>
|
||||
<Marker position={position} />
|
||||
</GoogleMap>
|
||||
|
|
88
src/store.ts
Normal file
88
src/store.ts
Normal file
|
@ -0,0 +1,88 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
|
||||
export type UpdateListener<T> = (newValue: StoreValue<T> | null) => void;
|
||||
|
||||
export type ValueFetcher<T> = (key: string) => Promise<T | null>;
|
||||
|
||||
export type StoreValue<T> = { value: T } | { error: any };
|
||||
|
||||
/**
|
||||
* This is a general-purpose, subscribable key-value store for content like posts, groups, and spaces.
|
||||
*/
|
||||
export class Store<T> {
|
||||
/**
|
||||
* Stores the internal data. If the value is `null`, then we attempted to fetch the data, but it did not exist.
|
||||
*/
|
||||
private data = new Map<string, StoreValue<T> | null>();
|
||||
private listeners = new Map<string, Set<UpdateListener<T>>>();
|
||||
|
||||
constructor(private fetcher: ValueFetcher<T>) {}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param key The key to get the data for
|
||||
* @param forceRefresh If the data already exists, fetch it again anyway
|
||||
*/
|
||||
get(key: string, forceRefresh = false): StoreValue<T> | null {
|
||||
if (!this.data.has(key) || forceRefresh) {
|
||||
this.fetcher(key)
|
||||
.then((value) => {
|
||||
this.set(key, value ? { value } : null);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.set(key, { error });
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.data.get(key) ?? null;
|
||||
}
|
||||
|
||||
set(key: string, value: StoreValue<T> | null) {
|
||||
if (this.listeners.has(key)) {
|
||||
this.listeners.get(key)?.forEach((callback) => {
|
||||
callback(value);
|
||||
});
|
||||
}
|
||||
|
||||
return this.data.set(key, value);
|
||||
}
|
||||
|
||||
subscribe(key: string, listener: UpdateListener<T>) {
|
||||
if (!this.listeners.has(key)) {
|
||||
this.listeners.set(key, new Set());
|
||||
}
|
||||
|
||||
this.listeners.get(key)?.add(listener);
|
||||
}
|
||||
|
||||
unsubscribe(key: string, listener: UpdateListener<T>) {
|
||||
if (this.listeners.has(key)) {
|
||||
if (this.listeners.get(key)?.has(listener)) {
|
||||
this.listeners.get(key)?.delete(listener);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
console.warn(
|
||||
'Unsubscribed from',
|
||||
key,
|
||||
'but listener does not exist: ',
|
||||
listener
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function useStoredValue<T>(store: Store<T>, key: string) {
|
||||
const [value, setValue] = useState<StoreValue<T> | null>(store.get(key));
|
||||
|
||||
useEffect(() => {
|
||||
const callback = (value: StoreValue<T> | null) => setValue(value);
|
||||
store.subscribe(key, callback);
|
||||
|
||||
return () => store.unsubscribe(key, callback);
|
||||
}, [key, store]);
|
||||
|
||||
return value;
|
||||
}
|
Loading…
Reference in New Issue
Block a user