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
957
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-f508655

dist/chunk-BZZROSLB.mjs

247

dist/index.js

@@ -21,10 +21,22 @@ "use strict";

// src/index.ts
var src_exports = {};
__export(src_exports, {
WebSocket: () => WebSocket2,
var index_exports = {};
__export(index_exports, {
PartySocket: () => PartySocket,
WebSocket: () => ReconnectingWebSocket,
default: () => PartySocket
});
module.exports = __toCommonJS(src_exports);
module.exports = __toCommonJS(index_exports);
// 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,5 +71,29 @@ message;

}
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 = {

@@ -74,23 +110,3 @@ maxReconnectionDelay: 1e4,

};
if (!globalThis.EventTarget) {
console.error(`
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:
\`\`\`
npm install event-target-shim
\`\`\`
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.
`);
}
var didWarnAboutMissingWebSocket = false;
var ReconnectingWebSocket = class _ReconnectingWebSocket extends EventTarget {

@@ -106,2 +122,3 @@ _ws;

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

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

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

@@ -282,3 +302,3 @@ }

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

@@ -308,4 +328,3 @@ }

_getNextProtocols(protocolsProvider) {
if (!protocolsProvider)
return Promise.resolve(null);
if (!protocolsProvider) return Promise.resolve(null);
if (typeof protocolsProvider === "string" || Array.isArray(protocolsProvider)) {

@@ -316,4 +335,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)) {

@@ -369,4 +387,22 @@ 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;
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;

@@ -395,3 +431,5 @@ this._connectLock = false;

try {
this._ws.close(code, reason);
if (this._ws.readyState === this.OPEN) {
this._ws.close(code, reason);
}
this._handleClose(new Events.CloseEvent(code, reason, this));

@@ -477,2 +515,3 @@ } catch (error) {

// src/index.ts
var valueIsNotNil = (keyValuePair) => keyValuePair[1] !== null && keyValuePair[1] !== void 0;
function generateUUID() {

@@ -496,33 +535,135 @@ if (typeof crypto !== "undefined" && crypto.randomUUID) {

}
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 && 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}/${basePath || `${prefix || "parties"}/${name}/${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.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);
}
};
var WebSocket2 = ReconnectingWebSocket;
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

@@ -529,0 +670,0 @@ });

@@ -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,5 +71,29 @@ message;

}
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 = {

@@ -74,23 +110,3 @@ maxReconnectionDelay: 1e4,

};
if (!globalThis.EventTarget) {
console.error(`
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:
\`\`\`
npm install event-target-shim
\`\`\`
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.
`);
}
var didWarnAboutMissingWebSocket = false;
var ReconnectingWebSocket = class _ReconnectingWebSocket extends EventTarget {

@@ -106,2 +122,3 @@ _ws;

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

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

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

@@ -282,3 +302,3 @@ }

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

@@ -308,4 +328,3 @@ }

_getNextProtocols(protocolsProvider) {
if (!protocolsProvider)
return Promise.resolve(null);
if (!protocolsProvider) return Promise.resolve(null);
if (typeof protocolsProvider === "string" || Array.isArray(protocolsProvider)) {

@@ -316,4 +335,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)) {

@@ -369,4 +387,22 @@ 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;
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;

@@ -395,3 +431,5 @@ this._connectLock = false;

try {
this._ws.close(code, reason);
if (this._ws.readyState === this.OPEN) {
this._ws.close(code, reason);
}
this._handleClose(new Events.CloseEvent(code, reason, this));

@@ -477,2 +515,3 @@ } catch (error) {

// src/index.ts
var valueIsNotNil = (keyValuePair) => keyValuePair[1] !== null && keyValuePair[1] !== void 0;
function generateUUID() {

@@ -496,77 +535,259 @@ if (typeof crypto !== "undefined" && crypto.randomUUID) {

}
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 && 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}/${basePath || `${prefix || "parties"}/${name}/${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.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 { onOpen, onMessage, onClose, onError, ...partySocketOptions } = options;
const socketRef = (0, import_react.useRef)(
new PartySocket({
...partySocketOptions,
startClosed: true
// only connect on mount
})
);
// 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 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 (options.startClosed !== true) {
}, [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
},
// 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,
options2.basePath,
options2.prefix,
...getOptionsThatShouldCauseRestartWhenChanged(options2)
])
});
useAttachWebSocketEventHandlers(socket, options);
return socket;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
usePartySocket,
useWebSocket
});
/*!

@@ -573,0 +794,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,5 +69,29 @@ message;

}
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 = {

@@ -73,23 +108,3 @@ maxReconnectionDelay: 1e4,

};
if (!globalThis.EventTarget) {
console.error(`
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:
\`\`\`
npm install event-target-shim
\`\`\`
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.
`);
}
var didWarnAboutMissingWebSocket = false;
var ReconnectingWebSocket = class _ReconnectingWebSocket extends EventTarget {

@@ -105,2 +120,3 @@ _ws;

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

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

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

@@ -281,3 +300,3 @@ }

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

@@ -307,4 +326,3 @@ }

