message_area.insertAdjacentHTML('beforeend', message);
}
-/* An EventSource wrapper that automatically reconnects when the
- * connection is closed (e.g. server restart). Retries a few times
- * with a delay before giving up and calling the onclose callback.
- */
-class ReconnectingEventSource {
- constructor(url, { max_retries = 5, retry_delay_ms = 2000, onclose } = {}) {
- this._url = url;
- this._max_retries = max_retries;
- this._retry_delay_ms = retry_delay_ms;
- this._onclose = onclose;
- this._listeners = [];
- this._retries = 0;
- this._closed = false;
- this._connect();
- }
-
- _connect() {
- this._es = new EventSource(this._url);
-
- this._es.onopen = () => {
- this._retries = 0;
- };
-
- this._es.onerror = () => {
- if (this._es.readyState === EventSource.CLOSED) {
- this._es.close();
- if (!this._closed && this._retries < this._max_retries) {
- this._retries++;
- setTimeout(() => this._connect(), this._retry_delay_ms);
- } else if (this._onclose) {
- this._onclose();
- }
- }
- };
-
- for (const { type, handler } of this._listeners) {
- this._es.addEventListener(type, handler);
- }
- }
-
- addEventListener(type, handler) {
- this._listeners.push({ type, handler });
- this._es.addEventListener(type, handler);
- }
-
- close() {
- this._closed = true;
- this._es.close();
- }
-}
-
function lmno_join_loadend(request, game_id) {
if (request.status === 404) {
add_message("danger", game_id + " is not a valid game ID. Try again.");