You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.8 KiB
52 lines
1.8 KiB
import { useLdo } from "./SolidLdoProvider";
|
|
import { useEffect, useRef } from "react";
|
|
|
|
export function useSubscribeToResource(...uris: string[]): void {
|
|
const { dataset } = useLdo();
|
|
const currentlySubscribed = useRef<Record<string, string>>({});
|
|
useEffect(() => {
|
|
const resources = uris.map((uri) => dataset.getResource(uri));
|
|
const previousSubscriptions = { ...currentlySubscribed.current };
|
|
Promise.all<void>(
|
|
resources.map(async (resource) => {
|
|
if (!previousSubscriptions[resource.uri]) {
|
|
// Prevent multiple triggers from created subscriptions while waiting
|
|
// for connection
|
|
currentlySubscribed.current[resource.uri] = "AWAITING";
|
|
// Read and subscribe
|
|
await resource.readIfUnfetched();
|
|
currentlySubscribed.current[resource.uri] =
|
|
await resource.subscribeToNotifications();
|
|
} else {
|
|
delete previousSubscriptions[resource.uri];
|
|
}
|
|
}),
|
|
).then(async () => {
|
|
// Unsubscribe from all remaining previous subscriptions
|
|
await Promise.all(
|
|
Object.entries(previousSubscriptions).map(
|
|
async ([resourceUri, subscriptionId]) => {
|
|
// Unsubscribe
|
|
delete currentlySubscribed.current[resourceUri];
|
|
const resource = dataset.getResource(resourceUri);
|
|
await resource.unsubscribeFromNotifications(subscriptionId);
|
|
},
|
|
),
|
|
);
|
|
});
|
|
}, [uris]);
|
|
|
|
// Cleanup Subscriptions
|
|
useEffect(() => {
|
|
return () => {
|
|
Promise.all(
|
|
Object.entries(currentlySubscribed.current).map(
|
|
async ([resourceUri, subscriptionId]) => {
|
|
const resource = dataset.getResource(resourceUri);
|
|
await resource.unsubscribeFromNotifications(subscriptionId);
|
|
},
|
|
),
|
|
);
|
|
};
|
|
}, []);
|
|
}
|
|
|