New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

partysocket

Package Overview
Dependencies
Maintainers
1
Versions
933
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

partysocket - npm Package Compare versions

Comparing version

to
0.0.0-a7531e3

dist/chunk-G2EOJEOR.mjs

224

dist/index.js

@@ -23,2 +23,4 @@ "use strict";

__export(src_exports, {
PartySocket: () => PartySocket,
WebSocket: () => ReconnectingWebSocket,
default: () => PartySocket

@@ -29,2 +31,13 @@ });

// src/ws.ts
if (!globalThis.EventTarget || !globalThis.Event) {
console.error(`
PartySocket requires a global 'EventTarget' class to be available!
You can polyfill this global by adding this to your code before any partysocket imports:
\`\`\`
import 'partysocket/event-target-polyfill';
\`\`\`
Please file an issue at https://github.com/partykit/partykit if you're still having trouble.
`);
}
var ErrorEvent = class extends Event {

@@ -59,8 +72,29 @@ message;

}
function isWebSocket(w) {
return typeof w !== "undefined" && !!w && typeof w === "function" && "CLOSING" in w && w.CLOSING === 2;
}
function cloneEvent(e) {
function cloneEventBrowser(e) {
return new e.constructor(e.type, e);
}
function cloneEventNode(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;
}
var isNode = typeof process !== "undefined" && typeof process.versions?.node !== "undefined" && typeof document === "undefined";
var cloneEvent = isNode ? cloneEventNode : cloneEventBrowser;
var DEFAULT = {

@@ -77,3 +111,4 @@ maxReconnectionDelay: 1e4,

};
var ReconnectingWebSocket = class extends EventTarget {
var didWarnAboutMissingWebSocket = false;
var ReconnectingWebSocket = class _ReconnectingWebSocket extends EventTarget {
_ws;

@@ -88,2 +123,3 @@ _retryCount = -1;

_messageQueue = [];
_debugLogger = console.log.bind(console);
_url;

@@ -100,2 +136,5 @@ _protocols;

}
if (this._options.debugLogger) {
this._debugLogger = this._options.debugLogger;
}
this._connect();

@@ -116,12 +155,12 @@ }

get CONNECTING() {
return ReconnectingWebSocket.CONNECTING;
return _ReconnectingWebSocket.CONNECTING;
}
get OPEN() {
return ReconnectingWebSocket.OPEN;
return _ReconnectingWebSocket.OPEN;
}
get CLOSING() {
return ReconnectingWebSocket.CLOSING;
return _ReconnectingWebSocket.CLOSING;
}
get CLOSED() {
return ReconnectingWebSocket.CLOSED;
return _ReconnectingWebSocket.CLOSED;
}

@@ -184,3 +223,3 @@ get binaryType() {

}
return this._options.startClosed ? ReconnectingWebSocket.CLOSED : ReconnectingWebSocket.CONNECTING;
return this._options.startClosed ? _ReconnectingWebSocket.CLOSED : _ReconnectingWebSocket.CONNECTING;
}

