UNPKG

partysocket

Version:

A better WebSocket that Just Worksâ„¢

186 lines (183 loc) • 6.02 kB
Object.defineProperty(exports, "__esModule", { value: true }); const require_ws = require("./ws-COtplmrw.cjs"); //#region src/index.ts const valueIsNotNil = (keyValuePair) => keyValuePair[1] !== null && keyValuePair[1] !== void 0; function generateUUID() { if (crypto?.randomUUID) return crypto.randomUUID(); let d = Date.now(); let d2 = (performance?.now && performance.now() * 1e3) || 0; return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { let r = Math.random() * 16; if (d > 0) { r = ((d + r) % 16) | 0; d = Math.floor(d / 16); } else { r = ((d2 + r) % 16) | 0; d2 = Math.floor(d2 / 16); } return (c === "x" ? r : (r & 3) | 8).toString(16); }); } function getPartyInfo(partySocketOptions, defaultProtocol, defaultParams = {}) { const { host: rawHost, path: rawPath, protocol: rawProtocol, room, party, basePath, prefix, query } = partySocketOptions; let host = rawHost.replace(/^(http|https|ws|wss):\/\//, ""); if (host.endsWith("/")) host = host.slice(0, -1); if (rawPath?.startsWith("/")) throw new Error("path must not start with a slash"); const name = party ?? "main"; const path = rawPath ? `/${rawPath}` : ""; const protocol = rawProtocol || (host.startsWith("localhost:") || host.startsWith("127.0.0.1:") || host.startsWith("192.168.") || host.startsWith("10.") || (host.startsWith("172.") && host.split(".")[1] >= "16" && host.split(".")[1] <= "31") || host.startsWith("[::ffff:7f00:1]:") ? defaultProtocol : `${defaultProtocol}s`); const baseUrl = `${protocol}://${host}/${basePath || `${prefix || "parties"}/${name}/${room}`}${path}`; const makeUrl = (query$1 = {}) => `${baseUrl}?${new URLSearchParams([...Object.entries(defaultParams), ...Object.entries(query$1).filter(valueIsNotNil)])}`; const urlProvider = typeof query === "function" ? async () => makeUrl(await query()) : makeUrl(query); return { host, path, room, name, protocol, partyUrl: baseUrl, urlProvider }; } var PartySocket = class extends require_ws.ReconnectingWebSocket { _pk; _pkurl; name; room; host; path; basePath; constructor(partySocketOptions) { const wsOptions = getWSOptions(partySocketOptions); super(wsOptions.urlProvider, wsOptions.protocols, wsOptions.socketOptions); this.partySocketOptions = partySocketOptions; this.setWSProperties(wsOptions); if (!partySocketOptions.startClosed && !this.room && !this.basePath) { this.close(); throw new Error( "Either room or basePath must be provided to connect. Use startClosed: true to create a socket and set them via updateProperties before calling reconnect()." ); } if (!partySocketOptions.disableNameValidation) { if (partySocketOptions.party?.includes("/")) console.warn( `PartySocket: party name "${partySocketOptions.party}" contains forward slash which may cause routing issues. Consider using a name without forward slashes or set disableNameValidation: true to bypass this warning.` ); if (partySocketOptions.room?.includes("/")) console.warn( `PartySocket: room name "${partySocketOptions.room}" contains forward slash which may cause routing issues. Consider using a name without forward slashes or set disableNameValidation: true to bypass this warning.` ); } } updateProperties(partySocketOptions) { const wsOptions = getWSOptions({ ...this.partySocketOptions, ...partySocketOptions, host: partySocketOptions.host ?? this.host, room: partySocketOptions.room ?? this.room, path: partySocketOptions.path ?? this.path, basePath: partySocketOptions.basePath ?? this.basePath }); this._url = wsOptions.urlProvider; this._protocols = wsOptions.protocols; this._options = wsOptions.socketOptions; this.setWSProperties(wsOptions); } setWSProperties(wsOptions) { const { _pk, _pkurl, name, room, host, path, basePath } = wsOptions; this._pk = _pk; this._pkurl = _pkurl; this.name = name; this.room = room; this.host = host; this.path = path; this.basePath = basePath; } reconnect(code, reason) { if (!this.host) throw new Error( "The host must be set before connecting, use `updateProperties` method to set it or pass it to the constructor." ); if (!this.room && !this.basePath) throw new Error( "The room (or basePath) must be set before connecting, use `updateProperties` method to set it or pass it to the constructor." ); super.reconnect(code, reason); } get id() { return this._pk; } /** * Exposes the static PartyKit room URL without applying query parameters. * To access the currently connected WebSocket url, use PartySocket#url. */ get roomUrl() { return this._pkurl; } static async fetch(options, init) { const party = getPartyInfo(options, "http"); const url = typeof party.urlProvider === "string" ? party.urlProvider : await party.urlProvider(); return (options.fetch ?? fetch)(url, init); } }; function getWSOptions(partySocketOptions) { const { id, host: _host, path: _path, party: _party, room: _room, protocol: _protocol, query: _query, protocols, ...socketOptions } = partySocketOptions; const _pk = id || generateUUID(); const party = getPartyInfo(partySocketOptions, "ws", { _pk }); return { _pk, _pkurl: party.partyUrl, name: party.name, room: party.room, host: party.host, path: party.path, basePath: partySocketOptions.basePath, protocols, socketOptions, urlProvider: party.urlProvider }; } //#endregion exports.PartySocket = PartySocket; exports.default = PartySocket; exports.WebSocket = require_ws.ReconnectingWebSocket; //# sourceMappingURL=index.cjs.map