_getNextProtocols(protocolsProvider) {
if (!protocolsProvider)
return Promise.resolve(null);
if (!protocolsProvider) return Promise.resolve(null);
if (typeof protocolsProvider === "string" || Array.isArray(protocolsProvider)) {

@@ -315,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)) {

@@ -368,4 +385,22 @@ 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;
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;

@@ -394,3 +429,5 @@ this._connectLock = false;

try {
this._ws.close(code, reason);
if (this._ws.readyState === this.OPEN) {
this._ws.close(code, reason);
}
this._handleClose(new Events.CloseEvent(code, reason, this));

@@ -397,0 +434,0 @@ } catch (error) {

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;
room?: string;
party?: string;
protocol?: string;
basePath?: string;
prefix?: 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;
basePath?: string;
prefix?: 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>;
}
declare const WebSocket: typeof ReconnectingWebSocket;
export { PartySocketOptions, WebSocket, PartySocket as default };
export { type PartyFetchOptions, PartySocket, type PartySocketOptions, ReconnectingWebSocket as WebSocket, PartySocket as default };
{
"name": "partysocket",
"version": "0.0.0-f4add35",
"description": "party hotline",
"version": "0.0.0-f508655",
"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,12 +0,11 @@

import PartySocket, { PartySocketOptions } from './index.js';
import { PartySocketOptions, PartySocket } 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 };

@@ -5,3 +5,3 @@ # PartySocket

A better WebSocket that Just Works™
A better WebSocket that Just Works™

@@ -11,3 +11,3 @@ ## Install

```bash
npm install partysocket@beta
npm install partysocket
```

@@ -19,3 +19,3 @@

- Reconnects when a connection drops
- Buffers messages when not connected, and sends accumulated messages when open
- Buffers messages when not connected, and sends accumulated messages when open
- Handle connection timeouts

@@ -40,3 +40,3 @@ - Allows changing server URL between reconnections

const ws = new WebSocket("ws://my.site.com");
const ws = new WebSocket("wss://my.site.com");

@@ -53,2 +53,5 @@ ws.addEventListener("open", () => {

// optional: only needed if creating using inside node.js. Run `npm install ws`, and then add:
// import WS from "ws";
const ws = new PartySocket({

@@ -59,4 +62,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
```

@@ -66,3 +80,3 @@

The `url` parameter will be resolved before connecting, possible types:
The `url` parameter will be resolved before connecting, with possible types:

@@ -76,3 +90,7 @@ - `string`

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;

@@ -110,3 +128,4 @@

import { WebSocket } from "partysocket";
const ws = new WebSocket("ws://your.site.com", "your protocol");
const ws = new WebSocket("wss://your.site.com", "your protocol");
```

@@ -123,3 +142,3 @@

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

@@ -138,5 +157,5 @@

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

@@ -143,0 +162,0 @@

@@ -36,2 +36,3 @@ type TypedEventTarget<EventMap extends object> = {

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

@@ -46,2 +47,3 @@ minReconnectionDelay?: number;

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

@@ -62,5 +64,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 +163,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