partysocket
Advanced tools
Comparing version 0.0.0-185f8c9 to 0.0.0-188273c
@@ -23,2 +23,3 @@ "use strict"; | ||
__export(src_exports, { | ||
PartySocket: () => PartySocket, | ||
WebSocket: () => ReconnectingWebSocket, | ||
@@ -33,17 +34,7 @@ default: () => PartySocket | ||
PartySocket requires a global 'EventTarget' class to be available! | ||
You can use the 'event-target-shim' package to polyfill this. See https://www.npmjs.com/package/event-target-shim. | ||
First, run: | ||
You can polyfill this global by adding this to your code before any partysocket imports: | ||
\`\`\` | ||
npm install event-target-shim | ||
import 'partysocket/event-target-polyfill'; | ||
\`\`\` | ||
Then, add this in your code: | ||
\`\`\` | ||
import {Event, EventTarget} from 'event-target-shim'; | ||
if(!globalThis.Event) { | ||
globalThis.Event = Event; | ||
} | ||
if(!globalThis.EventTarget) { | ||
globalThis.EventTarget = EventTarget; | ||
} | ||
\`\`\` | ||
Please file an issue at https://github.com/partykit/partykit if you're still having trouble. | ||
@@ -85,3 +76,22 @@ `); | ||
function cloneEventNode(e) { | ||
return new Event(e.type, e); | ||
if ("data" in e) { | ||
const evt2 = new MessageEvent(e.type, e); | ||
return evt2; | ||
} | ||
if ("code" in e || "reason" in e) { | ||
const evt2 = new CloseEvent( | ||
// @ts-expect-error we need to fix event/listener types | ||
e.code || 1999, | ||
// @ts-expect-error we need to fix event/listener types | ||
e.reason || "unknown reason", | ||
e | ||
); | ||
return evt2; | ||
} | ||
if ("error" in e) { | ||
const evt2 = new ErrorEvent(e.error, e); | ||
return evt2; | ||
} | ||
const evt = new Event(e.type, e); | ||
return evt; | ||
} | ||
@@ -101,2 +111,3 @@ var isNode = typeof process !== "undefined" && typeof process.versions?.node !== "undefined" && typeof document === "undefined"; | ||
}; | ||
var didWarnAboutMissingWebSocket = false; | ||
var ReconnectingWebSocket = class _ReconnectingWebSocket extends EventTarget { | ||
@@ -112,2 +123,3 @@ _ws; | ||
_messageQueue = []; | ||
_debugLogger = console.log.bind(console); | ||
_url; | ||
@@ -124,2 +136,5 @@ _protocols; | ||
} | ||
if (this._options.debugLogger) { | ||
this._debugLogger = this._options.debugLogger; | ||
} | ||
this._connect(); | ||
@@ -288,3 +303,3 @@ } | ||
if (this._options.debug) { | ||
console.log.apply(console, ["RWS>", ...args]); | ||
this._debugLogger("RWS>", ...args); | ||
} | ||
@@ -314,4 +329,3 @@ } | ||
_getNextProtocols(protocolsProvider) { | ||
if (!protocolsProvider) | ||
return Promise.resolve(null); | ||
if (!protocolsProvider) return Promise.resolve(null); | ||
if (typeof protocolsProvider === "string" || Array.isArray(protocolsProvider)) { | ||
@@ -322,4 +336,3 @@ return Promise.resolve(protocolsProvider); | ||
const protocols = protocolsProvider(); | ||
if (!protocols) | ||
return Promise.resolve(null); | ||
if (!protocols) return Promise.resolve(null); | ||
if (typeof protocols === "string" || Array.isArray(protocols)) { | ||
@@ -375,2 +388,19 @@ return Promise.resolve(protocols); | ||
} | ||
if (!this._options.WebSocket && typeof WebSocket === "undefined" && !didWarnAboutMissingWebSocket) { | ||
console.error(`\u203C\uFE0F No WebSocket implementation available. You should define options.WebSocket. | ||
For example, if you're using node.js, run \`npm install ws\`, and then in your code: | ||
import PartySocket from 'partysocket'; | ||
import WS from 'ws'; | ||
const partysocket = new PartySocket({ | ||
host: "127.0.0.1:1999", | ||
room: "test-room", | ||
WebSocket: WS | ||
}); | ||
`); | ||
didWarnAboutMissingWebSocket = true; | ||
} | ||
const WS = this._options.WebSocket || WebSocket; | ||
@@ -483,2 +513,3 @@ this._debug("connect", { url, protocols }); | ||
// src/index.ts | ||
var valueIsNotNil = (keyValuePair) => keyValuePair[1] !== null && keyValuePair[1] !== void 0; | ||
function generateUUID() { | ||
@@ -502,28 +533,49 @@ if (typeof crypto !== "undefined" && crypto.randomUUID) { | ||
} | ||
function getPartyInfo(partySocketOptions, defaultProtocol, defaultParams = {}) { | ||
const { | ||
host: rawHost, | ||
path: rawPath, | ||
protocol: rawProtocol, | ||
room, | ||
party, | ||
query | ||
} = partySocketOptions; | ||
let host = rawHost.replace(/^(http|https|ws|wss):\/\//, ""); | ||
if (host.endsWith("/")) { | ||
host = host.slice(0, -1); | ||
} | ||
if (rawPath && 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]:") ? ( | ||
// http / ws | ||
defaultProtocol | ||
) : ( | ||
// https / wss | ||
defaultProtocol + "s" | ||
)); | ||
const baseUrl = `${protocol}://${host}/${party ? `parties/${party}` : "party"}/${room}${path}`; | ||
const makeUrl = (query2 = {}) => `${baseUrl}?${new URLSearchParams([ | ||
...Object.entries(defaultParams), | ||
...Object.entries(query2).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 ReconnectingWebSocket { | ||
constructor(partySocketOptions) { | ||
const { | ||
host: rawHost, | ||
room, | ||
party, | ||
protocol, | ||
query, | ||
protocols, | ||
...socketOptions | ||
} = partySocketOptions; | ||
const _pk = partySocketOptions.id || generateUUID(); | ||
const host = rawHost.replace(/^(http|https|ws|wss):\/\//, ""); | ||
let url = `${protocol || (host.startsWith("localhost:") || host.startsWith("127.0.0.1:") ? "ws" : "wss")}://${host}/${party ? `parties/${party}` : "party"}/${room}`; | ||
if (query) { | ||
url += `?${new URLSearchParams({ ...query, _pk }).toString()}`; | ||
} else { | ||
url += `?_pk=${_pk}`; | ||
} | ||
super(url, protocols, socketOptions); | ||
const wsOptions = getWSOptions(partySocketOptions); | ||
super(wsOptions.urlProvider, wsOptions.protocols, wsOptions.socketOptions); | ||
this.partySocketOptions = partySocketOptions; | ||
this._pk = _pk; | ||
this._pkurl = url; | ||
this.name = party ?? "main"; | ||
this.room = room; | ||
this.host = host; | ||
this.setWSProperties(wsOptions); | ||
} | ||
@@ -535,12 +587,80 @@ _pk; | ||
host; | ||
path; | ||
updateProperties(partySocketOptions) { | ||
const wsOptions = getWSOptions({ | ||
...this.partySocketOptions, | ||
...partySocketOptions, | ||
host: partySocketOptions.host ?? this.host, | ||
room: partySocketOptions.room ?? this.room, | ||
path: partySocketOptions.path ?? this.path | ||
}); | ||
this._url = wsOptions.urlProvider; | ||
this._protocols = wsOptions.protocols; | ||
this._options = wsOptions.socketOptions; | ||
this.setWSProperties(wsOptions); | ||
} | ||
setWSProperties(wsOptions) { | ||
const { _pk, _pkurl, name, room, host, path } = wsOptions; | ||
this._pk = _pk; | ||
this._pkurl = _pkurl; | ||
this.name = name; | ||
this.room = room; | ||
this.host = host; | ||
this.path = path; | ||
} | ||
reconnect(code, reason) { | ||
if (!this.room || !this.host) { | ||
throw new Error( | ||
"The room and host must be set before connecting, use `updateProperties` method to set them or pass them to the constructor." | ||
); | ||
} | ||
super.reconnect(code, reason); | ||
} | ||
get id() { | ||
return this._pk; | ||
} | ||
// partysocket has a static url, so we can just return that | ||
get url() { | ||
/** | ||
* 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; | ||
} | ||
// a `fetch` method that uses (almost) the same options as `PartySocket` | ||
static async fetch(options, init) { | ||
const party = getPartyInfo(options, "http"); | ||
const url = typeof party.urlProvider === "string" ? party.urlProvider : await party.urlProvider(); | ||
const doFetch = options.fetch ?? fetch; | ||
return doFetch(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, | ||
protocols, | ||
socketOptions, | ||
urlProvider: party.urlProvider | ||
}; | ||
} | ||
// Annotate the CommonJS export names for ESM import in node: | ||
0 && (module.exports = { | ||
PartySocket, | ||
WebSocket | ||
@@ -547,0 +667,0 @@ }); |
@@ -24,6 +24,6 @@ "use strict"; | ||
default: () => usePartySocket, | ||
usePartySocket: () => usePartySocket, | ||
useWebSocket: () => useWebSocket | ||
}); | ||
module.exports = __toCommonJS(react_exports); | ||
var import_react2 = require("react"); | ||
@@ -34,17 +34,7 @@ // src/ws.ts | ||
PartySocket requires a global 'EventTarget' class to be available! | ||
You can use the 'event-target-shim' package to polyfill this. See https://www.npmjs.com/package/event-target-shim. | ||
First, run: | ||
You can polyfill this global by adding this to your code before any partysocket imports: | ||
\`\`\` | ||
npm install event-target-shim | ||
import 'partysocket/event-target-polyfill'; | ||
\`\`\` | ||
Then, add this in your code: | ||
\`\`\` | ||
import {Event, EventTarget} from 'event-target-shim'; | ||
if(!globalThis.Event) { | ||
globalThis.Event = Event; | ||
} | ||
if(!globalThis.EventTarget) { | ||
globalThis.EventTarget = EventTarget; | ||
} | ||
\`\`\` | ||
Please file an issue at https://github.com/partykit/partykit if you're still having trouble. | ||
@@ -86,3 +76,22 @@ `); | ||
function cloneEventNode(e) { | ||
return new Event(e.type, e); | ||
if ("data" in e) { | ||
const evt2 = new MessageEvent(e.type, e); | ||
return evt2; | ||
} | ||
if ("code" in e || "reason" in e) { | ||
const evt2 = new CloseEvent( | ||
// @ts-expect-error we need to fix event/listener types | ||
e.code || 1999, | ||
// @ts-expect-error we need to fix event/listener types | ||
e.reason || "unknown reason", | ||
e | ||
); | ||
return evt2; | ||
} | ||
if ("error" in e) { | ||
const evt2 = new ErrorEvent(e.error, e); | ||
return evt2; | ||
} | ||
const evt = new Event(e.type, e); | ||
return evt; | ||
} | ||
@@ -102,2 +111,3 @@ var isNode = typeof process !== "undefined" && typeof process.versions?.node !== "undefined" && typeof document === "undefined"; | ||
}; | ||
var didWarnAboutMissingWebSocket = false; | ||
var ReconnectingWebSocket = class _ReconnectingWebSocket extends EventTarget { | ||
@@ -113,2 +123,3 @@ _ws; | ||
_messageQueue = []; | ||
_debugLogger = console.log.bind(console); | ||
_url; | ||
@@ -125,2 +136,5 @@ _protocols; | ||
} | ||
if (this._options.debugLogger) { | ||
this._debugLogger = this._options.debugLogger; | ||
} | ||
this._connect(); | ||
@@ -289,3 +303,3 @@ } | ||
if (this._options.debug) { | ||
console.log.apply(console, ["RWS>", ...args]); | ||
this._debugLogger("RWS>", ...args); | ||
} | ||
@@ -315,4 +329,3 @@ } | ||
_getNextProtocols(protocolsProvider) { | ||
if (!protocolsProvider) | ||
return Promise.resolve(null); | ||
if (!protocolsProvider) return Promise.resolve(null); | ||
if (typeof protocolsProvider === "string" || Array.isArray(protocolsProvider)) { | ||
@@ -323,4 +336,3 @@ return Promise.resolve(protocolsProvider); | ||
const protocols = protocolsProvider(); | ||
if (!protocols) | ||
return Promise.resolve(null); | ||
if (!protocols) return Promise.resolve(null); | ||
if (typeof protocols === "string" || Array.isArray(protocols)) { | ||
@@ -376,2 +388,19 @@ return Promise.resolve(protocols); | ||
} | ||
if (!this._options.WebSocket && typeof WebSocket === "undefined" && !didWarnAboutMissingWebSocket) { | ||
console.error(`\u203C\uFE0F No WebSocket implementation available. You should define options.WebSocket. | ||
For example, if you're using node.js, run \`npm install ws\`, and then in your code: | ||
import PartySocket from 'partysocket'; | ||
import WS from 'ws'; | ||
const partysocket = new PartySocket({ | ||
host: "127.0.0.1:1999", | ||
room: "test-room", | ||
WebSocket: WS | ||
}); | ||
`); | ||
didWarnAboutMissingWebSocket = true; | ||
} | ||
const WS = this._options.WebSocket || WebSocket; | ||
@@ -484,2 +513,3 @@ this._debug("connect", { url, protocols }); | ||
// src/index.ts | ||
var valueIsNotNil = (keyValuePair) => keyValuePair[1] !== null && keyValuePair[1] !== void 0; | ||
function generateUUID() { | ||
@@ -503,28 +533,49 @@ if (typeof crypto !== "undefined" && crypto.randomUUID) { | ||
} | ||
function getPartyInfo(partySocketOptions, defaultProtocol, defaultParams = {}) { | ||
const { | ||
host: rawHost, | ||
path: rawPath, | ||
protocol: rawProtocol, | ||
room, | ||
party, | ||
query | ||
} = partySocketOptions; | ||
let host = rawHost.replace(/^(http|https|ws|wss):\/\//, ""); | ||
if (host.endsWith("/")) { | ||
host = host.slice(0, -1); | ||
} | ||
if (rawPath && 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]:") ? ( | ||
// http / ws | ||
defaultProtocol | ||
) : ( | ||
// https / wss | ||
defaultProtocol + "s" | ||
)); | ||
const baseUrl = `${protocol}://${host}/${party ? `parties/${party}` : "party"}/${room}${path}`; | ||
const makeUrl = (query2 = {}) => `${baseUrl}?${new URLSearchParams([ | ||
...Object.entries(defaultParams), | ||
...Object.entries(query2).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 ReconnectingWebSocket { | ||
constructor(partySocketOptions) { | ||
const { | ||
host: rawHost, | ||
room, | ||
party, | ||
protocol, | ||
query, | ||
protocols, | ||
...socketOptions | ||
} = partySocketOptions; | ||
const _pk = partySocketOptions.id || generateUUID(); | ||
const host = rawHost.replace(/^(http|https|ws|wss):\/\//, ""); | ||
let url = `${protocol || (host.startsWith("localhost:") || host.startsWith("127.0.0.1:") ? "ws" : "wss")}://${host}/${party ? `parties/${party}` : "party"}/${room}`; | ||
if (query) { | ||
url += `?${new URLSearchParams({ ...query, _pk }).toString()}`; | ||
} else { | ||
url += `?_pk=${_pk}`; | ||
} | ||
super(url, protocols, socketOptions); | ||
const wsOptions = getWSOptions(partySocketOptions); | ||
super(wsOptions.urlProvider, wsOptions.protocols, wsOptions.socketOptions); | ||
this.partySocketOptions = partySocketOptions; | ||
this._pk = _pk; | ||
this._pkurl = url; | ||
this.name = party ?? "main"; | ||
this.room = room; | ||
this.host = host; | ||
this.setWSProperties(wsOptions); | ||
} | ||
@@ -536,104 +587,200 @@ _pk; | ||
host; | ||
path; | ||
updateProperties(partySocketOptions) { | ||
const wsOptions = getWSOptions({ | ||
...this.partySocketOptions, | ||
...partySocketOptions, | ||
host: partySocketOptions.host ?? this.host, | ||
room: partySocketOptions.room ?? this.room, | ||
path: partySocketOptions.path ?? this.path | ||
}); | ||
this._url = wsOptions.urlProvider; | ||
this._protocols = wsOptions.protocols; | ||
this._options = wsOptions.socketOptions; | ||
this.setWSProperties(wsOptions); | ||
} | ||
setWSProperties(wsOptions) { | ||
const { _pk, _pkurl, name, room, host, path } = wsOptions; | ||
this._pk = _pk; | ||
this._pkurl = _pkurl; | ||
this.name = name; | ||
this.room = room; | ||
this.host = host; | ||
this.path = path; | ||
} | ||
reconnect(code, reason) { | ||
if (!this.room || !this.host) { | ||
throw new Error( | ||
"The room and host must be set before connecting, use `updateProperties` method to set them or pass them to the constructor." | ||
); | ||
} | ||
super.reconnect(code, reason); | ||
} | ||
get id() { | ||
return this._pk; | ||
} | ||
// partysocket has a static url, so we can just return that | ||
get url() { | ||
/** | ||
* 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; | ||
} | ||
// a `fetch` method that uses (almost) the same options as `PartySocket` | ||
static async fetch(options, init) { | ||
const party = getPartyInfo(options, "http"); | ||
const url = typeof party.urlProvider === "string" ? party.urlProvider : await party.urlProvider(); | ||
const doFetch = options.fetch ?? fetch; | ||
return doFetch(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, | ||
protocols, | ||
socketOptions, | ||
urlProvider: party.urlProvider | ||
}; | ||
} | ||
// src/use-ws.ts | ||
// src/use-handlers.ts | ||
var import_react = require("react"); | ||
function useWebSocket(url, protocols, options) { | ||
const [startClosed] = (0, import_react.useState)(options?.startClosed || false); | ||
const { onOpen, onMessage, onClose, onError, ...webSocketOptions } = options || {}; | ||
const socketRef = (0, import_react.useRef)( | ||
new ReconnectingWebSocket(url, protocols, { | ||
...webSocketOptions, | ||
startClosed: true | ||
// only connect on mount | ||
}) | ||
); | ||
var useAttachWebSocketEventHandlers = (socket, options) => { | ||
const handlersRef = (0, import_react.useRef)(options); | ||
handlersRef.current = options; | ||
(0, import_react.useEffect)(() => { | ||
const socket = socketRef.current; | ||
if (onOpen) | ||
socket.addEventListener("open", onOpen); | ||
if (onClose) | ||
socket.addEventListener("close", onClose); | ||
if (onError) | ||
socket.addEventListener("error", onError); | ||
if (onMessage) | ||
socket.addEventListener("message", onMessage); | ||
const onOpen = (event) => handlersRef.current?.onOpen?.(event); | ||
const onMessage = (event) => handlersRef.current?.onMessage?.(event); | ||
const onClose = (event) => handlersRef.current?.onClose?.(event); | ||
const onError = (event) => handlersRef.current?.onError?.(event); | ||
socket.addEventListener("open", onOpen); | ||
socket.addEventListener("close", onClose); | ||
socket.addEventListener("error", onError); | ||
socket.addEventListener("message", onMessage); | ||
return () => { | ||
if (onOpen) | ||
socket.removeEventListener("open", onOpen); | ||
if (onClose) | ||
socket.removeEventListener("close", onClose); | ||
if (onError) | ||
socket.removeEventListener("error", onError); | ||
if (onMessage) | ||
socket.removeEventListener("message", onMessage); | ||
socket.removeEventListener("open", onOpen); | ||
socket.removeEventListener("close", onClose); | ||
socket.removeEventListener("error", onError); | ||
socket.removeEventListener("message", onMessage); | ||
}; | ||
}, [onOpen, onMessage, onClose, onError]); | ||
(0, import_react.useEffect)(() => { | ||
const socket = socketRef.current; | ||
if (startClosed !== true) { | ||
socket.reconnect(); | ||
} | ||
return () => { | ||
socket.close(); | ||
}; | ||
}, [startClosed]); | ||
return socketRef.current; | ||
} | ||
}, [socket]); | ||
}; | ||
// src/react.ts | ||
function usePartySocket(options) { | ||
const { onOpen, onMessage, onClose, onError, ...partySocketOptions } = options; | ||
const socketRef = (0, import_react2.useRef)( | ||
new PartySocket({ | ||
...partySocketOptions, | ||
startClosed: true | ||
// only connect on mount | ||
}) | ||
// src/use-socket.ts | ||
var import_react2 = require("react"); | ||
var getOptionsThatShouldCauseRestartWhenChanged = (options) => [ | ||
options.startClosed, | ||
options.minUptime, | ||
options.maxRetries, | ||
options.connectionTimeout, | ||
options.maxEnqueuedMessages, | ||
options.maxReconnectionDelay, | ||
options.minReconnectionDelay, | ||
options.reconnectionDelayGrowFactor, | ||
options.debug | ||
]; | ||
function useStableSocket({ | ||
options, | ||
createSocket, | ||
createSocketMemoKey: createOptionsMemoKey | ||
}) { | ||
const shouldReconnect = createOptionsMemoKey(options); | ||
const socketOptions = (0, import_react2.useMemo)(() => { | ||
return options; | ||
}, [shouldReconnect]); | ||
const [socket, setSocket] = (0, import_react2.useState)( | ||
() => ( | ||
// only connect on first mount | ||
createSocket({ ...socketOptions, startClosed: true }) | ||
) | ||
); | ||
const socketInitializedRef = (0, import_react2.useRef)(null); | ||
const createSocketRef = (0, import_react2.useRef)(createSocket); | ||
createSocketRef.current = createSocket; | ||
(0, import_react2.useEffect)(() => { | ||
const socket = socketRef.current; | ||
if (onOpen) | ||
socket.addEventListener("open", onOpen); | ||
if (onClose) | ||
socket.addEventListener("close", onClose); | ||
if (onError) | ||
socket.addEventListener("error", onError); | ||
if (onMessage) | ||
socket.addEventListener("message", onMessage); | ||
return () => { | ||
if (onOpen) | ||
socket.removeEventListener("open", onOpen); | ||
if (onClose) | ||
socket.removeEventListener("close", onClose); | ||
if (onError) | ||
socket.removeEventListener("error", onError); | ||
if (onMessage) | ||
socket.removeEventListener("message", onMessage); | ||
}; | ||
}, [onOpen, onMessage, onClose, onError]); | ||
(0, import_react2.useEffect)( | ||
() => { | ||
const socket = socketRef.current; | ||
if (options.startClosed !== true) { | ||
if (socketInitializedRef.current === socket) { | ||
const newSocket = createSocketRef.current({ | ||
...socketOptions, | ||
// when reconnecting because of options change, we always reconnect | ||
// (startClosed only applies to initial mount) | ||
startClosed: false | ||
}); | ||
setSocket(newSocket); | ||
} else { | ||
if (!socketInitializedRef.current && socketOptions.startClosed !== true) { | ||
socket.reconnect(); | ||
} | ||
socketInitializedRef.current = socket; | ||
return () => { | ||
socket.close(); | ||
}; | ||
} | ||
}, [socket, socketOptions]); | ||
return socket; | ||
} | ||
// src/use-ws.ts | ||
function useWebSocket(url, protocols, options = {}) { | ||
const socket = useStableSocket({ | ||
options, | ||
createSocket: (options2) => new ReconnectingWebSocket(url, protocols, options2), | ||
createSocketMemoKey: (options2) => JSON.stringify([ | ||
// will reconnect if url or protocols are specified as a string. | ||
// if they are functions, the WebSocket will handle reconnection | ||
url, | ||
protocols, | ||
...getOptionsThatShouldCauseRestartWhenChanged(options2) | ||
]) | ||
}); | ||
useAttachWebSocketEventHandlers(socket, options); | ||
return socket; | ||
} | ||
// src/react.ts | ||
function usePartySocket(options) { | ||
const { host, ...otherOptions } = options; | ||
const socket = useStableSocket({ | ||
options: { | ||
host: host || (typeof window !== "undefined" ? window.location.host : "dummy-domain.com"), | ||
...otherOptions | ||
}, | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
[] | ||
); | ||
return socketRef.current; | ||
createSocket: (options2) => new PartySocket(options2), | ||
createSocketMemoKey: (options2) => JSON.stringify([ | ||
// NOTE: if query is defined as a function, the socket | ||
// won't reconnect when you change the function identity | ||
options2.query, | ||
options2.id, | ||
options2.host, | ||
options2.room, | ||
options2.party, | ||
options2.path, | ||
options2.protocol, | ||
options2.protocols, | ||
...getOptionsThatShouldCauseRestartWhenChanged(options2) | ||
]) | ||
}); | ||
useAttachWebSocketEventHandlers(socket, options); | ||
return socket; | ||
} | ||
// Annotate the CommonJS export names for ESM import in node: | ||
0 && (module.exports = { | ||
usePartySocket, | ||
useWebSocket | ||
@@ -640,0 +787,0 @@ }); |
@@ -26,4 +26,79 @@ "use strict"; | ||
module.exports = __toCommonJS(use_ws_exports); | ||
// src/use-handlers.ts | ||
var import_react = require("react"); | ||
var useAttachWebSocketEventHandlers = (socket, options) => { | ||
const handlersRef = (0, import_react.useRef)(options); | ||
handlersRef.current = options; | ||
(0, import_react.useEffect)(() => { | ||
const onOpen = (event) => handlersRef.current?.onOpen?.(event); | ||
const onMessage = (event) => handlersRef.current?.onMessage?.(event); | ||
const onClose = (event) => handlersRef.current?.onClose?.(event); | ||
const onError = (event) => handlersRef.current?.onError?.(event); | ||
socket.addEventListener("open", onOpen); | ||
socket.addEventListener("close", onClose); | ||
socket.addEventListener("error", onError); | ||
socket.addEventListener("message", onMessage); | ||
return () => { | ||
socket.removeEventListener("open", onOpen); | ||
socket.removeEventListener("close", onClose); | ||
socket.removeEventListener("error", onError); | ||
socket.removeEventListener("message", onMessage); | ||
}; | ||
}, [socket]); | ||
}; | ||
// src/use-socket.ts | ||
var import_react2 = require("react"); | ||
var getOptionsThatShouldCauseRestartWhenChanged = (options) => [ | ||
options.startClosed, | ||
options.minUptime, | ||
options.maxRetries, | ||
options.connectionTimeout, | ||
options.maxEnqueuedMessages, | ||
options.maxReconnectionDelay, | ||
options.minReconnectionDelay, | ||
options.reconnectionDelayGrowFactor, | ||
options.debug | ||
]; | ||
function useStableSocket({ | ||
options, | ||
createSocket, | ||
createSocketMemoKey: createOptionsMemoKey | ||
}) { | ||
const shouldReconnect = createOptionsMemoKey(options); | ||
const socketOptions = (0, import_react2.useMemo)(() => { | ||
return options; | ||
}, [shouldReconnect]); | ||
const [socket, setSocket] = (0, import_react2.useState)( | ||
() => ( | ||
// only connect on first mount | ||
createSocket({ ...socketOptions, startClosed: true }) | ||
) | ||
); | ||
const socketInitializedRef = (0, import_react2.useRef)(null); | ||
const createSocketRef = (0, import_react2.useRef)(createSocket); | ||
createSocketRef.current = createSocket; | ||
(0, import_react2.useEffect)(() => { | ||
if (socketInitializedRef.current === socket) { | ||
const newSocket = createSocketRef.current({ | ||
...socketOptions, | ||
// when reconnecting because of options change, we always reconnect | ||
// (startClosed only applies to initial mount) | ||
startClosed: false | ||
}); | ||
setSocket(newSocket); | ||
} else { | ||
if (!socketInitializedRef.current && socketOptions.startClosed !== true) { | ||
socket.reconnect(); | ||
} | ||
socketInitializedRef.current = socket; | ||
return () => { | ||
socket.close(); | ||
}; | ||
} | ||
}, [socket, socketOptions]); | ||
return socket; | ||
} | ||
// src/ws.ts | ||
@@ -33,17 +108,7 @@ if (!globalThis.EventTarget || !globalThis.Event) { | ||
PartySocket requires a global 'EventTarget' class to be available! | ||
You can use the 'event-target-shim' package to polyfill this. See https://www.npmjs.com/package/event-target-shim. | ||
First, run: | ||
You can polyfill this global by adding this to your code before any partysocket imports: | ||
\`\`\` | ||
npm install event-target-shim | ||
import 'partysocket/event-target-polyfill'; | ||
\`\`\` | ||
Then, add this in your code: | ||
\`\`\` | ||
import {Event, EventTarget} from 'event-target-shim'; | ||
if(!globalThis.Event) { | ||
globalThis.Event = Event; | ||
} | ||
if(!globalThis.EventTarget) { | ||
globalThis.EventTarget = EventTarget; | ||
} | ||
\`\`\` | ||
Please file an issue at https://github.com/partykit/partykit if you're still having trouble. | ||
@@ -85,3 +150,22 @@ `); | ||
function cloneEventNode(e) { | ||
return new Event(e.type, e); | ||
if ("data" in e) { | ||
const evt2 = new MessageEvent(e.type, e); | ||
return evt2; | ||
} | ||
if ("code" in e || "reason" in e) { | ||
const evt2 = new CloseEvent( | ||
// @ts-expect-error we need to fix event/listener types | ||
e.code || 1999, | ||
// @ts-expect-error we need to fix event/listener types | ||
e.reason || "unknown reason", | ||
e | ||
); | ||
return evt2; | ||
} | ||
if ("error" in e) { | ||
const evt2 = new ErrorEvent(e.error, e); | ||
return evt2; | ||
} | ||
const evt = new Event(e.type, e); | ||
return evt; | ||
} | ||
@@ -101,2 +185,3 @@ var isNode = typeof process !== "undefined" && typeof process.versions?.node !== "undefined" && typeof document === "undefined"; | ||
}; | ||
var didWarnAboutMissingWebSocket = false; | ||
var ReconnectingWebSocket = class _ReconnectingWebSocket extends EventTarget { | ||
@@ -112,2 +197,3 @@ _ws; | ||
_messageQueue = []; | ||
_debugLogger = console.log.bind(console); | ||
_url; | ||
@@ -124,2 +210,5 @@ _protocols; | ||
} | ||
if (this._options.debugLogger) { | ||
this._debugLogger = this._options.debugLogger; | ||
} | ||
this._connect(); | ||
@@ -288,3 +377,3 @@ } | ||
if (this._options.debug) { | ||
console.log.apply(console, ["RWS>", ...args]); | ||
this._debugLogger("RWS>", ...args); | ||
} | ||
@@ -314,4 +403,3 @@ } | ||
_getNextProtocols(protocolsProvider) { | ||
if (!protocolsProvider) | ||
return Promise.resolve(null); | ||
if (!protocolsProvider) return Promise.resolve(null); | ||
if (typeof protocolsProvider === "string" || Array.isArray(protocolsProvider)) { | ||
@@ -322,4 +410,3 @@ return Promise.resolve(protocolsProvider); | ||
const protocols = protocolsProvider(); | ||
if (!protocols) | ||
return Promise.resolve(null); | ||
if (!protocols) return Promise.resolve(null); | ||
if (typeof protocols === "string" || Array.isArray(protocols)) { | ||
@@ -375,2 +462,19 @@ return Promise.resolve(protocols); | ||
} | ||
if (!this._options.WebSocket && typeof WebSocket === "undefined" && !didWarnAboutMissingWebSocket) { | ||
console.error(`\u203C\uFE0F No WebSocket implementation available. You should define options.WebSocket. | ||
For example, if you're using node.js, run \`npm install ws\`, and then in your code: | ||
import PartySocket from 'partysocket'; | ||
import WS from 'ws'; | ||
const partysocket = new PartySocket({ | ||
host: "127.0.0.1:1999", | ||
room: "test-room", | ||
WebSocket: WS | ||
}); | ||
`); | ||
didWarnAboutMissingWebSocket = true; | ||
} | ||
const WS = this._options.WebSocket || WebSocket; | ||
@@ -483,43 +587,16 @@ this._debug("connect", { url, protocols }); | ||
// src/use-ws.ts | ||
function useWebSocket(url, protocols, options) { | ||
const [startClosed] = (0, import_react.useState)(options?.startClosed || false); | ||
const { onOpen, onMessage, onClose, onError, ...webSocketOptions } = options || {}; | ||
const socketRef = (0, import_react.useRef)( | ||
new ReconnectingWebSocket(url, protocols, { | ||
...webSocketOptions, | ||
startClosed: true | ||
// only connect on mount | ||
}) | ||
); | ||
(0, import_react.useEffect)(() => { | ||
const socket = socketRef.current; | ||
if (onOpen) | ||
socket.addEventListener("open", onOpen); | ||
if (onClose) | ||
socket.addEventListener("close", onClose); | ||
if (onError) | ||
socket.addEventListener("error", onError); | ||
if (onMessage) | ||
socket.addEventListener("message", onMessage); | ||
return () => { | ||
if (onOpen) | ||
socket.removeEventListener("open", onOpen); | ||
if (onClose) | ||
socket.removeEventListener("close", onClose); | ||
if (onError) | ||
socket.removeEventListener("error", onError); | ||
if (onMessage) | ||
socket.removeEventListener("message", onMessage); | ||
}; | ||
}, [onOpen, onMessage, onClose, onError]); | ||
(0, import_react.useEffect)(() => { | ||
const socket = socketRef.current; | ||
if (startClosed !== true) { | ||
socket.reconnect(); | ||
} | ||
return () => { | ||
socket.close(); | ||
}; | ||
}, [startClosed]); | ||
return socketRef.current; | ||
function useWebSocket(url, protocols, options = {}) { | ||
const socket = useStableSocket({ | ||
options, | ||
createSocket: (options2) => new ReconnectingWebSocket(url, protocols, options2), | ||
createSocketMemoKey: (options2) => JSON.stringify([ | ||
// will reconnect if url or protocols are specified as a string. | ||
// if they are functions, the WebSocket will handle reconnection | ||
url, | ||
protocols, | ||
...getOptionsThatShouldCauseRestartWhenChanged(options2) | ||
]) | ||
}); | ||
useAttachWebSocketEventHandlers(socket, options); | ||
return socket; | ||
} | ||
@@ -526,0 +603,0 @@ /*! |
@@ -31,17 +31,7 @@ "use strict"; | ||
PartySocket requires a global 'EventTarget' class to be available! | ||
You can use the 'event-target-shim' package to polyfill this. See https://www.npmjs.com/package/event-target-shim. | ||
First, run: | ||
You can polyfill this global by adding this to your code before any partysocket imports: | ||
\`\`\` | ||
npm install event-target-shim | ||
import 'partysocket/event-target-polyfill'; | ||
\`\`\` | ||
Then, add this in your code: | ||
\`\`\` | ||
import {Event, EventTarget} from 'event-target-shim'; | ||
if(!globalThis.Event) { | ||
globalThis.Event = Event; | ||
} | ||
if(!globalThis.EventTarget) { | ||
globalThis.EventTarget = EventTarget; | ||
} | ||
\`\`\` | ||
Please file an issue at https://github.com/partykit/partykit if you're still having trouble. | ||
@@ -83,3 +73,22 @@ `); | ||
function cloneEventNode(e) { | ||
return new Event(e.type, e); | ||
if ("data" in e) { | ||
const evt2 = new MessageEvent(e.type, e); | ||
return evt2; | ||
} | ||
if ("code" in e || "reason" in e) { | ||
const evt2 = new CloseEvent( | ||
// @ts-expect-error we need to fix event/listener types | ||
e.code || 1999, | ||
// @ts-expect-error we need to fix event/listener types | ||
e.reason || "unknown reason", | ||
e | ||
); | ||
return evt2; | ||
} | ||
if ("error" in e) { | ||
const evt2 = new ErrorEvent(e.error, e); | ||
return evt2; | ||
} | ||
const evt = new Event(e.type, e); | ||
return evt; | ||
} | ||
@@ -99,2 +108,3 @@ var isNode = typeof process !== "undefined" && typeof process.versions?.node !== "undefined" && typeof document === "undefined"; | ||
}; | ||
var didWarnAboutMissingWebSocket = false; | ||
var ReconnectingWebSocket = class _ReconnectingWebSocket extends EventTarget { | ||
@@ -110,2 +120,3 @@ _ws; | ||
_messageQueue = []; | ||
_debugLogger = console.log.bind(console); | ||
_url; | ||
@@ -122,2 +133,5 @@ _protocols; | ||
} | ||
if (this._options.debugLogger) { | ||
this._debugLogger = this._options.debugLogger; | ||
} | ||
this._connect(); | ||
@@ -286,3 +300,3 @@ } | ||
if (this._options.debug) { | ||
console.log.apply(console, ["RWS>", ...args]); | ||
this._debugLogger("RWS>", ...args); | ||
} | ||
@@ -312,4 +326,3 @@ } | ||
_getNextProtocols(protocolsProvider) { | ||
if (!protocolsProvider) | ||
return Promise.resolve(null); | ||
if (!protocolsProvider) return Promise.resolve(null); | ||
if (typeof protocolsProvider === "string" || Array.isArray(protocolsProvider)) { | ||
@@ -320,4 +333,3 @@ return Promise.resolve(protocolsProvider); | ||
const protocols = protocolsProvider(); | ||
if (!protocols) | ||
return Promise.resolve(null); | ||
if (!protocols) return Promise.resolve(null); | ||
if (typeof protocols === "string" || Array.isArray(protocols)) { | ||
@@ -373,2 +385,19 @@ return Promise.resolve(protocols); | ||
} | ||
if (!this._options.WebSocket && typeof WebSocket === "undefined" && !didWarnAboutMissingWebSocket) { | ||
console.error(`\u203C\uFE0F No WebSocket implementation available. You should define options.WebSocket. | ||
For example, if you're using node.js, run \`npm install ws\`, and then in your code: | ||
import PartySocket from 'partysocket'; | ||
import WS from 'ws'; | ||
const partysocket = new PartySocket({ | ||
host: "127.0.0.1:1999", | ||
room: "test-room", | ||
WebSocket: WS | ||
}); | ||
`); | ||
didWarnAboutMissingWebSocket = true; | ||
} | ||
const WS = this._options.WebSocket || WebSocket; | ||
@@ -375,0 +404,0 @@ this._debug("connect", { url, protocols }); |
import ReconnectingWebSocket, { Options } from './ws.js'; | ||
type Maybe<T> = T | null | undefined; | ||
type Params = Record<string, Maybe<string>>; | ||
type PartySocketOptions = Omit<Options, "constructor"> & { | ||
id?: string; | ||
host: string; | ||
room: string; | ||
room?: string; | ||
party?: string; | ||
protocol?: string; | ||
protocol?: "ws" | "wss"; | ||
protocols?: string[]; | ||
query?: Record<string, string>; | ||
path?: string; | ||
query?: Params | (() => Params | Promise<Params>); | ||
}; | ||
type PartyFetchOptions = { | ||
host: string; | ||
room: string; | ||
party?: string; | ||
path?: string; | ||
protocol?: "http" | "https"; | ||
query?: Params | (() => Params | Promise<Params>); | ||
fetch?: typeof fetch; | ||
}; | ||
declare class PartySocket extends ReconnectingWebSocket { | ||
@@ -17,9 +29,18 @@ readonly partySocketOptions: PartySocketOptions; | ||
name: string; | ||
room: string; | ||
room?: string; | ||
host: string; | ||
path: string; | ||
constructor(partySocketOptions: PartySocketOptions); | ||
updateProperties(partySocketOptions: Partial<PartySocketOptions>): void; | ||
private setWSProperties; | ||
reconnect(code?: number | undefined, reason?: string | undefined): void; | ||
get id(): string; | ||
get url(): string; | ||
/** | ||
* Exposes the static PartyKit room URL without applying query parameters. | ||
* To access the currently connected WebSocket url, use PartySocket#url. | ||
*/ | ||
get roomUrl(): string; | ||
static fetch(options: PartyFetchOptions, init?: RequestInit): Promise<Response>; | ||
} | ||
export { PartySocketOptions, ReconnectingWebSocket as WebSocket, PartySocket as default }; | ||
export { type PartyFetchOptions, PartySocket, type PartySocketOptions, ReconnectingWebSocket as WebSocket, PartySocket as default }; |
{ | ||
"name": "partysocket", | ||
"version": "0.0.0-185f8c9", | ||
"description": "party hotline", | ||
"version": "0.0.0-188273c", | ||
"description": "A better WebSocket that Just Works™", | ||
"homepage": "https://docs.partykit.io/reference/partysocket-api", | ||
"bugs": "https://github.com/partykit/partykit/issues", | ||
"main": "./dist/index.js", | ||
@@ -27,2 +29,7 @@ "module": "./dist/index.mjs", | ||
"require": "./dist/use-ws.js" | ||
}, | ||
"./event-target-polyfill": { | ||
"types": "./event-target-polyfill.d.ts", | ||
"import": "./dist/event-target-polyfill.mjs", | ||
"require": "./dist/event-target-polyfill.js" | ||
} | ||
@@ -35,3 +42,4 @@ }, | ||
"src/ws.ts", | ||
"src/use-ws.ts" | ||
"src/use-ws.ts", | ||
"src/event-target-polyfill.ts" | ||
], | ||
@@ -44,9 +52,6 @@ "format": [ | ||
}, | ||
"dependencies": { | ||
"react": "^18.2.0" | ||
}, | ||
"scripts": { | ||
"clean": "shx rm -rf dist *.d.ts", | ||
"post-build": "shx mv dist/*.d.ts* .", | ||
"build": "npm run clean && tsup && npm run post-build", | ||
"clean": "shx rm -rf dist *.d.ts *.d.mts event-target-polyfill.*", | ||
"post-build": "shx mv dist/*.d.ts dist/*.d.mts* . && shx mv dist/event-target-polyfill.* .", | ||
"build": "npm run clean && tsup --external react && npm run post-build", | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
@@ -56,7 +61,26 @@ }, | ||
"dist", | ||
"*.d.ts" | ||
"*.d.ts", | ||
"event-target-polyfill.*" | ||
], | ||
"keywords": [], | ||
"keywords": [ | ||
"websocket", | ||
"client", | ||
"reconnecting", | ||
"reconnection", | ||
"reconnect", | ||
"forever", | ||
"persistent", | ||
"forever", | ||
"automatic" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/partykit/partykit.git", | ||
"directory": "packages/partykit" | ||
}, | ||
"author": "", | ||
"license": "ISC" | ||
"license": "ISC", | ||
"dependencies": { | ||
"event-target-shim": "^6.0.2" | ||
} | ||
} |
@@ -1,13 +0,11 @@ | ||
import PartySocket, { PartySocketOptions } from './index.js'; | ||
export { default as useWebSocket } from './use-ws.js'; | ||
import { PartySocket, PartySocketOptions } from './index.js'; | ||
import { E as EventHandlerOptions } from './use-ws-CnrrNZS2.js'; | ||
export { u as useWebSocket } from './use-ws-CnrrNZS2.js'; | ||
import './ws.js'; | ||
type UsePartySocketOptions = PartySocketOptions & { | ||
onOpen?: (event: WebSocketEventMap["open"]) => void; | ||
onMessage?: (event: WebSocketEventMap["message"]) => void; | ||
onClose?: (event: WebSocketEventMap["close"]) => void; | ||
onError?: (event: WebSocketEventMap["error"]) => void; | ||
type UsePartySocketOptions = Omit<PartySocketOptions, "host"> & EventHandlerOptions & { | ||
host?: string | undefined; | ||
}; | ||
declare function usePartySocket(options: UsePartySocketOptions): PartySocket; | ||
export { usePartySocket as default }; | ||
export { usePartySocket as default, usePartySocket }; |
@@ -49,2 +49,5 @@ # PartySocket | ||
// optional: only needed if creating using inside node.js. Run `npm install ws`, and then add: | ||
// import WS from "ws"; | ||
const ws = new PartySocket({ | ||
@@ -55,4 +58,15 @@ host: "project.name.partykit.dev", // or localhost:1999 in dev | ||
// if not provided, a random id will be generated | ||
id: "some-connection-id", | ||
id: "some-connection-id" | ||
// optional: if used from node.js, you need to pass the WebSocket polyfill imported from `ws` | ||
// WebSocket: WS | ||
}); | ||
// optionally, update the properties of the connection | ||
// (e.g. to change the host or room) | ||
ws.updateProperties({ | ||
host: "another-project.username.partykit.dev", | ||
room: "my-new-room" | ||
}); | ||
ws.reconnect(); // make sure to call reconnect() after updating the properties | ||
``` | ||
@@ -74,3 +88,3 @@ | ||
"wss://your.site.com", | ||
"wss://their.site.com", | ||
"wss://their.site.com" | ||
]; | ||
@@ -109,2 +123,3 @@ let urlIndex = 0; | ||
import { WebSocket } from "partysocket"; | ||
const ws = new WebSocket("wss://your.site.com", "your protocol"); | ||
@@ -136,3 +151,3 @@ ``` | ||
connectionTimeout: 1000, | ||
maxRetries: 10, | ||
maxRetries: 10 | ||
}; | ||
@@ -139,0 +154,0 @@ const ws = new WebSocket("wss://my.site.com", [], options); |
@@ -1,11 +0,2 @@ | ||
import ReconnectingWebSocket, { UrlProvider, ProtocolsProvider, Options } from './ws.js'; | ||
type UseWebSocketOptions = Options & { | ||
onOpen?: (event: WebSocketEventMap["open"]) => void; | ||
onMessage?: (event: WebSocketEventMap["message"]) => void; | ||
onClose?: (event: WebSocketEventMap["close"]) => void; | ||
onError?: (event: WebSocketEventMap["error"]) => void; | ||
}; | ||
declare function useWebSocket(url: UrlProvider, protocols?: ProtocolsProvider, options?: UseWebSocketOptions): ReconnectingWebSocket; | ||
export { useWebSocket as default }; | ||
import './ws.js'; | ||
export { u as default } from './use-ws-CnrrNZS2.js'; |
10
ws.d.ts
@@ -46,2 +46,3 @@ type TypedEventTarget<EventMap extends object> = { | ||
debug?: boolean; | ||
debugLogger?: (...args: any[]) => void; | ||
}; | ||
@@ -62,5 +63,6 @@ type UrlProvider = string | (() => string) | (() => Promise<string>); | ||
private _messageQueue; | ||
private readonly _url; | ||
private readonly _protocols?; | ||
private readonly _options; | ||
private _debugLogger; | ||
protected _url: UrlProvider; | ||
protected _protocols?: ProtocolsProvider; | ||
protected _options: Options; | ||
constructor(url: UrlProvider, protocols?: ProtocolsProvider, options?: Options); | ||
@@ -160,2 +162,2 @@ static get CONNECTING(): number; | ||
export { CloseEvent, ErrorEvent, Message, Options, ProtocolsProvider, UrlProvider, WebSocketEventMap, ReconnectingWebSocket as default }; | ||
export { CloseEvent, ErrorEvent, type Message, type Options, type ProtocolsProvider, type UrlProvider, type WebSocketEventMap, ReconnectingWebSocket as default }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
116016
23
3552
2
230
0
3
+ Addedevent-target-shim@^6.0.2
+ Addedevent-target-shim@6.0.2(transitive)
- Removedreact@^18.2.0
- Removedjs-tokens@4.0.0(transitive)
- Removedloose-envify@1.4.0(transitive)
- Removedreact@18.3.1(transitive)