🚨 Active Supply Chain Attack:node-ipc Package Compromised.Learn More
Socket
Book a DemoSign in
Socket

@fuman/node

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fuman/node - npm Package Compare versions

Comparing version
0.0.10
to
0.0.11
+53
net/websocket.d.cts
import { IListener, IWebSocketServerConnection, IWebSocketServerConnectionFramed, TcpEndpoint } from '@fuman/net';
import { IncomingMessage } from 'node:http';
import { Duplex } from 'node:stream';
import { ServerOptions, WebSocket, WebSocketServer } from 'ws';
import { ConditionVariable } from '@fuman/utils';
declare abstract class NodeWebSocketConnectionBase {
#private;
readonly socket: WebSocket;
readonly request: IncomingMessage;
protected _error: Error | null;
protected _cv: ConditionVariable;
abstract onMessage(data: Buffer, isBinary: boolean): void;
constructor(socket: WebSocket, request: IncomingMessage);
get headers(): Headers;
get url(): string;
get localAddress(): null;
get remoteAddress(): TcpEndpoint | null;
close(): void;
}
declare class NodeWebSocketConnection extends NodeWebSocketConnectionBase implements IWebSocketServerConnection {
#private;
onMessage(data: Buffer): void;
read(into: Uint8Array): Promise<number>;
write(bytes: Uint8Array): Promise<void>;
}
declare class NodeWebSocketConnectionFramed extends NodeWebSocketConnectionBase implements IWebSocketServerConnectionFramed {
#private;
onMessage(data: Buffer, isBinary: boolean): void;
readFrame(): Promise<Uint8Array | string>;
writeFrame(data: Uint8Array | string): Promise<void>;
}
declare abstract class NodeWebSocketServerBase<Connection> {
#private;
/** Underlying server */
readonly server: WebSocketServer;
abstract makeConnection(socket: WebSocket, request: IncomingMessage): Connection;
constructor(
/** Underlying server */
server: WebSocketServer);
get address(): TcpEndpoint | null;
close(): void;
accept(): Promise<Connection>;
handleUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer): void;
}
export declare class NodeWebSocketServer extends NodeWebSocketServerBase<NodeWebSocketConnection> implements IListener<TcpEndpoint, IWebSocketServerConnection> {
makeConnection(socket: WebSocket, request: IncomingMessage): NodeWebSocketConnection;
}
export declare class NodeWebSocketServerFramed extends NodeWebSocketServerBase<NodeWebSocketConnectionFramed> {
makeConnection(socket: WebSocket, request: IncomingMessage): NodeWebSocketConnectionFramed;
}
export declare function listenWs(options: ServerOptions): NodeWebSocketServer;
export declare function listenWsFramed(options: ServerOptions): NodeWebSocketServerFramed;
export {};
import { IListener, IWebSocketServerConnection, IWebSocketServerConnectionFramed, TcpEndpoint } from '@fuman/net';
import { IncomingMessage } from 'node:http';
import { Duplex } from 'node:stream';
import { ServerOptions, WebSocket, WebSocketServer } from 'ws';
import { ConditionVariable } from '@fuman/utils';
declare abstract class NodeWebSocketConnectionBase {
#private;
readonly socket: WebSocket;
readonly request: IncomingMessage;
protected _error: Error | null;
protected _cv: ConditionVariable;
abstract onMessage(data: Buffer, isBinary: boolean): void;
constructor(socket: WebSocket, request: IncomingMessage);
get headers(): Headers;
get url(): string;
get localAddress(): null;
get remoteAddress(): TcpEndpoint | null;
close(): void;
}
declare class NodeWebSocketConnection extends NodeWebSocketConnectionBase implements IWebSocketServerConnection {
#private;
onMessage(data: Buffer): void;
read(into: Uint8Array): Promise<number>;
write(bytes: Uint8Array): Promise<void>;
}
declare class NodeWebSocketConnectionFramed extends NodeWebSocketConnectionBase implements IWebSocketServerConnectionFramed {
#private;
onMessage(data: Buffer, isBinary: boolean): void;
readFrame(): Promise<Uint8Array | string>;
writeFrame(data: Uint8Array | string): Promise<void>;
}
declare abstract class NodeWebSocketServerBase<Connection> {
#private;
/** Underlying server */
readonly server: WebSocketServer;
abstract makeConnection(socket: WebSocket, request: IncomingMessage): Connection;
constructor(
/** Underlying server */
server: WebSocketServer);
get address(): TcpEndpoint | null;
close(): void;
accept(): Promise<Connection>;
handleUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer): void;
}
export declare class NodeWebSocketServer extends NodeWebSocketServerBase<NodeWebSocketConnection> implements IListener<TcpEndpoint, IWebSocketServerConnection> {
makeConnection(socket: WebSocket, request: IncomingMessage): NodeWebSocketConnection;
}
export declare class NodeWebSocketServerFramed extends NodeWebSocketServerBase<NodeWebSocketConnectionFramed> {
makeConnection(socket: WebSocket, request: IncomingMessage): NodeWebSocketConnectionFramed;
}
export declare function listenWs(options: ServerOptions): NodeWebSocketServer;
export declare function listenWsFramed(options: ServerOptions): NodeWebSocketServerFramed;
export {};
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const io = require("@fuman/io");
const net = require("@fuman/net");
const utils = require("@fuman/utils");
const ws = require("ws");
class NodeWebSocketConnectionBase {
constructor(socket, request) {
this.socket = socket;
this.request = request;
socket.binaryType = "nodebuffer";
socket.on("message", (data, isBinary) => {
const data_ = data;
this.onMessage(data_, isBinary);
this._cv.notify();
});
socket.on("close", (code, reason) => {
if (this._error) return;
this._error = new net.WebSocketConnectionClosedError(code, reason.toString("utf-8"));
this._cv.notify();
});
socket.on("error", (error) => {
if (this._error) return;
this._error = error;
this._cv.notify();
});
}
_error = null;
_cv = new utils.ConditionVariable();
#headers;
get headers() {
if (!this.#headers) {
const headers = new Headers();
for (const [key, value] of Object.entries(this.request.headers)) {
if (value == null) continue;
if (Array.isArray(value)) {
for (const v of value) {
headers.append(key, v);
}
} else {
headers.set(key, value);
}
}
this.#headers = headers;
}
return this.#headers;
}
get url() {
return this.request.url ?? this.socket.url;
}
get localAddress() {
return null;
}
get remoteAddress() {
if (this.request.socket.remoteAddress == null) return null;
return {
address: this.request.socket.remoteAddress,
port: this.request.socket.remotePort ?? 0
};
}
close() {
this.socket.close();
this._error = new net.ConnectionClosedError();
this._cv.notify();
}
}
class NodeWebSocketConnection extends NodeWebSocketConnectionBase {
#buffer = io.Bytes.alloc(0);
onMessage(data) {
this.#buffer.writeSync(data.length).set(data);
this.#buffer.disposeWriteSync();
}
async read(into) {
if (this.#buffer.available > 0) {
const size2 = Math.min(this.#buffer.available, into.length);
into.set(this.#buffer.readSync(size2));
this.#buffer.reclaim();
return size2;
}
if (this._error !== null) throw this._error;
await this._cv.wait();
if (this._error !== null) throw this._error;
const size = Math.min(this.#buffer.available, into.length);
into.set(this.#buffer.readSync(size));
this.#buffer.reclaim();
return size;
}
async write(bytes) {
if (this._error) throw this._error;
if (!bytes.length) return;
this.socket.send(bytes);
}
}
class NodeWebSocketConnectionFramed extends NodeWebSocketConnectionBase {
#buffer = new utils.Deque();
onMessage(data, isBinary) {
if (isBinary) {
this.#buffer.pushBack(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));
} else {
this.#buffer.pushBack(data.toString("utf-8"));
}
}
async readFrame() {
if (!this.#buffer.isEmpty()) {
return this.#buffer.popFront();
}
if (this._error !== null) throw this._error;
await this._cv.wait();
if (this._error !== null) throw this._error;
return this.#buffer.popFront();
}
async writeFrame(data) {
if (this._error) throw this._error;
this.socket.send(data);
}
}
class NodeWebSocketServerBase {
constructor(server) {
this.server = server;
server.on("connection", (socket, request) => {
if (!this.#waiter) {
socket.close();
return;
}
this.#waiter.resolve(this.makeConnection(socket, request));
this.#waiter = void 0;
});
server.on("error", (error) => {
this.#waiter?.reject(error);
});
server.on("close", () => {
this.#waiter?.reject(new net.ListenerClosedError());
});
}
#closed = false;
#waiter;
get address() {
const addr = this.server.address();
if (addr == null) return null;
if (typeof addr === "string") {
const [host, port] = addr.split(":");
return {
address: host,
port: Number.parseInt(port)
};
}
return {
address: addr.address,
port: addr.port
};
}
close() {
this.server.close();
}
async accept() {
if (this.#closed) {
throw new net.ListenerClosedError();
}
this.#waiter = new utils.Deferred();
const connection = await this.#waiter.promise;
this.#waiter = void 0;
return connection;
}
handleUpgrade(req, socket, head) {
if (!this.#waiter) {
socket.destroy();
return;
}
const waiter = this.#waiter;
this.#waiter = void 0;
this.server.handleUpgrade(req, socket, head, (socket2, req2) => {
waiter.resolve(this.makeConnection(socket2, req2));
});
}
}
class NodeWebSocketServer extends NodeWebSocketServerBase {
makeConnection(socket, request) {
return new NodeWebSocketConnection(socket, request);
}
}
class NodeWebSocketServerFramed extends NodeWebSocketServerBase {
makeConnection(socket, request) {
return new NodeWebSocketConnectionFramed(socket, request);
}
}
function listenWs(options) {
return new NodeWebSocketServer(new ws.WebSocketServer(options));
}
function listenWsFramed(options) {
return new NodeWebSocketServerFramed(new ws.WebSocketServer(options));
}
exports.NodeWebSocketServer = NodeWebSocketServer;
exports.NodeWebSocketServerFramed = NodeWebSocketServerFramed;
exports.listenWs = listenWs;
exports.listenWsFramed = listenWsFramed;
export * from "./net/websocket.js"
export * from "./net/websocket.js"
import { Bytes } from "@fuman/io";
import { ListenerClosedError, WebSocketConnectionClosedError, ConnectionClosedError } from "@fuman/net";
import { Deque, Deferred, ConditionVariable } from "@fuman/utils";
import { WebSocketServer } from "ws";
class NodeWebSocketConnectionBase {
constructor(socket, request) {
this.socket = socket;
this.request = request;
socket.binaryType = "nodebuffer";
socket.on("message", (data, isBinary) => {
const data_ = data;
this.onMessage(data_, isBinary);
this._cv.notify();
});
socket.on("close", (code, reason) => {
if (this._error) return;
this._error = new WebSocketConnectionClosedError(code, reason.toString("utf-8"));
this._cv.notify();
});
socket.on("error", (error) => {
if (this._error) return;
this._error = error;
this._cv.notify();
});
}
_error = null;
_cv = new ConditionVariable();
#headers;
get headers() {
if (!this.#headers) {
const headers = new Headers();
for (const [key, value] of Object.entries(this.request.headers)) {
if (value == null) continue;
if (Array.isArray(value)) {
for (const v of value) {
headers.append(key, v);
}
} else {
headers.set(key, value);
}
}
this.#headers = headers;
}
return this.#headers;
}
get url() {
return this.request.url ?? this.socket.url;
}
get localAddress() {
return null;
}
get remoteAddress() {
if (this.request.socket.remoteAddress == null) return null;
return {
address: this.request.socket.remoteAddress,
port: this.request.socket.remotePort ?? 0
};
}
close() {
this.socket.close();
this._error = new ConnectionClosedError();
this._cv.notify();
}
}
class NodeWebSocketConnection extends NodeWebSocketConnectionBase {
#buffer = Bytes.alloc(0);
onMessage(data) {
this.#buffer.writeSync(data.length).set(data);
this.#buffer.disposeWriteSync();
}
async read(into) {
if (this.#buffer.available > 0) {
const size2 = Math.min(this.#buffer.available, into.length);
into.set(this.#buffer.readSync(size2));
this.#buffer.reclaim();
return size2;
}
if (this._error !== null) throw this._error;
await this._cv.wait();
if (this._error !== null) throw this._error;
const size = Math.min(this.#buffer.available, into.length);
into.set(this.#buffer.readSync(size));
this.#buffer.reclaim();
return size;
}
async write(bytes) {
if (this._error) throw this._error;
if (!bytes.length) return;
this.socket.send(bytes);
}
}
class NodeWebSocketConnectionFramed extends NodeWebSocketConnectionBase {
#buffer = new Deque();
onMessage(data, isBinary) {
if (isBinary) {
this.#buffer.pushBack(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));
} else {
this.#buffer.pushBack(data.toString("utf-8"));
}
}
async readFrame() {
if (!this.#buffer.isEmpty()) {
return this.#buffer.popFront();
}
if (this._error !== null) throw this._error;
await this._cv.wait();
if (this._error !== null) throw this._error;
return this.#buffer.popFront();
}
async writeFrame(data) {
if (this._error) throw this._error;
this.socket.send(data);
}
}
class NodeWebSocketServerBase {
constructor(server) {
this.server = server;
server.on("connection", (socket, request) => {
if (!this.#waiter) {
socket.close();
return;
}
this.#waiter.resolve(this.makeConnection(socket, request));
this.#waiter = void 0;
});
server.on("error", (error) => {
this.#waiter?.reject(error);
});
server.on("close", () => {
this.#waiter?.reject(new ListenerClosedError());
});
}
#closed = false;
#waiter;
get address() {
const addr = this.server.address();
if (addr == null) return null;
if (typeof addr === "string") {
const [host, port] = addr.split(":");
return {
address: host,
port: Number.parseInt(port)
};
}
return {
address: addr.address,
port: addr.port
};
}
close() {
this.server.close();
}
async accept() {
if (this.#closed) {
throw new ListenerClosedError();
}
this.#waiter = new Deferred();
const connection = await this.#waiter.promise;
this.#waiter = void 0;
return connection;
}
handleUpgrade(req, socket, head) {
if (!this.#waiter) {
socket.destroy();
return;
}
const waiter = this.#waiter;
this.#waiter = void 0;
this.server.handleUpgrade(req, socket, head, (socket2, req2) => {
waiter.resolve(this.makeConnection(socket2, req2));
});
}
}
class NodeWebSocketServer extends NodeWebSocketServerBase {
makeConnection(socket, request) {
return new NodeWebSocketConnection(socket, request);
}
}
class NodeWebSocketServerFramed extends NodeWebSocketServerBase {
makeConnection(socket, request) {
return new NodeWebSocketConnectionFramed(socket, request);
}
}
function listenWs(options) {
return new NodeWebSocketServer(new WebSocketServer(options));
}
function listenWsFramed(options) {
return new NodeWebSocketServerFramed(new WebSocketServer(options));
}
export {
NodeWebSocketServer,
NodeWebSocketServerFramed,
listenWs,
listenWsFramed
};
+22
-4
{
"name": "@fuman/node",
"type": "module",
"version": "0.0.10",
"version": "0.0.11",
"description": "node-specific utilities",

@@ -9,6 +9,9 @@ "license": "MIT",

"dependencies": {
"@fuman/io": "^0.0.10",
"@fuman/net": "^0.0.10",
"@fuman/utils": "^0.0.10"
"@fuman/io": "^0.0.11",
"@fuman/net": "^0.0.11",
"@fuman/utils": "^0.0.11"
},
"peerDependencies": {
"ws": "^8.18.1"
},
"exports": {

@@ -24,5 +27,20 @@ ".": {

}
},
"./websocket": {
"import": {
"types": "./websocket.d.ts",
"default": "./websocket.js"
},
"require": {
"types": "./websocket.d.cts",
"default": "./websocket.cjs"
}
}
},
"sideEffects": false,
"peerDependenciesMeta": {
"ws": {
"optional": true
}
},
"author": "",

@@ -29,0 +47,0 @@ "repository": {