2025-03-10 15:41:32 +01:00
|
|
|
import type { Schedule } from '~/shared/types/schedule';
|
|
|
|
|
|
|
|
let source: EventSource | null = null;
|
|
|
|
let sourceRefs = 0;
|
2025-03-10 16:43:21 +01:00
|
|
|
let sourceSessionId: number | undefined = undefined;
|
2025-03-10 15:41:32 +01:00
|
|
|
export const useSchedule = () => {
|
2025-03-10 16:43:21 +01:00
|
|
|
const { data: session } = useAccountSession();
|
2025-03-10 15:41:32 +01:00
|
|
|
const asyncData = useAsyncData<Schedule>(
|
|
|
|
'schedule',
|
|
|
|
() => $fetch("/api/schedule"),
|
|
|
|
{ default: () => ({ events: [], locations: [] }) },
|
|
|
|
)
|
|
|
|
const { data: schedule } = asyncData;
|
|
|
|
|
2025-03-10 16:43:21 +01:00
|
|
|
function connect() {
|
|
|
|
console.log("Opening event source sid:", session.value?.id);
|
|
|
|
sourceSessionId = session.value?.id;
|
2025-03-10 15:41:32 +01:00
|
|
|
source = new EventSource("/api/events");
|
|
|
|
source.addEventListener("message", (message) => {
|
|
|
|
console.log("Message", message.data);
|
|
|
|
});
|
|
|
|
source.addEventListener("update", (message) => {
|
|
|
|
const updatedSchedule: Schedule = JSON.parse(message.data);
|
|
|
|
console.log("Update", updatedSchedule);
|
|
|
|
schedule.value = updatedSchedule;
|
|
|
|
});
|
2025-03-10 16:43:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function disconnect() {
|
|
|
|
console.log("Closing event source")
|
|
|
|
source!.close();
|
|
|
|
source = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
console.log("useSchedule onMounted", sourceRefs);
|
|
|
|
sourceRefs += 1;
|
|
|
|
if (sourceRefs !== 1) {
|
|
|
|
console.log("Event source already open");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
connect();
|
|
|
|
})
|
|
|
|
|
|
|
|
watch(() => session.value?.id, () => {
|
|
|
|
if (sourceSessionId === session.value?.id) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sourceSessionId = session.value?.id;
|
|
|
|
console.log("Session changed, refetching schedule")
|
|
|
|
$fetch("/api/schedule").then(
|
|
|
|
data => { schedule.value = data; },
|
|
|
|
err => { console.error(err); schedule.value = { locations: [], events: []}},
|
|
|
|
)
|
|
|
|
if (source && sourceRefs > 0) {
|
|
|
|
console.log("Restarting event stream")
|
|
|
|
disconnect();
|
|
|
|
connect();
|
|
|
|
}
|
2025-03-10 15:41:32 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
console.log("useSchedule onUnmounted", sourceRefs);
|
|
|
|
sourceRefs -= 1;
|
|
|
|
if (source && sourceRefs === 0) {
|
2025-03-10 16:43:21 +01:00
|
|
|
disconnect();
|
2025-03-10 15:41:32 +01:00
|
|
|
}
|
|
|
|
if (sourceRefs < 0) {
|
|
|
|
throw Error("Source reference count below zero");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return asyncData.then(({ data }) => data);
|
|
|
|
}
|