1
1
mirror of https://github.com/go-gitea/gitea synced 2024-11-16 07:04:25 +00:00
gitea/web_src/js/features/eventsource.sharedworker.js
silverwind 3d751b6ec1
Enforce trailing comma in JS on multiline (#30002)
To keep blame info accurate and to avoid [changes like
this](https://github.com/go-gitea/gitea/pull/29977/files#diff-c3422631a14edbe1e508c4b22f0c718db318be08a6e889427802f9b6165d88d6R359),
it's good to always have a trailing comma, so let's enforce it in JS.

This rule is completely automatically fixable with `make lint-js-fix`
and that's what I did here.
2024-03-22 14:06:53 +00:00

142 lines
3.7 KiB
JavaScript

const sourcesByUrl = {};
const sourcesByPort = {};
class Source {
constructor(url) {
this.url = url;
this.eventSource = new EventSource(url);
this.listening = {};
this.clients = [];
this.listen('open');
this.listen('close');
this.listen('logout');
this.listen('notification-count');
this.listen('stopwatches');
this.listen('error');
}
register(port) {
if (this.clients.includes(port)) return;
this.clients.push(port);
port.postMessage({
type: 'status',
message: `registered to ${this.url}`,
});
}
deregister(port) {
const portIdx = this.clients.indexOf(port);
if (portIdx < 0) {
return this.clients.length;
}
this.clients.splice(portIdx, 1);
return this.clients.length;
}
close() {
if (!this.eventSource) return;
this.eventSource.close();
this.eventSource = null;
}
listen(eventType) {
if (this.listening[eventType]) return;
this.listening[eventType] = true;
this.eventSource.addEventListener(eventType, (event) => {
this.notifyClients({
type: eventType,
data: event.data,
});
});
}
notifyClients(event) {
for (const client of this.clients) {
client.postMessage(event);
}
}
status(port) {
port.postMessage({
type: 'status',
message: `url: ${this.url} readyState: ${this.eventSource.readyState}`,
});
}
}
self.addEventListener('connect', (e) => {
for (const port of e.ports) {
port.addEventListener('message', (event) => {
if (!self.EventSource) {
// some browsers (like PaleMoon, Firefox<53) don't support EventSource in SharedWorkerGlobalScope.
// this event handler needs EventSource when doing "new Source(url)", so just post a message back to the caller,
// in case the caller would like to use a fallback method to do its work.
port.postMessage({type: 'no-event-source'});
return;
}
if (event.data.type === 'start') {
const url = event.data.url;
if (sourcesByUrl[url]) {
// we have a Source registered to this url
const source = sourcesByUrl[url];
source.register(port);
sourcesByPort[port] = source;
return;
}
let source = sourcesByPort[port];
if (source) {
if (source.eventSource && source.url === url) return;
// How this has happened I don't understand...
// deregister from that source
const count = source.deregister(port);
// Clean-up
if (count === 0) {
source.close();
sourcesByUrl[source.url] = null;
}
}
// Create a new Source
source = new Source(url);
source.register(port);
sourcesByUrl[url] = source;
sourcesByPort[port] = source;
} else if (event.data.type === 'listen') {
const source = sourcesByPort[port];
source.listen(event.data.eventType);
} else if (event.data.type === 'close') {
const source = sourcesByPort[port];
if (!source) return;
const count = source.deregister(port);
if (count === 0) {
source.close();
sourcesByUrl[source.url] = null;
sourcesByPort[port] = null;
}
} else if (event.data.type === 'status') {
const source = sourcesByPort[port];
if (!source) {
port.postMessage({
type: 'status',
message: 'not connected',
});
return;
}
source.status(port);
} else {
// just send it back
port.postMessage({
type: 'error',
message: `received but don't know how to handle: ${event.data}`,
});
}
});
port.start();
}
});