@@ -266,3 +305,3 @@ /**

if (this._options.debug) {
console.log.apply(console, ["RWS>", ...args]);
this._debugLogger("RWS>", ...args);
}

@@ -341,5 +380,2 @@ }

this._removeListeners();
if (!isWebSocket(WebSocket)) {
throw Error("No valid WebSocket class provided");
}
this._wait().then(

@@ -355,4 +391,22 @@ () => Promise.all([

}
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;
this._debug("connect", { url, protocols });
this._ws = protocols ? new WebSocket(url, protocols) : new WebSocket(url);
this._ws = protocols ? new WS(url, protocols) : new WS(url);
this._ws.binaryType = this._binaryType;

@@ -462,4 +516,5 @@ this._connectLock = false;

// src/index.ts
var valueIsNotNil = (keyValuePair) => keyValuePair[1] !== null && keyValuePair[1] !== void 0;
function generateUUID() {
if (crypto.randomUUID) {
if (typeof crypto !== "undefined" && crypto.randomUUID) {
return crypto.randomUUID();

@@ -481,18 +536,135 @@ }

}
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, room, protocol, query, protocols, ...socketOptions } = partySocketOptions;
const _pk = partySocketOptions.id || generateUUID();
let url = `${protocol || (host.startsWith("localhost:") || host.startsWith("127.0.0.1:") ? "ws" : "wss")}://${host}/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.setWSProperties(wsOptions);
}
_pk;
_pkurl;
name;
room;
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;
}
_pk;
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;
}
/**
* 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
});
/*!

@@ -499,0 +671,0 @@ * Reconnecting WebSocket

@@ -23,8 +23,20 @@ "use strict";

__export(react_exports, {
default: () => usePartySocket
default: () => usePartySocket,
usePartySocket: () => usePartySocket,
useWebSocket: () => useWebSocket
});
module.exports = __toCommonJS(react_exports);
var import_react = require("react");
// src/ws.ts
if (!globalThis.EventTarget || !globalThis.Event) {
console.error(`
PartySocket requires a global 'EventTarget' class to be available!
You can polyfill this global by adding this to your code before any partysocket imports:
\`\`\`
import 'partysocket/event-target-polyfill';
\`\`\`
Please file an issue at https://github.com/partykit/partykit if you're still having trouble.
`);
}
var ErrorEvent = class extends Event {

@@ -59,8 +71,29 @@ message;

}
function isWebSocket(w) {
return typeof w !== "undefined" && !!w && typeof w === "function" && "CLOSING" in w && w.CLOSING === 2;
}
function cloneEvent(e) {
function cloneEventBrowser(e) {
return new e.constructor(e.type, e);
}
function cloneEventNode(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;
}
var isNode = typeof process !== "undefined" && typeof process.versions?.node !== "undefined" && typeof document === "undefined";
var cloneEvent = isNode ? cloneEventNode : cloneEventBrowser;
var DEFAULT = {

@@ -77,3 +110,4 @@ maxReconnectionDelay: 1e4,

};
var ReconnectingWebSocket = class extends EventTarget {
var didWarnAboutMissingWebSocket = false;
var ReconnectingWebSocket = class _ReconnectingWebSocket extends EventTarget {
_ws;

@@ -88,2 +122,3 @@ _retryCount = -1;

_messageQueue = [];
_debugLogger = console.log.bind(console);
_url;

@@ -100,2 +135,5 @@ _protocols;

}
if (this._options.debugLogger) {
this._debugLogger = this._options.debugLogger;
}
this._connect();

@@ -116,12 +154,12 @@ }

get CONNECTING() {
return ReconnectingWebSocket.CONNECTING;
return _ReconnectingWebSocket.CONNECTING;
}
get OPEN() {
return ReconnectingWebSocket.OPEN;
return _ReconnectingWebSocket.OPEN;
}
get CLOSING() {
return ReconnectingWebSocket.CLOSING;
return _ReconnectingWebSocket.CLOSING;
}
get CLOSED() {
return ReconnectingWebSocket.CLOSED;
return _ReconnectingWebSocket.CLOSED;
}

@@ -184,3 +222,3 @@ get binaryType() {

}
return this._options.startClosed ? ReconnectingWebSocket.CLOSED : ReconnectingWebSocket.CONNECTING;
return this._options.startClosed ? _ReconnectingWebSocket.CLOSED : _ReconnectingWebSocket.CONNECTING;
}

@@ -266,3 +304,3 @@ /**

if (this._options.debug) {
console.log.apply(console, ["RWS>", ...args]);
this._debugLogger("RWS>", ...args);
}

@@ -341,5 +379,2 @@ }

this._removeListeners();
if (!isWebSocket(WebSocket)) {
throw Error("No valid WebSocket class provided");
}
this._wait().then(

@@ -355,4 +390,22 @@ () => Promise.all([

}
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;
this._debug("connect", { url, protocols });
this._ws = protocols ? new WebSocket(url, protocols) : new WebSocket(url);
this._ws = protocols ? new WS(url, protocols) : new WS(url);
this._ws.binaryType = this._binaryType;

@@ -462,4 +515,5 @@ this._connectLock = false;

// src/index.ts
var valueIsNotNil = (keyValuePair) => keyValuePair[1] !== null && keyValuePair[1] !== void 0;
function generateUUID() {
if (crypto.randomUUID) {
if (typeof crypto !== "undefined" && crypto.randomUUID) {
return crypto.randomUUID();

@@ -481,35 +535,255 @@ }

}
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, room, protocol, query, protocols, ...socketOptions } = partySocketOptions;
const _pk = partySocketOptions.id || generateUUID();
let url = `${protocol || (host.startsWith("localhost:") || host.startsWith("127.0.0.1:") ? "ws" : "wss")}://${host}/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.setWSProperties(wsOptions);
}
_pk;
_pkurl;
name;
room;
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;
}
_pk;
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;
}
/**
* 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/react.ts
function usePartySocket(options) {
const socketRef = (0, import_react.useRef)(
new PartySocket({
...options,
startClosed: true
})
);
// 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)(() => {
socketRef.current.reconnect();
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 () => {
socketRef.current.close();
socket.removeEventListener("open", onOpen);
socket.removeEventListener("close", onClose);
socket.removeEventListener("error", onError);
socket.removeEventListener("message", onMessage);
};
}, []);
return socketRef.current;
}, [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/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
},
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
});
/*!

@@ -516,0 +790,0 @@ * Reconnecting WebSocket

@@ -28,2 +28,13 @@ "use strict";

module.exports = __toCommonJS(ws_exports);
if (!globalThis.EventTarget || !globalThis.Event) {
console.error(`
PartySocket requires a global 'EventTarget' class to be available!
You can polyfill this global by adding this to your code before any partysocket imports:
\`\`\`
import 'partysocket/event-target-polyfill';
\`\`\`
Please file an issue at https://github.com/partykit/partykit if you're still having trouble.
`);
}
var ErrorEvent = class extends Event {

@@ -58,8 +69,29 @@ message;

}
function isWebSocket(w) {
return typeof w !== "undefined" && !!w && typeof w === "function" && "CLOSING" in w && w.CLOSING === 2;
}
function cloneEvent(e) {
function cloneEventBrowser(e) {
return new e.constructor(e.type, e);
}
function cloneEventNode(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;
}
var isNode = typeof process !== "undefined" && typeof process.versions?.node !== "undefined" && typeof document === "undefined";
var cloneEvent = isNode ? cloneEventNode : cloneEventBrowser;
var DEFAULT = {

@@ -76,3 +108,4 @@ maxReconnectionDelay: 1e4,

};
var ReconnectingWebSocket = class extends EventTarget {
var didWarnAboutMissingWebSocket = false;
var ReconnectingWebSocket = class _ReconnectingWebSocket extends EventTarget {
_ws;

@@ -87,2 +120,3 @@ _retryCount = -1;

_messageQueue = [];
_debugLogger = console.log.bind(console);
_url;

@@ -99,2 +133,5 @@ _protocols;

}
if (this._options.debugLogger) {
this._debugLogger = this._options.debugLogger;
}
this._connect();

@@ -115,12 +152,12 @@ }

get CONNECTING() {
return ReconnectingWebSocket.CONNECTING;
return _ReconnectingWebSocket.CONNECTING;
}
get OPEN() {
return ReconnectingWebSocket.OPEN;
return _ReconnectingWebSocket.OPEN;
}
get CLOSING() {
return ReconnectingWebSocket.CLOSING;
return _ReconnectingWebSocket.CLOSING;
}
get CLOSED() {
return ReconnectingWebSocket.CLOSED;
return _ReconnectingWebSocket.CLOSED;
}

@@ -183,3 +220,3 @@ get binaryType() {

}
return this._options.startClosed ? ReconnectingWebSocket.CLOSED : ReconnectingWebSocket.CONNECTING;
return this._options.startClosed ? _ReconnectingWebSocket.CLOSED : _ReconnectingWebSocket.CONNECTING;
}

@@ -265,3 +302,3 @@ /**

if (this._options.debug) {
console.log.apply(console, ["RWS>", ...args]);
this._debugLogger("RWS>", ...args);
}

@@ -340,5 +377,2 @@ }

this._removeListeners();
if (!isWebSocket(WebSocket)) {
throw Error("No valid WebSocket class provided");
}
this._wait().then(

@@ -354,4 +388,22 @@ () => Promise.all([

}
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;
this._debug("connect", { url, protocols });
this._ws = protocols ? new WebSocket(url, protocols) : new WebSocket(url);
this._ws = protocols ? new WS(url, protocols) : new WS(url);
this._ws.binaryType = this._binaryType;

@@ -358,0 +410,0 @@ this._connectLock = false;

import ReconnectingWebSocket, { Options } from './ws.js';
type PartySocketOptions = Omit<Options, "WebSocket" | "constructor"> & {
type Maybe<T> = T | null | undefined;
type Params = Record<string, Maybe<string>>;
type PartySocketOptions = Omit<Options, "constructor"> & {
id?: string;
host: string;
room: string;
protocol?: string;
room?: string;
party?: 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 {
readonly partySocketOptions: PartySocketOptions;
_pk: string;
_pkurl: string;
name: 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;
/**
* 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, PartySocket as default };
export { type PartyFetchOptions, PartySocket, type PartySocketOptions, ReconnectingWebSocket as WebSocket, PartySocket as default };

54

package.json
{
"name": "partysocket",
"version": "0.0.0-a7370aa",
"description": "party hotline",
"version": "0.0.0-a7531e3",
"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",

@@ -22,2 +24,12 @@ "module": "./dist/index.mjs",

"require": "./dist/react.js"
},
"./use-ws": {
"types": "./use-ws.d.ts",
"import": "./dist/use-ws.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"
}

@@ -29,3 +41,5 @@ },

"src/react.ts",
"src/ws.ts"
"src/ws.ts",
"src/use-ws.ts",
"src/event-target-polyfill.ts"
],

@@ -38,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"

@@ -50,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,6 +0,11 @@

import PartySocket, { PartySocketOptions } from './index.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';
declare function usePartySocket(options: PartySocketOptions): PartySocket;
type UsePartySocketOptions = Omit<PartySocketOptions, "host"> & EventHandlerOptions & {
host?: string | undefined;
};
declare function usePartySocket(options: UsePartySocketOptions): PartySocket;
export { usePartySocket as default };
export { usePartySocket as default, usePartySocket };

@@ -1,35 +0,26 @@

- https://github.com/pladaria/reconnecting-websocket/pull/166 Fix: handle error if getNextUrl throws (TODO: add test for this one )
- https://github.com/pladaria/reconnecting-websocket/pull/132 feat: make protocols updatable
- https://github.com/pladaria/reconnecting-websocket/pull/141 [Fix] Socket doesn't connect again after closing while connecting
# PartySocket
(TODO: more)
_(Forked from the wonderful [reconnecting-websocket](https://github.com/joewalnes/reconnecting-websocket/) project, updated with pending PRs and bugfixes)_
- https://github.com/pladaria/reconnecting-websocket/pull/163 Support for Dynamic Protocols
- https://github.com/pladaria/reconnecting-websocket/pull/47 reconnecting and reconnectscheduled custom events
A better WebSocket that Just Works™
# Reconnecting WebSocket
## Install
[![Build Status](https://travis-ci.org/pladaria/reconnecting-websocket.svg?branch=master&v=1)](https://travis-ci.org/pladaria/reconnecting-websocket)
[![Coverage Status](https://coveralls.io/repos/github/pladaria/reconnecting-websocket/badge.svg?branch=master&v=3)](https://coveralls.io/github/pladaria/reconnecting-websocket?branch=master)
```bash
npm install partysocket
```
WebSocket that will automatically reconnect if the connection is closed.
## Features
- WebSocket API compatible (same interface, Level0 and Level2 event model)
- Reconnects when a connection drops
- Buffers messages when not connected, and sends accumulated messages when open
- Handle connection timeouts
- Allows changing server URL between reconnections
- Fully configurable
- Multi-platform (Web, ServiceWorkers, Node.js, React Native)
- Multi-platform (Web, ServiceWorkers, Node.js, React Native, Cloudflare Workers, Deno, Bun)
- Dependency free (does not depend on Window, DOM or any EventEmitter library)
- Handle connection timeouts
- Allows changing server URL between reconnections
- Buffering. Will send accumulated messages on open
- Multiple builds available (see dist folder)
- Debug mode
- Works everywhere, not just with PartyKit!
## Install
```bash
npm install --save reconnecting-websocket
```
## Usage

@@ -39,23 +30,47 @@

So this documentation should be valid:
[MDN WebSocket API](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket).
Ping me if you find any problems. Or, even better, write a test for your case and make a pull
request :)
### Simple usage
```javascript
import ReconnectingWebSocket from "reconnecting-websocket";
import { WebSocket } from "partysocket";
const rws = new ReconnectingWebSocket("ws://my.site.com");
const ws = new WebSocket("wss://my.site.com");
rws.addEventListener("open", () => {
rws.send("hello!");
ws.addEventListener("open", () => {
ws.send("hello!");
});
```
### Usage with PartyKit
```javascript
import PartySocket from "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({
host: "project.name.partykit.dev", // or localhost:1999 in dev
room: "my-room",
// add an optional id to identify the client,
// if not provided, a random id will be generated
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
```
### Update URL
The `url` parameter will be resolved before connecting, possible types:
The `url` parameter will be resolved before connecting, with possible types:

@@ -67,5 +82,9 @@ - `string`

```javascript
import ReconnectingWebSocket from "reconnecting-websocket";
import { WebSocket } from "partysocket";
const urls = ["ws://my.site.com", "ws://your.site.com", "ws://their.site.com"];
const urls = [
"wss://my.site.com",
"wss://your.site.com",
"wss://their.site.com"
];
let urlIndex = 0;

@@ -76,7 +95,7 @@

const rws = new ReconnectingWebSocket(urlProvider);
const ws = new WebSocket(urlProvider);
```
```javascript
import ReconnectingWebSocket from "reconnecting-websocket";
import { WebSocket } from "partysocket";

@@ -89,3 +108,3 @@ // async url provider

const rws = new ReconnectingWebSocket(urlProvider);
const ws = new WebSocket(urlProvider);
```

@@ -104,8 +123,9 @@

```javascript
import ReconnectingWebSocket from 'reconnecting-websocket`;
const rws = new ReconnectingWebSocket('ws://your.site.com', 'your protocol');
import { WebSocket } from "partysocket";
const ws = new WebSocket("wss://your.site.com", "your protocol");
```
```javascript
import ReconnectingWebSocket from 'reconnecting-websocket`;
import WebSocket from 'partysocket`;

@@ -118,3 +138,3 @@ const protocols = ['p1', 'p2', ['p3.1', 'p3.2']];

const rws = new ReconnectingWebSocket('ws://your.site.com', protocolsProvider);
const ws = new WebSocket('wss://your.site.com', protocolsProvider);
```

@@ -127,3 +147,3 @@

```javascript
import ReconnectingWebSocket from "reconnecting-websocket";
import { WebSocket } from "partysocket";
import WS from "ws";

@@ -134,5 +154,5 @@

connectionTimeout: 1000,
maxRetries: 10,
maxRetries: 10
};
const rws = new ReconnectingWebSocket("ws://my.site.com", [], options);
const ws = new WebSocket("wss://my.site.com", [], options);
```

@@ -215,8 +235,4 @@

## Contributing
[Read here](./CONTRIBUTING.md)
## License
MIT

@@ -7,2 +7,4 @@ type TypedEventTarget<EventMap extends object> = {

addEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void;
removeEventListener<K extends keyof EventMap>(type: K, callback: (event: EventMap[K] extends Event ? EventMap[K] : never) => EventMap[K] extends Event ? void : never, options?: boolean | AddEventListenerOptions): void;
removeEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void;
}

@@ -35,2 +37,3 @@

type Options = {
WebSocket?: any;
maxReconnectionDelay?: number;

@@ -45,2 +48,3 @@ minReconnectionDelay?: number;

debug?: boolean;
debugLogger?: (...args: any[]) => void;
};

@@ -61,5 +65,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);

@@ -159,2 +164,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