UNPKG

@stadium-ws/core

Version:

Build scalable realtime applications.

390 lines (382 loc) 11.6 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/index.ts var src_exports = {}; __export(src_exports, { ChannelType: () => ChannelType, SortDirection: () => SortDirection, Stadium: () => Stadium }); module.exports = __toCommonJS(src_exports); // src/types.ts var ChannelType = /* @__PURE__ */ ((ChannelType2) => { ChannelType2["PUBLIC"] = "PUBLIC"; ChannelType2["PRIVATE"] = "PRIVATE"; ChannelType2["DIRECT"] = "DIRECT"; return ChannelType2; })(ChannelType || {}); var SortDirection = /* @__PURE__ */ ((SortDirection2) => { SortDirection2["ASC"] = "asc"; SortDirection2["DESC"] = "desc"; return SortDirection2; })(SortDirection || {}); // src/Stadium.ts var import_eventemitter3 = __toESM(require("eventemitter3")); // src/Connection.ts var import_isomorphic_ws = __toESM(require("isomorphic-ws")); var Connection = class { constructor(config) { this.isConnected = false; this.connect = ({ onEvent, token }) => { return new Promise((resolve, reject) => { this.webSocket = new import_isomorphic_ws.default(`${this.baseUrl}?token=${token}`); this.webSocket.addEventListener("error", () => { reject(new Error("nope")); }); this.webSocket.addEventListener("message", (e) => { const data = JSON.parse(e.data); onEvent(data); }); this.webSocket.addEventListener("open", () => { this.isConnected = true; resolve(); }); this.webSocket.addEventListener("close", () => { this.isConnected = false; }); }); }; this.disconnect = () => __async(this, null, function* () { if (!this.isConnected) { return; } this.webSocket.close(); }); this.baseUrl = config.baseUrl; } }; var Connection_default = Connection; // src/Requester.ts var import_qs = __toESM(require("qs")); var ApiRequestError = class extends Error { constructor(message, statusCode) { super(message); this.statusCode = statusCode; Error.captureStackTrace(this, this.constructor); } }; var Requester = class { constructor(baseUrl, successStatuses = [200, 201]) { this.successStatuses = [200, 201]; this.headers = { "Content-Type": "application/json", Accept: "application/json" }; this.setTokenHeader = (token) => { this.headers["Authorization"] = `Bearer ${token}`; }; this.clearTokenHeader = () => { delete this.headers["Authorization"]; }; this.request = (options) => __async(this, null, function* () { let url = `${this.baseUrl}/${options.urlSegment}`; if (options.query) { url += `?${import_qs.default.stringify(options.query)}`; } const method = (options == null ? void 0 : options.method) || "GET"; const fetchRes = yield fetch(url, { method, body: (options == null ? void 0 : options.body) ? JSON.stringify(options.body) : void 0, headers: this.headers }); if (!this.successStatuses.includes(fetchRes.status)) { const text = yield fetchRes.text(); throw new ApiRequestError(text, fetchRes.status); } if (fetchRes.status === 201) { return {}; } const json = yield fetchRes.json(); return json; }); this.baseUrl = baseUrl; this.successStatuses = successStatuses; } }; var Requester_default = Requester; // src/utils.ts var MessageTypeMap = { [0 /* EVENT_CREATE */]: "eventCreate", [2 /* EVENT_UPDATE */]: "eventUpdate", [1 /* EVENT_DELETE */]: "eventDelete", [3 /* EVENT_REACTION_CREATE */]: "eventReactionCreate", [4 /* EVENT_REACTION_DELETE */]: "eventReactionDelete", [5 /* CHANNEL_UPDATE */]: "channelUpdate", [6 /* CHANNEL_USER_ADDED */]: "channelUserAdded" }; var getEventName = (type) => { return MessageTypeMap[type]; }; // src/Stadium.ts var Stadium = class { constructor(config = {}) { this.updateUser = (userId, options) => __async(this, null, function* () { yield this.ensureAccessToken(); const body = {}; if (options.displayName) { body.displayName = options.displayName; } if (options.isOnline) { body.isOnline = options.isOnline; } if (options.meta) { body.meta = options.meta; } if (options.userRoleId) { body.userRoleId = options.userRoleId; } return this.requester.request({ urlSegment: `users/${userId}`, method: "PUT", body }); }); this.onEvent = (event) => { var _a; const eventName = getEventName(event.type); (_a = this.emitter) == null ? void 0 : _a.emit(eventName, event.data); }; this.apiUrl = config.apiUrl || "https://api.stadium.ws"; this.gatewayUrl = config.gatewayUrl || "wss://gateway.stadium.ws"; this.config = config; this.requester = new Requester_default(this.apiUrl); } on(event, listener) { if (!this.emitter) { this.emitter = new import_eventemitter3.default(); } this.emitter.on(event, listener); } once(event, listener) { if (!this.emitter) { this.emitter = new import_eventemitter3.default(); } this.emitter.once(event, listener); } off(event, listener) { if (!this.emitter) { return; } this.emitter.off(event, listener); } removeAllListeners() { if (!this.emitter) { return; } this.emitter.removeAllListeners(); } createUser(_0) { return __async(this, arguments, function* ({ userRoleId, displayName, meta }) { yield this.ensureAccessToken(); return this.requester.request({ urlSegment: "users", method: "POST", body: { userRoleId, displayName, meta } }); }); } setUserToken(token) { this.accessToken = token; this.requester.setTokenHeader(this.accessToken); } getMe() { return __async(this, null, function* () { const res = yield this.requester.request({ urlSegment: "oauth/token" }); return res.user; }); } getChannel(channelId) { return __async(this, null, function* () { yield this.ensureAccessToken(); return this.requester.request({ urlSegment: `channels/${channelId}` }); }); } getChannelUsers(channelId) { return __async(this, null, function* () { yield this.ensureAccessToken(); return this.requester.request({ urlSegment: `channels/${channelId}/users` }); }); } createEvent(options) { return __async(this, null, function* () { yield this.ensureAccessToken(); return this.requester.request({ urlSegment: "events", method: "POST", body: options }); }); } getChannelEvents(channelId, options) { return __async(this, null, function* () { yield this.ensureAccessToken(); const query = { from: options == null ? void 0 : options.from, limit: options == null ? void 0 : options.limit, direction: options == null ? void 0 : options.direction, type: options == null ? void 0 : options.type }; return this.requester.request({ urlSegment: `channels/${channelId}/events`, query }); }); } getUserRoles(options) { return __async(this, null, function* () { yield this.ensureAccessToken(); const query = { from: options == null ? void 0 : options.from, limit: options == null ? void 0 : options.limit, direction: options == null ? void 0 : options.direction }; return this.requester.request({ urlSegment: "user-roles", query }); }); } getUsers(options) { return __async(this, null, function* () { yield this.ensureAccessToken(); const query = { from: options == null ? void 0 : options.from, limit: options == null ? void 0 : options.limit, direction: options == null ? void 0 : options.direction }; return this.requester.request({ urlSegment: "users", query }); }); } getChannels(options) { return __async(this, null, function* () { yield this.ensureAccessToken(); const query = { from: options == null ? void 0 : options.from, limit: options == null ? void 0 : options.limit, direction: options == null ? void 0 : options.direction }; return this.requester.request({ urlSegment: "channels", query }); }); } ensureAccessToken() { return __async(this, null, function* () { if (this.accessToken) { return; } const accessTokenResponse = yield this.requester.request({ urlSegment: "oauth/token", method: "POST", body: { grant_type: "client_credentials", client_id: this.config.clientId, client_secret: this.config.clientSecret } }); if (!(accessTokenResponse == null ? void 0 : accessTokenResponse.access_token)) { throw new Error("Could not authenticate with Stadium"); } this.accessToken = accessTokenResponse.access_token; this.requester.setTokenHeader(this.accessToken); }); } connect() { return __async(this, null, function* () { this.connection = new Connection_default({ baseUrl: this.gatewayUrl }); this.emitter = new import_eventemitter3.default(); yield this.connection.connect({ token: this.accessToken, onEvent: this.onEvent }); }); } disconnect() { return __async(this, null, function* () { var _a; if (!this.connection) { return; } (_a = this.emitter) == null ? void 0 : _a.removeAllListeners(); return this.connection.disconnect(); }); } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { ChannelType, SortDirection, Stadium });