@zettelooo/api-server
Version:
Zettel: Public API types and access for server-side code
131 lines (130 loc) • 6.57 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Ws = void 0;
const api_types_1 = require("@zettelooo/api-types");
const websocket_1 = require("websocket");
const apiConfig_1 = require("../apiConfig");
var Ws;
(function (Ws) {
class GetUpdates {
constructor(options) {
this.options = options;
this.setStatus(GetUpdates.Status.ClosedInitially);
}
setStatus(status) {
var _a, _b;
if (this.status !== status) {
this.status = status;
(_b = (_a = this.options).onStatusChange) === null || _b === void 0 ? void 0 : _b.call(_a, status);
switch (status) {
case GetUpdates.Status.ClosedInitially:
if (this.options.startInitially) {
this.start();
}
break;
case GetUpdates.Status.Starting:
case GetUpdates.Status.Started:
// Do nothing!
break;
case GetUpdates.Status.ClosedByClient:
case GetUpdates.Status.ClosedByServer:
case GetUpdates.Status.ClosedDueToServerOrNetworkFailure:
if (typeof this.options.retryConnectionTimeoutMilliseconds === 'number') {
setTimeout(() => this.start(), this.options.retryConnectionTimeoutMilliseconds);
}
break;
}
}
}
getStatus() {
return this.status;
}
getRegistrationKey() {
return this.registrationKey;
}
start() {
var _a, _b, _c;
if (this.status === GetUpdates.Status.Starting || this.status === GetUpdates.Status.Started)
return;
this.setStatus(GetUpdates.Status.Starting);
const baseUrl = ((_a = this.options.wsApi) === null || _a === void 0 ? void 0 : _a.baseUrl) ||
apiConfig_1.apiConfig.baseUrlsByTargetEnvironment[(_c = (_b = this.options.wsApi) === null || _b === void 0 ? void 0 : _b.targetEnvironment) !== null && _c !== void 0 ? _c : 'live'].ws;
this.socket = new websocket_1.w3cwebsocket(`${baseUrl}/${api_types_1.version}/ws/get-updates`);
this.socket.binaryType = 'arraybuffer';
const referencedSocket = this.socket;
referencedSocket.onopen = () => {
if (this.socket !== referencedSocket)
return;
referencedSocket.send(GetUpdates.formatRequest({
type: api_types_1.ZettelTypes.Service.Ws.GetUpdates.Request.Type.Start,
extensionAccessKey: this.options.extensionAccessKey,
}));
};
referencedSocket.onmessage = (event) => __awaiter(this, void 0, void 0, function* () {
var _d, _e;
if (this.socket !== referencedSocket)
return;
if (typeof event.data !== 'string')
return;
const message = GetUpdates.parseResponse(event.data);
switch (message.type) {
case api_types_1.ZettelTypes.Service.Ws.GetUpdates.Response.Type.Started:
this.registrationKey = message.registrationKey;
this.setStatus(GetUpdates.Status.Started);
break;
case api_types_1.ZettelTypes.Service.Ws.GetUpdates.Response.Type.Mutation:
(_e = (_d = this.options).onMutation) === null || _e === void 0 ? void 0 : _e.call(_d, message.mutation);
break;
}
});
referencedSocket.onclose = event => {
if (this.socket !== referencedSocket)
return;
this.close(event.wasClean ? GetUpdates.Status.ClosedByServer : GetUpdates.Status.ClosedDueToServerOrNetworkFailure);
};
referencedSocket.onerror = event => {
if (this.socket !== referencedSocket)
return;
this.close(GetUpdates.Status.ClosedDueToServerOrNetworkFailure);
};
}
close(status = GetUpdates.Status.ClosedByClient) {
if (this.status === GetUpdates.Status.Starting || this.status === GetUpdates.Status.Started) {
const { socket } = this;
delete this.socket;
if ((socket === null || socket === void 0 ? void 0 : socket.readyState) === websocket_1.w3cwebsocket.CONNECTING || (socket === null || socket === void 0 ? void 0 : socket.readyState) === websocket_1.w3cwebsocket.OPEN) {
socket === null || socket === void 0 ? void 0 : socket.close();
}
delete this.registrationKey;
this.setStatus(status);
}
}
static formatRequest(message) {
return JSON.stringify(message);
}
static parseResponse(message) {
return JSON.parse(message);
}
}
Ws.GetUpdates = GetUpdates;
(function (GetUpdates) {
let Status;
(function (Status) {
Status["ClosedInitially"] = "CLOSED_INITIALLY";
Status["Starting"] = "STARTING";
Status["Started"] = "STARTED";
Status["ClosedByClient"] = "CLOSED_BY_CLIENT";
Status["ClosedByServer"] = "CLOSED_BY_SERVER";
Status["ClosedDueToServerOrNetworkFailure"] = "CLOSED_DUE_TO_SERVER_OR_NETWORK_FAILURE";
})(Status = GetUpdates.Status || (GetUpdates.Status = {}));
})(GetUpdates = Ws.GetUpdates || (Ws.GetUpdates = {}));
})(Ws = exports.Ws || (exports.Ws = {}));