From 7c85dd1538992f2cfa861e47ac687e31766de83d Mon Sep 17 00:00:00 2001 From: Paul Neubauer Date: Wed, 19 Jul 2023 09:51:37 +0200 Subject: [PATCH 01/29] Implement PoC Polyfill --- package.json | 1 + .../src/components/Topbar/Notifications.vue | 39 +++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 740446a852c..0198a0c4c83 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "not OperaMobile > 0" ], "dependencies": { + "@microsoft/fetch-event-source": "^2.0.1", "@vue/compiler-dom": "3.3.4", "@vue/compiler-sfc": "3.3.4", "@vue/runtime-dom": "3.3.4", diff --git a/packages/web-runtime/src/components/Topbar/Notifications.vue b/packages/web-runtime/src/components/Topbar/Notifications.vue index 4dfd6cf0d71..d5420bf0857 100644 --- a/packages/web-runtime/src/components/Topbar/Notifications.vue +++ b/packages/web-runtime/src/components/Topbar/Notifications.vue @@ -96,12 +96,14 @@ import { Notification } from '../../helpers/notifications' import { formatDateFromISO, formatRelativeDateFromISO, + useAccessToken, useClientService, useRoute, useStore } from 'web-pkg' import { useGettext } from 'vue3-gettext' import { useTask } from 'vue-concurrency' +import { EventStreamContentType, fetchEventSource } from '@microsoft/fetch-event-source' import { createFileRouteOptions } from 'web-pkg/src/helpers/router' const POLLING_INTERVAL = 30000 @@ -291,11 +293,42 @@ export default { setAdditionalData() } + const accessToken = useAccessToken({ store }) + onMounted(() => { + class RetriableError extends Error {} + class FatalError extends Error {} + + fetchEventSource('/ocs/v2.php/apps/notifications/api/v1/notifications/sse', { + headers: { + Authorization: `Bearer ${accessToken.value}` + }, + async onopen(response) { + if (response.ok && response.headers.get('content-type') === EventStreamContentType) { + console.log('SSE OK') + return + } else if (response.status >= 400 && response.status < 500 && response.status !== 429) { + throw new FatalError() + } else { + throw new RetriableError() + } + }, + onmessage(msg) { + console.log(msg) + if (msg.event === 'FatalError') { + throw new FatalError(msg.data) + } + }, + onclose() { + throw new RetriableError() + }, + onerror(err) { + if (err instanceof FatalError) { + throw err + } + } + }) fetchNotificationsTask.perform() - notificationsInterval.value = setInterval(() => { - fetchNotificationsTask.perform() - }, POLLING_INTERVAL) }) onUnmounted(() => { From 642f864487c9096ba301534a0b30a47b8b43d85f Mon Sep 17 00:00:00 2001 From: Paul Neubauer Date: Fri, 21 Jul 2023 10:19:00 +0200 Subject: [PATCH 02/29] WIP --- .../src/components/Topbar/Notifications.vue | 23 +++++++------------ pnpm-lock.yaml | 13 ++++++++++- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/packages/web-runtime/src/components/Topbar/Notifications.vue b/packages/web-runtime/src/components/Topbar/Notifications.vue index d5420bf0857..4e3940674a0 100644 --- a/packages/web-runtime/src/components/Topbar/Notifications.vue +++ b/packages/web-runtime/src/components/Topbar/Notifications.vue @@ -295,10 +295,7 @@ export default { const accessToken = useAccessToken({ store }) - onMounted(() => { - class RetriableError extends Error {} - class FatalError extends Error {} - + const setupSSE = () => { fetchEventSource('/ocs/v2.php/apps/notifications/api/v1/notifications/sse', { headers: { Authorization: `Bearer ${accessToken.value}` @@ -307,27 +304,23 @@ export default { if (response.ok && response.headers.get('content-type') === EventStreamContentType) { console.log('SSE OK') return - } else if (response.status >= 400 && response.status < 500 && response.status !== 429) { - throw new FatalError() } else { - throw new RetriableError() + throw new Error(`SSE notifications couldn't be set up ${response.status}`) } }, onmessage(msg) { console.log(msg) if (msg.event === 'FatalError') { - throw new FatalError(msg.data) + throw new Error(`SSE notifications error: ${msg.data}`) } }, - onclose() { - throw new RetriableError() - }, - onerror(err) { - if (err instanceof FatalError) { - throw err - } + onerror() { + setTimeout(setupSSE, 10000) } }) + } + onMounted(() => { + setupSSE() fetchNotificationsTask.perform() }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a3f425e96f3..ca062b3cad2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,8 @@ -lockfileVersion: '6.0' +lockfileVersion: '6.1' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false settings: autoInstallPeers: true @@ -41,6 +45,9 @@ importers: .: dependencies: + '@microsoft/fetch-event-source': + specifier: ^2.0.1 + version: 2.0.1 '@vue/compiler-dom': specifier: 3.3.4 version: 3.3.4 @@ -5845,6 +5852,10 @@ packages: '@lezer/common': 1.0.3 dev: true + /@microsoft/fetch-event-source@2.0.1: + resolution: {integrity: sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==} + dev: false + /@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1: resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} dependencies: From 45ea1607f8e8f41990765f8a19650996cfe634d8 Mon Sep 17 00:00:00 2001 From: Paul Neubauer Date: Fri, 21 Jul 2023 11:00:38 +0200 Subject: [PATCH 03/29] make basic sse notification handling work --- .../src/components/Topbar/Notifications.vue | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/web-runtime/src/components/Topbar/Notifications.vue b/packages/web-runtime/src/components/Topbar/Notifications.vue index 4e3940674a0..0a48488c9cb 100644 --- a/packages/web-runtime/src/components/Topbar/Notifications.vue +++ b/packages/web-runtime/src/components/Topbar/Notifications.vue @@ -87,7 +87,7 @@