diff --git a/app.vue b/app.vue
index afa34bb..a8c7190 100644
--- a/app.vue
+++ b/app.vue
@@ -11,10 +11,7 @@
import "~/assets/global.css";
const event = useRequestEvent();
const sessionStore = useSessionStore();
-const eventsStore = useEventsStore();
-const nuxtApp = useNuxtApp();
-await callOnce("fetch-globals", async () => {
+await callOnce("fetch-session", async () => {
await sessionStore.fetch(event);
- await nuxtApp.runWithContext(eventsStore.fetchLastEventId);
})
diff --git a/components/DiffSchedule.vue b/components/DiffSchedule.vue
index 5bc2541..3175d5a 100644
--- a/components/DiffSchedule.vue
+++ b/components/DiffSchedule.vue
@@ -61,7 +61,7 @@ const shifts = computed(() => {
});
-
diff --git a/components/TableUsers.vue b/components/TableUsers.vue
index 7021206..789f902 100644
--- a/components/TableUsers.vue
+++ b/components/TableUsers.vue
@@ -61,3 +61,7 @@
useEventSource();
const usersStore = useUsersStore();
+
+
diff --git a/composables/event-source.ts b/composables/event-source.ts
index 0e06b17..838b879 100644
--- a/composables/event-source.ts
+++ b/composables/event-source.ts
@@ -2,12 +2,12 @@
SPDX-FileCopyrightText: © 2025 Hornwitser
SPDX-License-Identifier: AGPL-3.0-or-later
*/
-import type { ApiEvent, ApiEventStreamMessage } from "~/shared/types/api";
+import type { ApiEvent } from "~/shared/types/api";
interface AppEventMap {
"open": Event,
- "message": MessageEvent,
- "event": MessageEvent,
+ "message": MessageEvent,
+ "update": MessageEvent,
"error": Event,
"close": Event,
}
@@ -18,11 +18,12 @@ class AppEventSource extends EventTarget {
#forwardEvent(type: string) {
this.#source!.addEventListener(type, event => {
- console.log("AppEventSource", event.type, event.data);
- if (type === "open" || type === "error") {
+ if (type === "open" || type === "message" || type === "error") {
+ console.log("AppEventSource", event.type, event.data);
this.dispatchEvent(new Event(event.type));
- } else if (type === "message") {
- const data = event.data ? JSON.parse(event.data) as ApiEventStreamMessage : undefined;
+ } else {
+ const data = event.data ? JSON.parse(event.data) as ApiEvent : undefined;
+ console.log("AppEventSource", event.type, data);
if (data?.type === "connected") {
this.#sourceSessionId = data.session?.id;
}
@@ -33,27 +34,17 @@ class AppEventSource extends EventTarget {
source: event.source,
ports: [...event.ports],
}));
- } else {
- const data = event.data ? JSON.parse(event.data) as ApiEvent : undefined;
- this.dispatchEvent(new MessageEvent(event.type, {
- data,
- origin: event.origin,
- lastEventId: event.lastEventId,
- source: event.source,
- ports: [...event.ports],
- }));
}
});
}
- open(sessionId: number | undefined, lastEventId: number) {
+ open(sessionId: number | undefined) {
console.log("Opening event source sid:", sessionId);
this.#sourceSessionId = sessionId;
- const query = new URLSearchParams({ lastEventId: String(lastEventId) });
- this.#source = new EventSource(`/api/events?${query}`);
+ this.#source = new EventSource("/api/events");
this.#forwardEvent("open");
this.#forwardEvent("message");
- this.#forwardEvent("event");
+ this.#forwardEvent("update");
this.#forwardEvent("error");
}
@@ -67,20 +58,20 @@ class AppEventSource extends EventTarget {
}
#connectRefs = 0;
- connect(sessionId: number | undefined, lastEventId: number) {
+ connect(sessionId: number | undefined) {
this.#connectRefs += 1;
if (this.#source && this.#sourceSessionId !== sessionId) {
this.close();
}
if (!this.#source) {
- this.open(sessionId, lastEventId);
+ this.open(sessionId);
}
}
- reconnect(sessionId: number | undefined, lastEventId: number) {
+ reconnect(sessionId: number | undefined) {
if (this.#source && this.#sourceSessionId !== sessionId) {
this.close();
- this.open(sessionId, lastEventId);
+ this.open(sessionId);
}
}
@@ -122,15 +113,14 @@ export const appEventSource = import.meta.client ? new AppEventSource() : null;
export function useEventSource() {
const sessionStore = useSessionStore();
- const eventsStore = useEventsStore();
onMounted(() => {
console.log("useEventSource onMounted", sessionStore.id);
- appEventSource!.connect(sessionStore.id, eventsStore.lastEventId);
+ appEventSource!.connect(sessionStore.id);
})
watch(() => sessionStore.id, () => {
console.log("useEventSource sessionStore.id change", sessionStore.id);
- appEventSource!.reconnect(sessionStore.id, eventsStore.lastEventId);
+ appEventSource!.reconnect(sessionStore.id);
})
onUnmounted(() => {
diff --git a/docs/dev/server-sent-events.md b/docs/dev/server-sent-events.md
index d510c1e..82ff99b 100644
--- a/docs/dev/server-sent-events.md
+++ b/docs/dev/server-sent-events.md
@@ -11,9 +11,3 @@ To update in real time this application sends a `text/event-source` stream using
Upon connecting a `"connect"` event is emitted with the session the connection was made under. This is the primary mechanism a user agent discovers its own session having been rotated into a new one, which also happens when the access level of the account associated with the session changes.
After the `"connect"` event the user agent will start to receive updates to resources it has access to that has changed. There is no filtering for what resoucres the user agent receives updates for at the moment as there's not enough events to justify the complexity of server-side subscriptions and filtering.
-
-## Id and order
-
-Events are guaranteed to be delivered in order, and to maintain consistency the server provides the following guarantee: Any entities fetched after receiving a response from `/api/last-event-id` will include updates from all events up to and including the `id` received from the response.
-
-This means that a client can fetch an up to date and live representation of any API entity by first fetching the last event from `/api/last-event-id`, and then in parallel fetch any entities as well as opening the `/api/events` stream with the `lastEventId` query param set to the value received from the `/api/last-event-id` endpoint.
diff --git a/pages/admin/index.vue b/pages/admin/index.vue
index 86a1b5f..116a189 100644
--- a/pages/admin/index.vue
+++ b/pages/admin/index.vue
@@ -109,3 +109,7 @@ const tabs = [
{ id: "database", title: "Database" },
];
+
+
diff --git a/pages/admin/users/[id].vue b/pages/admin/users/[id].vue
index bf2355c..0579b44 100644
--- a/pages/admin/users/[id].vue
+++ b/pages/admin/users/[id].vue
@@ -84,7 +84,7 @@ const { pending, data, error } = await useFetch(() => `/api/users/${id.value}/de
const userDetails = data as Ref;
-