masto
Version:
Mastodon API client for JavaScript, TypeScript, Node.js, browsers
89 lines (88 loc) • 3.04 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebSocketConnectorImpl = void 0;
const isomorphic_ws_1 = __importDefault(require("isomorphic-ws"));
const index_js_1 = require("../../utils/index.js");
const index_js_2 = require("../errors/index.js");
const wait_for_events_js_1 = require("./wait-for-events.js");
class WebSocketConnectorImpl {
props;
logger;
ws;
killed = false;
queue = [];
backoff;
constructor(props, logger) {
this.props = props;
this.logger = logger;
this.backoff = new index_js_1.ExponentialBackoff({
maxAttempts: this.props.maxAttempts,
});
this.spawn();
}
acquire() {
if (this.killed) {
throw new index_js_2.MastoWebSocketError("WebSocket closed");
}
if (this.ws) {
return Promise.resolve(this.ws);
}
const promiseWithResolvers = (0, index_js_1.createPromiseWithResolvers)();
this.queue.push(promiseWithResolvers);
return promiseWithResolvers.promise;
}
async *[Symbol.asyncIterator]() {
while (!this.killed) {
yield await this.acquire();
}
}
kill() {
this.killed = true;
this.ws?.close();
this.backoff.clear();
for (const { reject } of this.queue) {
reject(new index_js_2.MastoWebSocketError("WebSocket closed"));
}
this.queue = [];
}
async spawn() {
while (!this.killed) {
try {
await this.backoff.sleep();
}
catch {
break;
}
try {
this.logger?.log("info", "Connecting to WebSocket...");
{
const ctor = (this.props.implementation ??
isomorphic_ws_1.default);
const ws = new ctor(...this.props.constructorParameters);
await (0, wait_for_events_js_1.waitForOpen)(ws);
this.ws = ws;
}
this.logger?.log("info", "Connected to WebSocket");
for (const { resolve } of this.queue) {
resolve(this.ws);
}
this.queue = [];
await (0, wait_for_events_js_1.waitForClose)(this.ws);
this.logger?.log("info", "WebSocket closed");
this.backoff.clear();
}
catch (error) {
this.logger?.log("error", "WebSocket error:", error);
}
this.ws = undefined;
}
for (const { reject } of this.queue) {
reject(new index_js_2.MastoWebSocketError(`Failed to connect to WebSocket after ${this.props.maxAttempts} attempts`));
}
this.queue = [];
}
}
exports.WebSocketConnectorImpl = WebSocketConnectorImpl;