Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@mercuryworkshop/bare-mux

Package Overview
Dependencies
Maintainers
0
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mercuryworkshop/bare-mux - npm Package Compare versions

Comparing version 2.0.6 to 2.0.7

dist/websocket.d.ts

36

dist/client.d.ts

@@ -7,38 +7,2 @@ import { BareHeaders, BareTransport } from './baretypes';

};
export declare namespace BareWebSocket {
type GetReadyStateCallback = () => number;
type GetSendErrorCallback = () => Error | undefined;
type GetProtocolCallback = () => string;
type HeadersType = BareHeaders | Headers | undefined;
type HeadersProvider = BareHeaders | (() => BareHeaders | Promise<BareHeaders>);
interface Options {
/**
* A provider of request headers to pass to the remote.
* Usually one of `User-Agent`, `Origin`, and `Cookie`
* Can be just the headers object or an synchronous/asynchronous function that returns the headers object
*/
headers?: BareWebSocket.HeadersProvider;
/**
* A hook executed by this function with helper arguments for hooking the readyState property. If a hook isn't provided, bare-client will hook the property on the instance. Hooking it on an instance basis is good for small projects, but ideally the class should be hooked by the user of bare-client.
*/
readyStateHook?: ((socket: WebSocket, getReadyState: BareWebSocket.GetReadyStateCallback) => void) | undefined;
/**
* A hook executed by this function with helper arguments for determining if the send function should throw an error. If a hook isn't provided, bare-client will hook the function on the instance.
*/
sendErrorHook?: ((socket: WebSocket, getSendError: BareWebSocket.GetSendErrorCallback) => void) | undefined;
/**
* A hook executed by this function with the URL. If a hook isn't provided, bare-client will hook the URL.
*/
urlHook?: ((socket: WebSocket, url: URL) => void) | undefined;
/**
* A hook executed by this function with a helper for getting the current fake protocol. If a hook isn't provided, bare-client will hook the protocol.
*/
protocolHook?: ((socket: WebSocket, getProtocol: BareWebSocket.GetProtocolCallback) => void) | undefined;
/**
* A callback executed by this function with an array of cookies. This is called once the metadata from the server is received.
*/
setCookiesCallback?: ((setCookies: string[]) => void) | undefined;
webSocketImpl?: WebSocket;
}
}
/**

@@ -45,0 +9,0 @@ * A Response with additional properties.

244

dist/index.js

@@ -182,2 +182,114 @@ (function (global, factory) {

class BareWebSocket extends EventTarget {
constructor(remote, protocols = [], worker, requestHeaders, arrayBufferImpl) {
super();
this.protocols = [];
this.readyState = WebSocketFields.CONNECTING;
this.binaryType = "blob";
//legacy event handlers
this.onopen = (event) => { };
this.onerror = (event) => { };
this.onmessage = (event) => { };
this.onclose = (event) => { };
this.url = remote.toString();
this.protocols = protocols;
const onopen = (protocol) => {
this.readyState = WebSocketFields.OPEN;
this.protocols = protocol;
this.meta = {
headers: {
"sec-websocket-protocol": protocol,
}
};
const event = new Event("open");
this.dispatchEvent(event);
this.onopen(event);
};
const onmessage = async (payload) => {
if ("byteLength" in payload) {
if (this.binaryType === "blob") {
payload = new Blob([payload]);
}
else {
Object.setPrototypeOf(payload, arrayBufferImpl);
}
}
else if ("arrayBuffer" in payload) {
if (this.binaryType === "arraybuffer") {
payload = await payload.arrayBuffer();
Object.setPrototypeOf(payload, arrayBufferImpl);
}
}
const event = new MessageEvent("message", { data: payload });
this.dispatchEvent(event);
this.onmessage(event);
};
const onclose = (code, reason) => {
this.readyState = WebSocketFields.CLOSED;
const event = new CloseEvent("close", { code, reason });
this.dispatchEvent(event);
this.onclose(event);
};
const onerror = () => {
this.readyState = WebSocketFields.CLOSED;
const event = new Event("error");
this.dispatchEvent(event);
this.onerror(event);
};
this.channel = new MessageChannel();
this.channel.port1.onmessage = event => {
if (event.data.type === "open") {
onopen(event.data.args[0]);
}
else if (event.data.type === "message") {
onmessage(event.data.args[0]);
}
else if (event.data.type === "close") {
onclose(event.data.args[0], event.data.args[1]);
}
else if (event.data.type === "error") {
onerror( /* event.data.args[0] */);
}
};
worker.sendMessage({
type: "websocket",
websocket: {
url: remote.toString(),
origin: origin,
//@ts-expect-error
protocols: protocols,
requestHeaders: requestHeaders,
channel: this.channel.port2,
},
}, [this.channel.port2]);
}
send(...args) {
if (this.readyState === WebSocketFields.CONNECTING) {
throw new DOMException("Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.");
}
let data = args[0];
if (data.buffer)
data = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
this.channel.port1.postMessage({ type: "data", data: data }, data instanceof ArrayBuffer ? [data] : []);
}
close(code, reason) {
this.readyState = WebSocketFields.CLOSING;
this.channel.port1.postMessage({ type: "close", closeCode: code, closeReason: reason });
}
get bufferedAmount() {
return 0;
}
get protocol() {
if (Array.isArray(this.protocols)) {
return this.protocols[0] || "";
}
else {
return this.protocols || "";
}
}
get extensions() {
return "";
}
}
function sendError(port, err, name) {

@@ -327,23 +439,3 @@ console.error(`error while processing '${name}': `, err);

throw new DOMException(`Failed to construct 'WebSocket': The subprotocol '${proto}' is invalid.`);
let wsImpl = (webSocketImpl || WebSocket);
const socket = new wsImpl("ws://127.0.0.1:1", protocols);
let fakeProtocol = '';
let fakeReadyState = WebSocketFields.CONNECTING;
let initialErrorHappened = false;
socket.addEventListener("error", (e) => {
if (!initialErrorHappened) {
fakeReadyState = WebSocket.CONNECTING;
e.stopImmediatePropagation();
initialErrorHappened = true;
}
});
let initialCloseHappened = false;
socket.addEventListener("close", (e) => {
if (!initialCloseHappened) {
e.stopImmediatePropagation();
initialCloseHappened = true;
}
});
// TODO socket onerror will be broken
arrayBufferImpl = arrayBufferImpl || wsImpl.constructor.constructor("return ArrayBuffer")().prototype;
arrayBufferImpl = arrayBufferImpl || (webSocketImpl || WebSocket).constructor.constructor("return ArrayBuffer")().prototype;
requestHeaders = requestHeaders || {};

@@ -357,111 +449,3 @@ requestHeaders['Host'] = (new URL(remote)).host;

requestHeaders['Connection'] = 'Upgrade';
const onopen = (protocol) => {
fakeReadyState = WebSocketFields.OPEN;
fakeProtocol = protocol;
socket.meta = {
headers: {
"sec-websocket-protocol": protocol,
}
}; // what the fuck is a meta
socket.dispatchEvent(new Event("open"));
};
const onmessage = async (payload) => {
if (typeof payload === "string") {
socket.dispatchEvent(new MessageEvent("message", { data: payload }));
}
else if ("byteLength" in payload) {
if (socket.binaryType === "blob") {
payload = new Blob([payload]);
}
else {
Object.setPrototypeOf(payload, arrayBufferImpl);
}
socket.dispatchEvent(new MessageEvent("message", { data: payload }));
}
else if ("arrayBuffer" in payload) {
if (socket.binaryType === "arraybuffer") {
payload = await payload.arrayBuffer();
Object.setPrototypeOf(payload, arrayBufferImpl);
}
socket.dispatchEvent(new MessageEvent("message", { data: payload }));
}
};
const onclose = (code, reason) => {
fakeReadyState = WebSocketFields.CLOSED;
socket.dispatchEvent(new CloseEvent("close", { code, reason }));
};
const onerror = () => {
fakeReadyState = WebSocketFields.CLOSED;
socket.dispatchEvent(new Event("error"));
};
const channel = new MessageChannel();
channel.port1.onmessage = event => {
if (event.data.type === "open") {
onopen(event.data.args[0]);
}
else if (event.data.type === "message") {
onmessage(event.data.args[0]);
}
else if (event.data.type === "close") {
onclose(event.data.args[0], event.data.args[1]);
}
else if (event.data.type === "error") {
onerror( /* event.data.args[0] */);
}
};
this.worker.sendMessage({
type: "websocket",
websocket: {
url: remote.toString(),
origin: origin,
protocols: protocols,
requestHeaders: requestHeaders,
channel: channel.port2,
},
}, [channel.port2]);
// protocol is always an empty before connecting
// updated when we receive the metadata
// this value doesn't change when it's CLOSING or CLOSED etc
const getReadyState = () => fakeReadyState;
// we have to hook .readyState ourselves
Object.defineProperty(socket, 'readyState', {
get: getReadyState,
configurable: true,
enumerable: true,
});
/**
* @returns The error that should be thrown if send() were to be called on this socket according to the fake readyState value
*/
const getSendError = () => {
const readyState = getReadyState();
if (readyState === WebSocketFields.CONNECTING)
return new DOMException("Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.");
};
// we have to hook .send ourselves
// use ...args to avoid giving the number of args a quantity
// no arguments will trip the following error: TypeError: Failed to execute 'send' on 'WebSocket': 1 argument required, but only 0 present.
socket.send = function (...args) {
const error = getSendError();
if (error)
throw error;
let data = args[0];
// @ts-expect-error
if (data.buffer)
data = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
channel.port1.postMessage({ type: "data", data: data }, data instanceof ArrayBuffer ? [data] : []);
};
socket.close = function (code, reason) {
channel.port1.postMessage({ type: "close", closeCode: code, closeReason: reason });
};
Object.defineProperty(socket, 'url', {
get: () => remote.toString(),
configurable: true,
enumerable: true,
});
const getProtocol = () => fakeProtocol;
Object.defineProperty(socket, 'protocol', {
get: getProtocol,
configurable: true,
enumerable: true,
});
const socket = new BareWebSocket(remote, protocols, this.worker, requestHeaders, arrayBufferImpl);
return socket;

@@ -468,0 +452,0 @@ }

{
"name": "@mercuryworkshop/bare-mux",
"version": "2.0.6",
"version": "2.0.7",
"description": "",

@@ -5,0 +5,0 @@ "type": "module",

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc