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/assets/global.css b/assets/global.css
index 4869d13..3d4e0c0 100644
--- a/assets/global.css
+++ b/assets/global.css
@@ -76,7 +76,7 @@ label>* {
margin-inline-start: 0.5rem;
}
-:is(p, form, fieldset, pre, ul, .flow) + :is(p, form, fieldset, pre, ul, .flow) {
+:is(p, form, fieldset, pre, ul) + :is(p, form, fieldset, pre, ul) {
margin-block-start: 0.5rem;
}
diff --git a/components/CardEvent.vue b/components/CardEvent.vue
index 0d90894..baca351 100644
--- a/components/CardEvent.vue
+++ b/components/CardEvent.vue
@@ -3,10 +3,7 @@
SPDX-License-Identifier: AGPL-3.0-or-later
-->
-
Host: {{ event.host }}
@@ -19,11 +16,7 @@
{{ event.notice }}
{{ event.description ?? "No description provided" }}
{{ event.interested }} interested
{{ event.name }}
Timeslots
-
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/package.json b/package.json
index 790d2b1..7f6cd85 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,6 @@
"dependencies": {
"@pinia/nuxt": "^0.11.1",
"luxon": "^3.6.1",
- "micromark": "^4.0.2",
"nuxt": "^3.17.6",
"pinia": "^3.0.3",
"vue": "^3.5.17",
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;
-