FRE-600: Fix code review blockers

- Consolidated duplicate UndoManagers to single instance
- Fixed connection promise to only resolve on 'connected' status
- Fixed WebSocketProvider import (WebsocketProvider)
- Added proper doc.destroy() cleanup
- Renamed isPresenceInitialized property to avoid conflict

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-04-25 00:08:01 -04:00
parent 65b552bb08
commit 7c684a42cc
48450 changed files with 5679671 additions and 383 deletions

10
node_modules/rpc-websockets/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,10 @@
Copyright (c) Elpheria j.d.o.o.
rpc-websockets is an Open Source project licensed under the terms of
the LGPLv3 license. Please see <https://www.gnu.org/licenses/lgpl-3.0.html>
for license text.
rpc-websockets Pro has a commercial-friendly license allowing private forks
and modifications of rpc-websockets.
Please see https://www.elpheria.com/products/rpc-websockets-pro.html
or email us at info@elpheria.com for more detail.

153
node_modules/rpc-websockets/README.md generated vendored Normal file
View File

@@ -0,0 +1,153 @@
<div align="center">
<a href="https://github.com/elpheria/rpc-websockets">
<img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/logo.png">
</a>
<br>
<p>
WebSockets for <a href="http://nodejs.org">Node.js</a> and <a href="https://en.wikipedia.org/wiki/JavaScript">JavaScript</a>/<a href="https://en.wikipedia.org/wiki/TypeScript">TypeScript</a> with <a href="https://www.jsonrpc.org/specification">JSON RPC 2.0</a> support on top. </p>
<a href="https://www.npmjs.com/package/rpc-websockets">
<img src="https://img.shields.io/npm/v/rpc-websockets.svg">
</a>
<a href="https://travis-ci.org/elpheria/rpc-websockets">
<img src="https://travis-ci.org/elpheria/rpc-websockets.svg?branch=master">
</a>
<a href="https://www.npmjs.com/package/rpc-websockets">
<img src="https://img.shields.io/npm/dm/rpc-websockets.svg?maxAge=2592000">
</a>
<br><br><br>
</div>
## About
The **rpc-websockets** library enables developers to easily implement their business logic that includes messaging between users, machines or any devices. It provides a possibility to send and receive JSON data through the WebSocket communication protocol in order to support two-way notification push, running RPC methods and firing any types of event signalling. Only clients can call RPC methods and not vice versa at the moment. Both frontend (HTML/JS-based) and backend (Node.js-based) development environments are supported.
**rpc-websockets** is built on Node.js and supports both LTS and Current versions.
Use the free OSS edition in order to implement and manage your own WebSocket server instances, or subscribe for our [Pro plan](#pro-features) and have us manage your instances and provide you with management of your methods, events and notifications on an easy-to-use Web Management portal.
## Quick start
Install our OSS library in your project:
```
npm install rpc-websockets
```
Write your source code using `rpc-websockets`:
```js
var WebSocket = require('rpc-websockets').Client
var WebSocketServer = require('rpc-websockets').Server
// instantiate Server and start listening for requests
var server = new WebSocketServer({
port: 8080,
host: 'localhost'
})
// register an RPC method
server.register('sum', function(params) {
return params[0] + params[1]
})
// ...and maybe a protected one also
server.register('account', function() {
return ['confi1', 'confi2']
}).protected()
// create an event
server.event('feedUpdated')
// get events
console.log(server.eventList())
// emit an event to subscribers
server.emit('feedUpdated')
// close the server
server.close()
// instantiate Client and connect to an RPC server
var ws = new WebSocket('ws://localhost:8080')
ws.on('open', function() {
// call an RPC method with parameters
ws.call('sum', [5, 3]).then(function(result) {
require('assert').equal(result, 8)
})
// send a notification to an RPC server
ws.notify('openedNewsModule')
// subscribe to receive an event
ws.subscribe('feedUpdated')
ws.on('feedUpdated', function() {
updateLogic()
})
// unsubscribe from an event
ws.unsubscribe('feedUpdated')
// login your client to be able to use protected methods
ws.login({'username': 'confi1', 'password':'foobar'}).then(function() {
ws.call('account').then(function(result) {
require('assert').equal(result, ['confi1', 'confi2'])
})
}).catch(function(error) {
console.log('auth failed')
})
// close a websocket connection
ws.close()
})
```
## Documentation
Please consult our [API documentation](API.md) for both WebSocket server and client JavaScript and TypeScript classes.
## OSS Features
Features of the free open-source edition.
![OSS Features](assets/oss-features.png)
All library's open-source features are documented in our [API documentation](API.md) and can be used free of charge. You are free to implement your solutions based on provided methods in any way you are comfortable with, as long as you use our work along our very permissive [license](LICENSE) conditions.
## Pro Features
In order to support your production-ready environments, we can provide you with additional features built on top of our free OSS edition along with the skill set to turn your business case or a Proof-of-Concept idea into reality.
![Pro Features](assets/pro-features.png)
Describe us your use case by [contacting us](mailto:info@elpheria.com?subject=Pro%20Plan%20enquiry) and we will swiftly get back to you with a proposed solution that meets your needs.
## Professional support
We offer professional support for **rpc-websockets** and beyond. We have many years of expertise on building robust, scalable Node.js applications and can help you overcome issues and challenges preventing you to ship your great products. We excel in software architecture and implementation, being able to provide you with development, planning, consulting, training and customization services. Feel free to [contact us](mailto:support@elpheria.com?subject=rpc-websockets%20support%20enquiry) so we can discuss how to help you finish your products!
## Users
**rpc-websockets** is being actively used in production by multiple companies in a variety of different use cases.
<br>
<a href="https://scratchbox.io" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-scratchbox.png" alt="Scratchbox" height=50px></a>&emsp;
<a href="https://loomx.io" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-loom.png" alt="Loom Network" height=50px></a>&emsp;
<a href="https://www.uniqcast.com" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-uniqcast.png" alt="uniqCast" height=50px></a>&emsp;
<a href="https://leapdao.org" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-leapdao.png" alt="LeapDAO" height=50px></a>&emsp;
<a href="https://klika-tech.com" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-klikatech.png" alt="Klika Tech, Inc." height=50px></a>&emsp;
<a href="https://kodebox.io" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-kodebox.png" alt="Kodebox, Inc." height=50px></a>&emsp;
<a href="https://hey.network" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-heynetwork.png" alt="Hey-Group S.A./N.V." height=50px></a>&emsp;
<a href="https://www.hylo.com" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-hylo.png" alt="Hylo, Inc." height=50px></a>&emsp;
<a href="https://witnet.foundation" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-witnet.png" alt="Witnet Foundation" height=50px></a>&emsp;
<a href="https://www.scaleleap.com" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-scaleleap.png" alt="Scale Leap" height=50px></a>&emsp;
<a href="https://codice.org" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-codice.png" alt="Codice Foundation, Inc." height=50px></a>&emsp;
<a href="https://holo.host" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-holo.png" alt="Holo Ltd." height=50px></a>&emsp;
<a href="https://solana.com" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-solana.png" alt="Solana Labs, Inc." height=50px></a>&emsp;
<a href="https://filecoin.io" target="_blank"><img src="https://raw.githubusercontent.com/elpheria/rpc-websockets/master/assets/user-filecoin.png" alt="Filecoin" height=50px></a>&emsp;
## Sponsors
Become a sponsor and get your logo on project's README on GitHub with a link to your site. Feel free to [contact us](mailto:info@elpheria.com?subject=Sponsors) for the arrangement!
## License
This library is licensed under LGPLv3. Please see [LICENSE](LICENSE) for licensing details.

File diff suppressed because one or more lines are too long

425
node_modules/rpc-websockets/dist/index.browser.cjs generated vendored Normal file
View File

@@ -0,0 +1,425 @@
'use strict';
var buffer = require('buffer');
var eventemitter3 = require('eventemitter3');
// node_modules/esbuild-plugin-polyfill-node/polyfills/buffer.js
var WebSocketBrowserImpl = class extends eventemitter3.EventEmitter {
socket;
/** Instantiate a WebSocket class
* @constructor
* @param {String} address - url to a websocket server
* @param {WebSocketBrowserOptions} options - websocket options
* @return {WebSocketBrowserImpl} - returns a WebSocket instance
*/
constructor(address, options) {
super();
this.socket = new window.WebSocket(address, options.protocols);
this.socket.onopen = () => this.emit("open");
this.socket.onmessage = (event) => this.emit("message", event.data);
this.socket.onerror = (error) => this.emit("error", error);
this.socket.onclose = (event) => {
this.emit("close", event.code, event.reason);
};
}
/**
* Sends data through a websocket connection
* @method
* @param {(String|Object)} data - data to be sent via websocket
* @param {Object} optionsOrCallback - ws options
* @param {Function} callback - a callback called once the data is sent
* @return {Undefined}
*/
send(data, optionsOrCallback, callback) {
const cb = callback || optionsOrCallback;
try {
this.socket.send(data);
cb();
} catch (error) {
cb(error);
}
}
/**
* Closes an underlying socket
* @method
* @param {Number} code - status code explaining why the connection is being closed
* @param {String} reason - a description why the connection is closing
* @return {Undefined}
* @throws {Error}
*/
close(code, reason) {
this.socket.close(code, reason);
}
addEventListener(type, listener, options) {
this.socket.addEventListener(type, listener, options);
}
};
function WebSocket(address, options) {
return new WebSocketBrowserImpl(address, options);
}
// src/lib/utils.ts
var DefaultDataPack = class {
encode(value) {
return JSON.stringify(value);
}
decode(value) {
return JSON.parse(value);
}
};
// src/lib/client.ts
var CommonClient = class extends eventemitter3.EventEmitter {
address;
rpc_id;
queue;
options;
autoconnect;
ready;
reconnect;
reconnect_timer_id;
reconnect_interval;
max_reconnects;
rest_options;
current_reconnects;
generate_request_id;
socket;
webSocketFactory;
dataPack;
/**
* Instantiate a Client class.
* @constructor
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket
* @param {String} address - url to a websocket server
* @param {Object} options - ws options object with reconnect parameters
* @param {Function} generate_request_id - custom generation request Id
* @param {DataPack} dataPack - data pack contains encoder and decoder
* @return {CommonClient}
*/
constructor(webSocketFactory, address = "ws://localhost:8080", {
autoconnect = true,
reconnect = true,
reconnect_interval = 1e3,
max_reconnects = 5,
...rest_options
} = {}, generate_request_id, dataPack) {
super();
this.webSocketFactory = webSocketFactory;
this.queue = {};
this.rpc_id = 0;
this.address = address;
this.autoconnect = autoconnect;
this.ready = false;
this.reconnect = reconnect;
this.reconnect_timer_id = void 0;
this.reconnect_interval = reconnect_interval;
this.max_reconnects = max_reconnects;
this.rest_options = rest_options;
this.current_reconnects = 0;
this.generate_request_id = generate_request_id || (() => typeof this.rpc_id === "number" ? ++this.rpc_id : Number(this.rpc_id) + 1);
if (!dataPack) this.dataPack = new DefaultDataPack();
else this.dataPack = dataPack;
if (this.autoconnect)
this._connect(this.address, {
autoconnect: this.autoconnect,
reconnect: this.reconnect,
reconnect_interval: this.reconnect_interval,
max_reconnects: this.max_reconnects,
...this.rest_options
});
}
/**
* Connects to a defined server if not connected already.
* @method
* @return {Undefined}
*/
connect() {
if (this.socket) return;
this._connect(this.address, {
autoconnect: this.autoconnect,
reconnect: this.reconnect,
reconnect_interval: this.reconnect_interval,
max_reconnects: this.max_reconnects,
...this.rest_options
});
}
/**
* Calls a registered RPC method on server.
* @method
* @param {String} method - RPC method name
* @param {Object|Array} params - optional method parameters
* @param {Number} timeout - RPC reply timeout value
* @param {Object} ws_opts - options passed to ws
* @return {Promise}
*/
call(method, params, timeout, ws_opts) {
if (!ws_opts && "object" === typeof timeout) {
ws_opts = timeout;
timeout = null;
}
return new Promise((resolve, reject) => {
if (!this.ready) return reject(new Error("socket not ready"));
const rpc_id = this.generate_request_id(method, params);
const message = {
jsonrpc: "2.0",
method,
params: params || void 0,
id: rpc_id
};
this.socket.send(this.dataPack.encode(message), ws_opts, (error) => {
if (error) return reject(error);
this.queue[rpc_id] = { promise: [resolve, reject] };
if (timeout) {
this.queue[rpc_id].timeout = setTimeout(() => {
delete this.queue[rpc_id];
reject(new Error("reply timeout"));
}, timeout);
}
});
});
}
/**
* Logins with the other side of the connection.
* @method
* @param {Object} params - Login credentials object
* @return {Promise}
*/
async login(params) {
const resp = await this.call("rpc.login", params);
if (!resp) throw new Error("authentication failed");
return resp;
}
/**
* Fetches a list of client's methods registered on server.
* @method
* @return {Array}
*/
async listMethods() {
return await this.call("__listMethods");
}
/**
* Sends a JSON-RPC 2.0 notification to server.
* @method
* @param {String} method - RPC method name
* @param {Object} params - optional method parameters
* @return {Promise}
*/
notify(method, params) {
return new Promise((resolve, reject) => {
if (!this.ready) return reject(new Error("socket not ready"));
const message = {
jsonrpc: "2.0",
method,
params
};
this.socket.send(this.dataPack.encode(message), (error) => {
if (error) return reject(error);
resolve();
});
});
}
/**
* Subscribes for a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
async subscribe(event) {
if (typeof event === "string") event = [event];
const result = await this.call("rpc.on", event);
if (typeof event === "string" && result[event] !== "ok")
throw new Error(
"Failed subscribing to an event '" + event + "' with: " + result[event]
);
return result;
}
/**
* Unsubscribes from a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
async unsubscribe(event) {
if (typeof event === "string") event = [event];
const result = await this.call("rpc.off", event);
if (typeof event === "string" && result[event] !== "ok")
throw new Error("Failed unsubscribing from an event with: " + result);
return result;
}
/**
* Closes a WebSocket connection gracefully.
* @method
* @param {Number} code - socket close code
* @param {String} data - optional data to be sent before closing
* @return {Undefined}
*/
close(code, data) {
if (this.socket) this.socket.close(code || 1e3, data);
}
/**
* Enable / disable automatic reconnection.
* @method
* @param {Boolean} reconnect - enable / disable reconnection
* @return {Undefined}
*/
setAutoReconnect(reconnect) {
this.reconnect = reconnect;
}
/**
* Set the interval between reconnection attempts.
* @method
* @param {Number} interval - reconnection interval in milliseconds
* @return {Undefined}
*/
setReconnectInterval(interval) {
this.reconnect_interval = interval;
}
/**
* Set the maximum number of reconnection attempts.
* @method
* @param {Number} max_reconnects - maximum reconnection attempts
* @return {Undefined}
*/
setMaxReconnects(max_reconnects) {
this.max_reconnects = max_reconnects;
}
/**
* Get the current number of reconnection attempts made.
* @method
* @return {Number} current reconnection attempts
*/
getCurrentReconnects() {
return this.current_reconnects;
}
/**
* Get the maximum number of reconnection attempts.
* @method
* @return {Number} maximum reconnection attempts
*/
getMaxReconnects() {
return this.max_reconnects;
}
/**
* Check if the client is currently attempting to reconnect.
* @method
* @return {Boolean} true if reconnection is in progress
*/
isReconnecting() {
return this.reconnect_timer_id !== void 0;
}
/**
* Check if the client will attempt to reconnect on the next close event.
* @method
* @return {Boolean} true if reconnection will be attempted
*/
willReconnect() {
return this.reconnect && (this.max_reconnects === 0 || this.current_reconnects < this.max_reconnects);
}
/**
* Connection/Message handler.
* @method
* @private
* @param {String} address - WebSocket API address
* @param {Object} options - ws options object
* @return {Undefined}
*/
_connect(address, options) {
clearTimeout(this.reconnect_timer_id);
this.socket = this.webSocketFactory(address, options);
this.socket.addEventListener("open", () => {
this.ready = true;
this.emit("open");
this.current_reconnects = 0;
});
this.socket.addEventListener("message", ({ data: message }) => {
if (message instanceof ArrayBuffer)
message = buffer.Buffer.from(message).toString();
try {
message = this.dataPack.decode(message);
} catch (_error) {
return;
}
if (message.notification && this.listeners(message.notification).length) {
if (!Object.keys(message.params).length)
return this.emit(message.notification);
const args = [message.notification];
if (message.params.constructor === Object) args.push(message.params);
else
for (let i = 0; i < message.params.length; i++)
args.push(message.params[i]);
return Promise.resolve().then(() => {
this.emit.apply(this, args);
});
}
if (!this.queue[message.id]) {
if (message.method) {
return Promise.resolve().then(() => {
this.emit(message.method, message?.params);
});
}
return;
}
if ("error" in message === "result" in message)
this.queue[message.id].promise[1](
new Error(
'Server response malformed. Response must include either "result" or "error", but not both.'
)
);
if (this.queue[message.id].timeout)
clearTimeout(this.queue[message.id].timeout);
if (message.error) this.queue[message.id].promise[1](message.error);
else this.queue[message.id].promise[0](message.result);
delete this.queue[message.id];
});
this.socket.addEventListener("error", (error) => this.emit("error", error));
this.socket.addEventListener("close", ({ code, reason }) => {
if (this.ready)
setTimeout(() => this.emit("close", code, reason), 0);
this.ready = false;
this.socket = void 0;
if (code === 1e3) return;
this.current_reconnects++;
if (this.reconnect && (this.max_reconnects > this.current_reconnects || this.max_reconnects === 0))
this.reconnect_timer_id = setTimeout(
() => this._connect(address, options),
this.reconnect_interval
);
else if (this.reconnect && this.max_reconnects > 0 && this.current_reconnects >= this.max_reconnects) {
setTimeout(() => this.emit("max_reconnects_reached", code, reason), 1);
}
});
}
};
// src/index.browser.ts
var Client = class extends CommonClient {
constructor(address = "ws://localhost:8080", {
autoconnect = true,
reconnect = true,
reconnect_interval = 1e3,
max_reconnects = 5,
...rest_options
} = {}, generate_request_id) {
super(
WebSocket,
address,
{
autoconnect,
reconnect,
reconnect_interval,
max_reconnects,
...rest_options
},
generate_request_id
);
}
};
exports.Client = Client;
exports.CommonClient = CommonClient;
exports.DefaultDataPack = DefaultDataPack;
exports.WebSocket = WebSocket;
//# sourceMappingURL=index.browser.cjs.map
//# sourceMappingURL=index.browser.cjs.map

File diff suppressed because one or more lines are too long

255
node_modules/rpc-websockets/dist/index.browser.d.mts generated vendored Normal file
View File

@@ -0,0 +1,255 @@
import { EventEmitter } from 'eventemitter3';
import NodeWebSocket from 'ws';
type BrowserWebSocketType = InstanceType<typeof WebSocket>;
type NodeWebSocketType = InstanceType<typeof NodeWebSocket>;
type NodeWebSocketTypeOptions = NodeWebSocket.ClientOptions;
interface IWSClientAdditionalOptions {
autoconnect?: boolean;
reconnect?: boolean;
reconnect_interval?: number;
max_reconnects?: number;
}
interface ICommonWebSocketFactory {
(address: string, options: IWSClientAdditionalOptions): ICommonWebSocket;
}
interface ICommonWebSocket {
send: (data: Parameters<BrowserWebSocketType["send"]>[0], optionsOrCallback: ((error?: Error) => void) | Parameters<NodeWebSocketType["send"]>[1], callback?: (error?: Error) => void) => void;
close: (code?: number, reason?: string) => void;
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
}
/**
* WebSocket implements a browser-side WebSocket specification.
* @module Client
*/
type WebSocketBrowserOptions = {
/**
* One or more protocols passed to the websocket constructor
* @link https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket
*/
protocols?: string | string[];
};
declare class WebSocketBrowserImpl extends EventEmitter {
socket: BrowserWebSocketType;
/** Instantiate a WebSocket class
* @constructor
* @param {String} address - url to a websocket server
* @param {WebSocketBrowserOptions} options - websocket options
* @return {WebSocketBrowserImpl} - returns a WebSocket instance
*/
constructor(address: string, options: WebSocketBrowserOptions);
/**
* Sends data through a websocket connection
* @method
* @param {(String|Object)} data - data to be sent via websocket
* @param {Object} optionsOrCallback - ws options
* @param {Function} callback - a callback called once the data is sent
* @return {Undefined}
*/
send(data: Parameters<BrowserWebSocketType["send"]>[0], optionsOrCallback: (error?: Error) => void | Parameters<NodeWebSocketType["send"]>[1], callback?: () => void): void;
/**
* Closes an underlying socket
* @method
* @param {Number} code - status code explaining why the connection is being closed
* @param {String} reason - a description why the connection is closing
* @return {Undefined}
* @throws {Error}
*/
close(code?: number, reason?: string): void;
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
}
/**
* factory method for common WebSocket instance
* @method
* @param {String} address - url to a websocket server
* @param {(Object)} options - websocket options
* @return {Undefined}
*/
declare function WebSocket$1(address: string, options: IWSClientAdditionalOptions & WebSocketBrowserOptions): WebSocketBrowserImpl;
interface DataPack<T, R extends string | ArrayBufferLike | Blob | ArrayBufferView> {
encode(value: T): R;
decode(value: R): T;
}
declare class DefaultDataPack implements DataPack<Object, string> {
encode(value: Object): string;
decode(value: string): Object;
}
/**
* "Client" wraps "ws" or a browser-implemented "WebSocket" library
* according to the environment providing JSON RPC 2.0 support on top.
* @module Client
*/
interface IQueueElement {
promise: [
Parameters<ConstructorParameters<typeof Promise>[0]>[0],
Parameters<ConstructorParameters<typeof Promise>[0]>[1]
];
timeout?: ReturnType<typeof setTimeout>;
}
interface IQueue {
[x: number | string]: IQueueElement;
}
interface IWSRequestParams {
[x: string]: any;
[x: number]: any;
}
declare class CommonClient extends EventEmitter {
private address;
private rpc_id;
private queue;
private options;
private autoconnect;
private ready;
private reconnect;
private reconnect_timer_id;
private reconnect_interval;
private max_reconnects;
private rest_options;
private current_reconnects;
private generate_request_id;
private socket;
private webSocketFactory;
private dataPack;
/**
* Instantiate a Client class.
* @constructor
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket
* @param {String} address - url to a websocket server
* @param {Object} options - ws options object with reconnect parameters
* @param {Function} generate_request_id - custom generation request Id
* @param {DataPack} dataPack - data pack contains encoder and decoder
* @return {CommonClient}
*/
constructor(webSocketFactory: ICommonWebSocketFactory, address?: string, { autoconnect, reconnect, reconnect_interval, max_reconnects, ...rest_options }?: {
autoconnect?: boolean;
reconnect?: boolean;
reconnect_interval?: number;
max_reconnects?: number;
}, generate_request_id?: (method: string, params: object | Array<any>) => number | string, dataPack?: DataPack<object, string>);
/**
* Connects to a defined server if not connected already.
* @method
* @return {Undefined}
*/
connect(): void;
/**
* Calls a registered RPC method on server.
* @method
* @param {String} method - RPC method name
* @param {Object|Array} params - optional method parameters
* @param {Number} timeout - RPC reply timeout value
* @param {Object} ws_opts - options passed to ws
* @return {Promise}
*/
call(method: string, params?: IWSRequestParams, timeout?: number, ws_opts?: Parameters<NodeWebSocketType["send"]>[1]): Promise<unknown>;
/**
* Logins with the other side of the connection.
* @method
* @param {Object} params - Login credentials object
* @return {Promise}
*/
login(params: IWSRequestParams): Promise<unknown>;
/**
* Fetches a list of client's methods registered on server.
* @method
* @return {Array}
*/
listMethods(): Promise<unknown>;
/**
* Sends a JSON-RPC 2.0 notification to server.
* @method
* @param {String} method - RPC method name
* @param {Object} params - optional method parameters
* @return {Promise}
*/
notify(method: string, params?: IWSRequestParams): Promise<void>;
/**
* Subscribes for a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
subscribe(event: string | Array<string>): Promise<unknown>;
/**
* Unsubscribes from a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
unsubscribe(event: string | Array<string>): Promise<unknown>;
/**
* Closes a WebSocket connection gracefully.
* @method
* @param {Number} code - socket close code
* @param {String} data - optional data to be sent before closing
* @return {Undefined}
*/
close(code?: number, data?: string): void;
/**
* Enable / disable automatic reconnection.
* @method
* @param {Boolean} reconnect - enable / disable reconnection
* @return {Undefined}
*/
setAutoReconnect(reconnect: boolean): void;
/**
* Set the interval between reconnection attempts.
* @method
* @param {Number} interval - reconnection interval in milliseconds
* @return {Undefined}
*/
setReconnectInterval(interval: number): void;
/**
* Set the maximum number of reconnection attempts.
* @method
* @param {Number} max_reconnects - maximum reconnection attempts
* @return {Undefined}
*/
setMaxReconnects(max_reconnects: number): void;
/**
* Get the current number of reconnection attempts made.
* @method
* @return {Number} current reconnection attempts
*/
getCurrentReconnects(): number;
/**
* Get the maximum number of reconnection attempts.
* @method
* @return {Number} maximum reconnection attempts
*/
getMaxReconnects(): number;
/**
* Check if the client is currently attempting to reconnect.
* @method
* @return {Boolean} true if reconnection is in progress
*/
isReconnecting(): boolean;
/**
* Check if the client will attempt to reconnect on the next close event.
* @method
* @return {Boolean} true if reconnection will be attempted
*/
willReconnect(): boolean;
/**
* Connection/Message handler.
* @method
* @private
* @param {String} address - WebSocket API address
* @param {Object} options - ws options object
* @return {Undefined}
*/
private _connect;
}
declare class Client extends CommonClient {
constructor(address?: string, { autoconnect, reconnect, reconnect_interval, max_reconnects, ...rest_options }?: IWSClientAdditionalOptions & WebSocketBrowserOptions, generate_request_id?: (method: string, params: object | Array<any>) => number | string);
}
export { type BrowserWebSocketType, Client, CommonClient, type DataPack, DefaultDataPack, type ICommonWebSocket, type ICommonWebSocketFactory, type IQueue, type IWSClientAdditionalOptions, type IWSRequestParams, type NodeWebSocketType, type NodeWebSocketTypeOptions, WebSocket$1 as WebSocket, type WebSocketBrowserOptions };

255
node_modules/rpc-websockets/dist/index.browser.d.ts generated vendored Normal file
View File

@@ -0,0 +1,255 @@
import { EventEmitter } from 'eventemitter3';
import NodeWebSocket from 'ws';
type BrowserWebSocketType = InstanceType<typeof WebSocket>;
type NodeWebSocketType = InstanceType<typeof NodeWebSocket>;
type NodeWebSocketTypeOptions = NodeWebSocket.ClientOptions;
interface IWSClientAdditionalOptions {
autoconnect?: boolean;
reconnect?: boolean;
reconnect_interval?: number;
max_reconnects?: number;
}
interface ICommonWebSocketFactory {
(address: string, options: IWSClientAdditionalOptions): ICommonWebSocket;
}
interface ICommonWebSocket {
send: (data: Parameters<BrowserWebSocketType["send"]>[0], optionsOrCallback: ((error?: Error) => void) | Parameters<NodeWebSocketType["send"]>[1], callback?: (error?: Error) => void) => void;
close: (code?: number, reason?: string) => void;
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
}
/**
* WebSocket implements a browser-side WebSocket specification.
* @module Client
*/
type WebSocketBrowserOptions = {
/**
* One or more protocols passed to the websocket constructor
* @link https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket
*/
protocols?: string | string[];
};
declare class WebSocketBrowserImpl extends EventEmitter {
socket: BrowserWebSocketType;
/** Instantiate a WebSocket class
* @constructor
* @param {String} address - url to a websocket server
* @param {WebSocketBrowserOptions} options - websocket options
* @return {WebSocketBrowserImpl} - returns a WebSocket instance
*/
constructor(address: string, options: WebSocketBrowserOptions);
/**
* Sends data through a websocket connection
* @method
* @param {(String|Object)} data - data to be sent via websocket
* @param {Object} optionsOrCallback - ws options
* @param {Function} callback - a callback called once the data is sent
* @return {Undefined}
*/
send(data: Parameters<BrowserWebSocketType["send"]>[0], optionsOrCallback: (error?: Error) => void | Parameters<NodeWebSocketType["send"]>[1], callback?: () => void): void;
/**
* Closes an underlying socket
* @method
* @param {Number} code - status code explaining why the connection is being closed
* @param {String} reason - a description why the connection is closing
* @return {Undefined}
* @throws {Error}
*/
close(code?: number, reason?: string): void;
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
}
/**
* factory method for common WebSocket instance
* @method
* @param {String} address - url to a websocket server
* @param {(Object)} options - websocket options
* @return {Undefined}
*/
declare function WebSocket$1(address: string, options: IWSClientAdditionalOptions & WebSocketBrowserOptions): WebSocketBrowserImpl;
interface DataPack<T, R extends string | ArrayBufferLike | Blob | ArrayBufferView> {
encode(value: T): R;
decode(value: R): T;
}
declare class DefaultDataPack implements DataPack<Object, string> {
encode(value: Object): string;
decode(value: string): Object;
}
/**
* "Client" wraps "ws" or a browser-implemented "WebSocket" library
* according to the environment providing JSON RPC 2.0 support on top.
* @module Client
*/
interface IQueueElement {
promise: [
Parameters<ConstructorParameters<typeof Promise>[0]>[0],
Parameters<ConstructorParameters<typeof Promise>[0]>[1]
];
timeout?: ReturnType<typeof setTimeout>;
}
interface IQueue {
[x: number | string]: IQueueElement;
}
interface IWSRequestParams {
[x: string]: any;
[x: number]: any;
}
declare class CommonClient extends EventEmitter {
private address;
private rpc_id;
private queue;
private options;
private autoconnect;
private ready;
private reconnect;
private reconnect_timer_id;
private reconnect_interval;
private max_reconnects;
private rest_options;
private current_reconnects;
private generate_request_id;
private socket;
private webSocketFactory;
private dataPack;
/**
* Instantiate a Client class.
* @constructor
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket
* @param {String} address - url to a websocket server
* @param {Object} options - ws options object with reconnect parameters
* @param {Function} generate_request_id - custom generation request Id
* @param {DataPack} dataPack - data pack contains encoder and decoder
* @return {CommonClient}
*/
constructor(webSocketFactory: ICommonWebSocketFactory, address?: string, { autoconnect, reconnect, reconnect_interval, max_reconnects, ...rest_options }?: {
autoconnect?: boolean;
reconnect?: boolean;
reconnect_interval?: number;
max_reconnects?: number;
}, generate_request_id?: (method: string, params: object | Array<any>) => number | string, dataPack?: DataPack<object, string>);
/**
* Connects to a defined server if not connected already.
* @method
* @return {Undefined}
*/
connect(): void;
/**
* Calls a registered RPC method on server.
* @method
* @param {String} method - RPC method name
* @param {Object|Array} params - optional method parameters
* @param {Number} timeout - RPC reply timeout value
* @param {Object} ws_opts - options passed to ws
* @return {Promise}
*/
call(method: string, params?: IWSRequestParams, timeout?: number, ws_opts?: Parameters<NodeWebSocketType["send"]>[1]): Promise<unknown>;
/**
* Logins with the other side of the connection.
* @method
* @param {Object} params - Login credentials object
* @return {Promise}
*/
login(params: IWSRequestParams): Promise<unknown>;
/**
* Fetches a list of client's methods registered on server.
* @method
* @return {Array}
*/
listMethods(): Promise<unknown>;
/**
* Sends a JSON-RPC 2.0 notification to server.
* @method
* @param {String} method - RPC method name
* @param {Object} params - optional method parameters
* @return {Promise}
*/
notify(method: string, params?: IWSRequestParams): Promise<void>;
/**
* Subscribes for a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
subscribe(event: string | Array<string>): Promise<unknown>;
/**
* Unsubscribes from a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
unsubscribe(event: string | Array<string>): Promise<unknown>;
/**
* Closes a WebSocket connection gracefully.
* @method
* @param {Number} code - socket close code
* @param {String} data - optional data to be sent before closing
* @return {Undefined}
*/
close(code?: number, data?: string): void;
/**
* Enable / disable automatic reconnection.
* @method
* @param {Boolean} reconnect - enable / disable reconnection
* @return {Undefined}
*/
setAutoReconnect(reconnect: boolean): void;
/**
* Set the interval between reconnection attempts.
* @method
* @param {Number} interval - reconnection interval in milliseconds
* @return {Undefined}
*/
setReconnectInterval(interval: number): void;
/**
* Set the maximum number of reconnection attempts.
* @method
* @param {Number} max_reconnects - maximum reconnection attempts
* @return {Undefined}
*/
setMaxReconnects(max_reconnects: number): void;
/**
* Get the current number of reconnection attempts made.
* @method
* @return {Number} current reconnection attempts
*/
getCurrentReconnects(): number;
/**
* Get the maximum number of reconnection attempts.
* @method
* @return {Number} maximum reconnection attempts
*/
getMaxReconnects(): number;
/**
* Check if the client is currently attempting to reconnect.
* @method
* @return {Boolean} true if reconnection is in progress
*/
isReconnecting(): boolean;
/**
* Check if the client will attempt to reconnect on the next close event.
* @method
* @return {Boolean} true if reconnection will be attempted
*/
willReconnect(): boolean;
/**
* Connection/Message handler.
* @method
* @private
* @param {String} address - WebSocket API address
* @param {Object} options - ws options object
* @return {Undefined}
*/
private _connect;
}
declare class Client extends CommonClient {
constructor(address?: string, { autoconnect, reconnect, reconnect_interval, max_reconnects, ...rest_options }?: IWSClientAdditionalOptions & WebSocketBrowserOptions, generate_request_id?: (method: string, params: object | Array<any>) => number | string);
}
export { type BrowserWebSocketType, Client, CommonClient, type DataPack, DefaultDataPack, type ICommonWebSocket, type ICommonWebSocketFactory, type IQueue, type IWSClientAdditionalOptions, type IWSRequestParams, type NodeWebSocketType, type NodeWebSocketTypeOptions, WebSocket$1 as WebSocket, type WebSocketBrowserOptions };

420
node_modules/rpc-websockets/dist/index.browser.mjs generated vendored Normal file
View File

@@ -0,0 +1,420 @@
import { Buffer } from 'buffer';
import { EventEmitter } from 'eventemitter3';
// node_modules/esbuild-plugin-polyfill-node/polyfills/buffer.js
var WebSocketBrowserImpl = class extends EventEmitter {
socket;
/** Instantiate a WebSocket class
* @constructor
* @param {String} address - url to a websocket server
* @param {WebSocketBrowserOptions} options - websocket options
* @return {WebSocketBrowserImpl} - returns a WebSocket instance
*/
constructor(address, options) {
super();
this.socket = new window.WebSocket(address, options.protocols);
this.socket.onopen = () => this.emit("open");
this.socket.onmessage = (event) => this.emit("message", event.data);
this.socket.onerror = (error) => this.emit("error", error);
this.socket.onclose = (event) => {
this.emit("close", event.code, event.reason);
};
}
/**
* Sends data through a websocket connection
* @method
* @param {(String|Object)} data - data to be sent via websocket
* @param {Object} optionsOrCallback - ws options
* @param {Function} callback - a callback called once the data is sent
* @return {Undefined}
*/
send(data, optionsOrCallback, callback) {
const cb = callback || optionsOrCallback;
try {
this.socket.send(data);
cb();
} catch (error) {
cb(error);
}
}
/**
* Closes an underlying socket
* @method
* @param {Number} code - status code explaining why the connection is being closed
* @param {String} reason - a description why the connection is closing
* @return {Undefined}
* @throws {Error}
*/
close(code, reason) {
this.socket.close(code, reason);
}
addEventListener(type, listener, options) {
this.socket.addEventListener(type, listener, options);
}
};
function WebSocket(address, options) {
return new WebSocketBrowserImpl(address, options);
}
// src/lib/utils.ts
var DefaultDataPack = class {
encode(value) {
return JSON.stringify(value);
}
decode(value) {
return JSON.parse(value);
}
};
// src/lib/client.ts
var CommonClient = class extends EventEmitter {
address;
rpc_id;
queue;
options;
autoconnect;
ready;
reconnect;
reconnect_timer_id;
reconnect_interval;
max_reconnects;
rest_options;
current_reconnects;
generate_request_id;
socket;
webSocketFactory;
dataPack;
/**
* Instantiate a Client class.
* @constructor
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket
* @param {String} address - url to a websocket server
* @param {Object} options - ws options object with reconnect parameters
* @param {Function} generate_request_id - custom generation request Id
* @param {DataPack} dataPack - data pack contains encoder and decoder
* @return {CommonClient}
*/
constructor(webSocketFactory, address = "ws://localhost:8080", {
autoconnect = true,
reconnect = true,
reconnect_interval = 1e3,
max_reconnects = 5,
...rest_options
} = {}, generate_request_id, dataPack) {
super();
this.webSocketFactory = webSocketFactory;
this.queue = {};
this.rpc_id = 0;
this.address = address;
this.autoconnect = autoconnect;
this.ready = false;
this.reconnect = reconnect;
this.reconnect_timer_id = void 0;
this.reconnect_interval = reconnect_interval;
this.max_reconnects = max_reconnects;
this.rest_options = rest_options;
this.current_reconnects = 0;
this.generate_request_id = generate_request_id || (() => typeof this.rpc_id === "number" ? ++this.rpc_id : Number(this.rpc_id) + 1);
if (!dataPack) this.dataPack = new DefaultDataPack();
else this.dataPack = dataPack;
if (this.autoconnect)
this._connect(this.address, {
autoconnect: this.autoconnect,
reconnect: this.reconnect,
reconnect_interval: this.reconnect_interval,
max_reconnects: this.max_reconnects,
...this.rest_options
});
}
/**
* Connects to a defined server if not connected already.
* @method
* @return {Undefined}
*/
connect() {
if (this.socket) return;
this._connect(this.address, {
autoconnect: this.autoconnect,
reconnect: this.reconnect,
reconnect_interval: this.reconnect_interval,
max_reconnects: this.max_reconnects,
...this.rest_options
});
}
/**
* Calls a registered RPC method on server.
* @method
* @param {String} method - RPC method name
* @param {Object|Array} params - optional method parameters
* @param {Number} timeout - RPC reply timeout value
* @param {Object} ws_opts - options passed to ws
* @return {Promise}
*/
call(method, params, timeout, ws_opts) {
if (!ws_opts && "object" === typeof timeout) {
ws_opts = timeout;
timeout = null;
}
return new Promise((resolve, reject) => {
if (!this.ready) return reject(new Error("socket not ready"));
const rpc_id = this.generate_request_id(method, params);
const message = {
jsonrpc: "2.0",
method,
params: params || void 0,
id: rpc_id
};
this.socket.send(this.dataPack.encode(message), ws_opts, (error) => {
if (error) return reject(error);
this.queue[rpc_id] = { promise: [resolve, reject] };
if (timeout) {
this.queue[rpc_id].timeout = setTimeout(() => {
delete this.queue[rpc_id];
reject(new Error("reply timeout"));
}, timeout);
}
});
});
}
/**
* Logins with the other side of the connection.
* @method
* @param {Object} params - Login credentials object
* @return {Promise}
*/
async login(params) {
const resp = await this.call("rpc.login", params);
if (!resp) throw new Error("authentication failed");
return resp;
}
/**
* Fetches a list of client's methods registered on server.
* @method
* @return {Array}
*/
async listMethods() {
return await this.call("__listMethods");
}
/**
* Sends a JSON-RPC 2.0 notification to server.
* @method
* @param {String} method - RPC method name
* @param {Object} params - optional method parameters
* @return {Promise}
*/
notify(method, params) {
return new Promise((resolve, reject) => {
if (!this.ready) return reject(new Error("socket not ready"));
const message = {
jsonrpc: "2.0",
method,
params
};
this.socket.send(this.dataPack.encode(message), (error) => {
if (error) return reject(error);
resolve();
});
});
}
/**
* Subscribes for a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
async subscribe(event) {
if (typeof event === "string") event = [event];
const result = await this.call("rpc.on", event);
if (typeof event === "string" && result[event] !== "ok")
throw new Error(
"Failed subscribing to an event '" + event + "' with: " + result[event]
);
return result;
}
/**
* Unsubscribes from a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
async unsubscribe(event) {
if (typeof event === "string") event = [event];
const result = await this.call("rpc.off", event);
if (typeof event === "string" && result[event] !== "ok")
throw new Error("Failed unsubscribing from an event with: " + result);
return result;
}
/**
* Closes a WebSocket connection gracefully.
* @method
* @param {Number} code - socket close code
* @param {String} data - optional data to be sent before closing
* @return {Undefined}
*/
close(code, data) {
if (this.socket) this.socket.close(code || 1e3, data);
}
/**
* Enable / disable automatic reconnection.
* @method
* @param {Boolean} reconnect - enable / disable reconnection
* @return {Undefined}
*/
setAutoReconnect(reconnect) {
this.reconnect = reconnect;
}
/**
* Set the interval between reconnection attempts.
* @method
* @param {Number} interval - reconnection interval in milliseconds
* @return {Undefined}
*/
setReconnectInterval(interval) {
this.reconnect_interval = interval;
}
/**
* Set the maximum number of reconnection attempts.
* @method
* @param {Number} max_reconnects - maximum reconnection attempts
* @return {Undefined}
*/
setMaxReconnects(max_reconnects) {
this.max_reconnects = max_reconnects;
}
/**
* Get the current number of reconnection attempts made.
* @method
* @return {Number} current reconnection attempts
*/
getCurrentReconnects() {
return this.current_reconnects;
}
/**
* Get the maximum number of reconnection attempts.
* @method
* @return {Number} maximum reconnection attempts
*/
getMaxReconnects() {
return this.max_reconnects;
}
/**
* Check if the client is currently attempting to reconnect.
* @method
* @return {Boolean} true if reconnection is in progress
*/
isReconnecting() {
return this.reconnect_timer_id !== void 0;
}
/**
* Check if the client will attempt to reconnect on the next close event.
* @method
* @return {Boolean} true if reconnection will be attempted
*/
willReconnect() {
return this.reconnect && (this.max_reconnects === 0 || this.current_reconnects < this.max_reconnects);
}
/**
* Connection/Message handler.
* @method
* @private
* @param {String} address - WebSocket API address
* @param {Object} options - ws options object
* @return {Undefined}
*/
_connect(address, options) {
clearTimeout(this.reconnect_timer_id);
this.socket = this.webSocketFactory(address, options);
this.socket.addEventListener("open", () => {
this.ready = true;
this.emit("open");
this.current_reconnects = 0;
});
this.socket.addEventListener("message", ({ data: message }) => {
if (message instanceof ArrayBuffer)
message = Buffer.from(message).toString();
try {
message = this.dataPack.decode(message);
} catch (_error) {
return;
}
if (message.notification && this.listeners(message.notification).length) {
if (!Object.keys(message.params).length)
return this.emit(message.notification);
const args = [message.notification];
if (message.params.constructor === Object) args.push(message.params);
else
for (let i = 0; i < message.params.length; i++)
args.push(message.params[i]);
return Promise.resolve().then(() => {
this.emit.apply(this, args);
});
}
if (!this.queue[message.id]) {
if (message.method) {
return Promise.resolve().then(() => {
this.emit(message.method, message?.params);
});
}
return;
}
if ("error" in message === "result" in message)
this.queue[message.id].promise[1](
new Error(
'Server response malformed. Response must include either "result" or "error", but not both.'
)
);
if (this.queue[message.id].timeout)
clearTimeout(this.queue[message.id].timeout);
if (message.error) this.queue[message.id].promise[1](message.error);
else this.queue[message.id].promise[0](message.result);
delete this.queue[message.id];
});
this.socket.addEventListener("error", (error) => this.emit("error", error));
this.socket.addEventListener("close", ({ code, reason }) => {
if (this.ready)
setTimeout(() => this.emit("close", code, reason), 0);
this.ready = false;
this.socket = void 0;
if (code === 1e3) return;
this.current_reconnects++;
if (this.reconnect && (this.max_reconnects > this.current_reconnects || this.max_reconnects === 0))
this.reconnect_timer_id = setTimeout(
() => this._connect(address, options),
this.reconnect_interval
);
else if (this.reconnect && this.max_reconnects > 0 && this.current_reconnects >= this.max_reconnects) {
setTimeout(() => this.emit("max_reconnects_reached", code, reason), 1);
}
});
}
};
// src/index.browser.ts
var Client = class extends CommonClient {
constructor(address = "ws://localhost:8080", {
autoconnect = true,
reconnect = true,
reconnect_interval = 1e3,
max_reconnects = 5,
...rest_options
} = {}, generate_request_id) {
super(
WebSocket,
address,
{
autoconnect,
reconnect,
reconnect_interval,
max_reconnects,
...rest_options
},
generate_request_id
);
}
};
export { Client, CommonClient, DefaultDataPack, WebSocket };
//# sourceMappingURL=index.browser.mjs.map
//# sourceMappingURL=index.browser.mjs.map

File diff suppressed because one or more lines are too long

938
node_modules/rpc-websockets/dist/index.cjs generated vendored Normal file
View File

@@ -0,0 +1,938 @@
'use strict';
var WebSocketImpl = require('ws');
var eventemitter3 = require('eventemitter3');
var url = require('url');
var uuid = require('uuid');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var WebSocketImpl__default = /*#__PURE__*/_interopDefault(WebSocketImpl);
var url__default = /*#__PURE__*/_interopDefault(url);
// src/lib/client/websocket.ts
function WebSocket(address, options) {
return new WebSocketImpl__default.default(address, options);
}
// src/lib/utils.ts
var DefaultDataPack = class {
encode(value) {
return JSON.stringify(value);
}
decode(value) {
return JSON.parse(value);
}
};
// src/lib/client.ts
var CommonClient = class extends eventemitter3.EventEmitter {
address;
rpc_id;
queue;
options;
autoconnect;
ready;
reconnect;
reconnect_timer_id;
reconnect_interval;
max_reconnects;
rest_options;
current_reconnects;
generate_request_id;
socket;
webSocketFactory;
dataPack;
/**
* Instantiate a Client class.
* @constructor
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket
* @param {String} address - url to a websocket server
* @param {Object} options - ws options object with reconnect parameters
* @param {Function} generate_request_id - custom generation request Id
* @param {DataPack} dataPack - data pack contains encoder and decoder
* @return {CommonClient}
*/
constructor(webSocketFactory, address = "ws://localhost:8080", {
autoconnect = true,
reconnect = true,
reconnect_interval = 1e3,
max_reconnects = 5,
...rest_options
} = {}, generate_request_id, dataPack) {
super();
this.webSocketFactory = webSocketFactory;
this.queue = {};
this.rpc_id = 0;
this.address = address;
this.autoconnect = autoconnect;
this.ready = false;
this.reconnect = reconnect;
this.reconnect_timer_id = void 0;
this.reconnect_interval = reconnect_interval;
this.max_reconnects = max_reconnects;
this.rest_options = rest_options;
this.current_reconnects = 0;
this.generate_request_id = generate_request_id || (() => typeof this.rpc_id === "number" ? ++this.rpc_id : Number(this.rpc_id) + 1);
if (!dataPack) this.dataPack = new DefaultDataPack();
else this.dataPack = dataPack;
if (this.autoconnect)
this._connect(this.address, {
autoconnect: this.autoconnect,
reconnect: this.reconnect,
reconnect_interval: this.reconnect_interval,
max_reconnects: this.max_reconnects,
...this.rest_options
});
}
/**
* Connects to a defined server if not connected already.
* @method
* @return {Undefined}
*/
connect() {
if (this.socket) return;
this._connect(this.address, {
autoconnect: this.autoconnect,
reconnect: this.reconnect,
reconnect_interval: this.reconnect_interval,
max_reconnects: this.max_reconnects,
...this.rest_options
});
}
/**
* Calls a registered RPC method on server.
* @method
* @param {String} method - RPC method name
* @param {Object|Array} params - optional method parameters
* @param {Number} timeout - RPC reply timeout value
* @param {Object} ws_opts - options passed to ws
* @return {Promise}
*/
call(method, params, timeout, ws_opts) {
if (!ws_opts && "object" === typeof timeout) {
ws_opts = timeout;
timeout = null;
}
return new Promise((resolve, reject) => {
if (!this.ready) return reject(new Error("socket not ready"));
const rpc_id = this.generate_request_id(method, params);
const message = {
jsonrpc: "2.0",
method,
params: params || void 0,
id: rpc_id
};
this.socket.send(this.dataPack.encode(message), ws_opts, (error) => {
if (error) return reject(error);
this.queue[rpc_id] = { promise: [resolve, reject] };
if (timeout) {
this.queue[rpc_id].timeout = setTimeout(() => {
delete this.queue[rpc_id];
reject(new Error("reply timeout"));
}, timeout);
}
});
});
}
/**
* Logins with the other side of the connection.
* @method
* @param {Object} params - Login credentials object
* @return {Promise}
*/
async login(params) {
const resp = await this.call("rpc.login", params);
if (!resp) throw new Error("authentication failed");
return resp;
}
/**
* Fetches a list of client's methods registered on server.
* @method
* @return {Array}
*/
async listMethods() {
return await this.call("__listMethods");
}
/**
* Sends a JSON-RPC 2.0 notification to server.
* @method
* @param {String} method - RPC method name
* @param {Object} params - optional method parameters
* @return {Promise}
*/
notify(method, params) {
return new Promise((resolve, reject) => {
if (!this.ready) return reject(new Error("socket not ready"));
const message = {
jsonrpc: "2.0",
method,
params
};
this.socket.send(this.dataPack.encode(message), (error) => {
if (error) return reject(error);
resolve();
});
});
}
/**
* Subscribes for a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
async subscribe(event) {
if (typeof event === "string") event = [event];
const result = await this.call("rpc.on", event);
if (typeof event === "string" && result[event] !== "ok")
throw new Error(
"Failed subscribing to an event '" + event + "' with: " + result[event]
);
return result;
}
/**
* Unsubscribes from a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
async unsubscribe(event) {
if (typeof event === "string") event = [event];
const result = await this.call("rpc.off", event);
if (typeof event === "string" && result[event] !== "ok")
throw new Error("Failed unsubscribing from an event with: " + result);
return result;
}
/**
* Closes a WebSocket connection gracefully.
* @method
* @param {Number} code - socket close code
* @param {String} data - optional data to be sent before closing
* @return {Undefined}
*/
close(code, data) {
if (this.socket) this.socket.close(code || 1e3, data);
}
/**
* Enable / disable automatic reconnection.
* @method
* @param {Boolean} reconnect - enable / disable reconnection
* @return {Undefined}
*/
setAutoReconnect(reconnect) {
this.reconnect = reconnect;
}
/**
* Set the interval between reconnection attempts.
* @method
* @param {Number} interval - reconnection interval in milliseconds
* @return {Undefined}
*/
setReconnectInterval(interval) {
this.reconnect_interval = interval;
}
/**
* Set the maximum number of reconnection attempts.
* @method
* @param {Number} max_reconnects - maximum reconnection attempts
* @return {Undefined}
*/
setMaxReconnects(max_reconnects) {
this.max_reconnects = max_reconnects;
}
/**
* Get the current number of reconnection attempts made.
* @method
* @return {Number} current reconnection attempts
*/
getCurrentReconnects() {
return this.current_reconnects;
}
/**
* Get the maximum number of reconnection attempts.
* @method
* @return {Number} maximum reconnection attempts
*/
getMaxReconnects() {
return this.max_reconnects;
}
/**
* Check if the client is currently attempting to reconnect.
* @method
* @return {Boolean} true if reconnection is in progress
*/
isReconnecting() {
return this.reconnect_timer_id !== void 0;
}
/**
* Check if the client will attempt to reconnect on the next close event.
* @method
* @return {Boolean} true if reconnection will be attempted
*/
willReconnect() {
return this.reconnect && (this.max_reconnects === 0 || this.current_reconnects < this.max_reconnects);
}
/**
* Connection/Message handler.
* @method
* @private
* @param {String} address - WebSocket API address
* @param {Object} options - ws options object
* @return {Undefined}
*/
_connect(address, options) {
clearTimeout(this.reconnect_timer_id);
this.socket = this.webSocketFactory(address, options);
this.socket.addEventListener("open", () => {
this.ready = true;
this.emit("open");
this.current_reconnects = 0;
});
this.socket.addEventListener("message", ({ data: message }) => {
if (message instanceof ArrayBuffer)
message = Buffer.from(message).toString();
try {
message = this.dataPack.decode(message);
} catch (_error) {
return;
}
if (message.notification && this.listeners(message.notification).length) {
if (!Object.keys(message.params).length)
return this.emit(message.notification);
const args = [message.notification];
if (message.params.constructor === Object) args.push(message.params);
else
for (let i = 0; i < message.params.length; i++)
args.push(message.params[i]);
return Promise.resolve().then(() => {
this.emit.apply(this, args);
});
}
if (!this.queue[message.id]) {
if (message.method) {
return Promise.resolve().then(() => {
this.emit(message.method, message?.params);
});
}
return;
}
if ("error" in message === "result" in message)
this.queue[message.id].promise[1](
new Error(
'Server response malformed. Response must include either "result" or "error", but not both.'
)
);
if (this.queue[message.id].timeout)
clearTimeout(this.queue[message.id].timeout);
if (message.error) this.queue[message.id].promise[1](message.error);
else this.queue[message.id].promise[0](message.result);
delete this.queue[message.id];
});
this.socket.addEventListener("error", (error) => this.emit("error", error));
this.socket.addEventListener("close", ({ code, reason }) => {
if (this.ready)
setTimeout(() => this.emit("close", code, reason), 0);
this.ready = false;
this.socket = void 0;
if (code === 1e3) return;
this.current_reconnects++;
if (this.reconnect && (this.max_reconnects > this.current_reconnects || this.max_reconnects === 0))
this.reconnect_timer_id = setTimeout(
() => this._connect(address, options),
this.reconnect_interval
);
else if (this.reconnect && this.max_reconnects > 0 && this.current_reconnects >= this.max_reconnects) {
setTimeout(() => this.emit("max_reconnects_reached", code, reason), 1);
}
});
}
};
var Server = class extends eventemitter3.EventEmitter {
namespaces;
dataPack;
wss;
/**
* Instantiate a Server class.
* @constructor
* @param {Object} options - ws constructor's parameters with rpc
* @param {DataPack} dataPack - data pack contains encoder and decoder
* @return {Server} - returns a new Server instance
*/
constructor(options, dataPack) {
super();
this.namespaces = {};
if (!dataPack) this.dataPack = new DefaultDataPack();
else this.dataPack = dataPack;
this.wss = new WebSocketImpl.WebSocketServer(options);
this.wss.on("listening", () => this.emit("listening"));
this.wss.on("connection", (socket, request) => {
const u = url__default.default.parse(request.url, true);
const ns = u.pathname;
if (u.query.socket_id) socket._id = u.query.socket_id;
else socket._id = uuid.v1();
socket["_authenticated"] = false;
socket.on("error", (error) => this.emit("socket-error", socket, error));
socket.on("close", () => {
this.namespaces[ns].clients.delete(socket._id);
for (const event of Object.keys(this.namespaces[ns].events)) {
const index = this.namespaces[ns].events[event].sockets.indexOf(
socket._id
);
if (index >= 0)
this.namespaces[ns].events[event].sockets.splice(index, 1);
}
this.emit("disconnection", socket);
});
if (!this.namespaces[ns]) this._generateNamespace(ns);
this.namespaces[ns].clients.set(socket._id, socket);
this.emit("connection", socket, request);
return this._handleRPC(socket, ns);
});
this.wss.on("error", (error) => this.emit("error", error));
}
/**
* Registers an RPC method.
* @method
* @param {String} name - method name
* @param {Function} fn - a callee function
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Object} - returns an IMethod object
*/
register(name, fn, ns = "/") {
if (!this.namespaces[ns]) this._generateNamespace(ns);
this.namespaces[ns].rpc_methods[name] = {
fn,
protected: false
};
return {
protected: () => this._makeProtectedMethod(name, ns),
public: () => this._makePublicMethod(name, ns)
};
}
/**
* Sets an auth method.
* @method
* @param {Function} fn - an arbitrary auth method
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Undefined}
*/
setAuth(fn, ns = "/") {
this.register("rpc.login", fn, ns);
}
/**
* Marks an RPC method as protected.
* @method
* @param {String} name - method name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
_makeProtectedMethod(name, ns = "/") {
this.namespaces[ns].rpc_methods[name].protected = true;
}
/**
* Marks an RPC method as public.
* @method
* @param {String} name - method name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
_makePublicMethod(name, ns = "/") {
this.namespaces[ns].rpc_methods[name].protected = false;
}
/**
* Marks an event as protected.
* @method
* @param {String} name - event name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
_makeProtectedEvent(name, ns = "/") {
this.namespaces[ns].events[name].protected = true;
}
/**
* Marks an event as public.
* @method
* @param {String} name - event name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
_makePublicEvent(name, ns = "/") {
this.namespaces[ns].events[name].protected = false;
}
/**
* Removes a namespace and closes all connections
* @method
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Undefined}
*/
closeNamespace(ns) {
const namespace = this.namespaces[ns];
if (namespace) {
delete namespace.rpc_methods;
delete namespace.events;
for (const socket of namespace.clients.values()) socket.close();
delete this.namespaces[ns];
}
}
/**
* Creates a new event that can be emitted to clients.
* @method
* @param {String} name - event name
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Object} - returns an IEvent object
*/
event(name, ns = "/") {
if (!this.namespaces[ns]) this._generateNamespace(ns);
else {
const index = this.namespaces[ns].events[name];
if (index !== void 0)
throw new Error(`Already registered event ${ns}${name}`);
}
this.namespaces[ns].events[name] = {
sockets: [],
protected: false
};
this.on(name, (...params) => {
if (params.length === 1 && params[0] instanceof Object)
params = params[0];
for (const socket_id of this.namespaces[ns].events[name].sockets) {
const socket = this.namespaces[ns].clients.get(socket_id);
if (!socket) continue;
socket.send(
this.dataPack.encode({
notification: name,
params
})
);
}
});
return {
protected: () => this._makeProtectedEvent(name, ns),
public: () => this._makePublicEvent(name, ns)
};
}
/**
* Returns a requested namespace object
* @method
* @param {String} name - namespace identifier
* @throws {TypeError}
* @return {Object} - namespace object
*/
of(name) {
if (!this.namespaces[name]) this._generateNamespace(name);
const self = this;
return {
// self.register convenience method
register(fn_name, fn) {
if (arguments.length !== 2)
throw new Error("must provide exactly two arguments");
if (typeof fn_name !== "string")
throw new Error("name must be a string");
if (typeof fn !== "function")
throw new Error("handler must be a function");
return self.register(fn_name, fn, name);
},
// self.event convenience method
event(ev_name) {
if (arguments.length !== 1)
throw new Error("must provide exactly one argument");
if (typeof ev_name !== "string")
throw new Error("name must be a string");
return self.event(ev_name, name);
},
// self.eventList convenience method
get eventList() {
return Object.keys(self.namespaces[name].events);
},
/**
* Emits a specified event to this namespace.
* @inner
* @method
* @param {String} event - event name
* @param {Array} params - event parameters
* @return {Undefined}
*/
emit(event, ...params) {
const nsEvent = self.namespaces[name].events[event];
if (nsEvent)
for (const socket_id of nsEvent.sockets) {
const socket = self.namespaces[name].clients.get(socket_id);
if (!socket) continue;
socket.send(
self.dataPack.encode({
notification: event,
params
})
);
}
},
/**
* Returns a name of this namespace.
* @inner
* @method
* @kind constant
* @return {String}
*/
get name() {
return name;
},
/**
* Returns a hash of websocket objects connected to this namespace.
* @inner
* @method
* @return {Object}
*/
connected() {
const socket_ids = [...self.namespaces[name].clients.keys()];
return socket_ids.reduce(
(acc, curr) => ({
...acc,
[curr]: self.namespaces[name].clients.get(curr)
}),
{}
);
},
/**
* Returns a list of client unique identifiers connected to this namespace.
* @inner
* @method
* @return {Array}
*/
clients() {
return self.namespaces[name];
}
};
}
/**
* Lists all created events in a given namespace. Defaults to "/".
* @method
* @param {String} ns - namespaces identifier
* @readonly
* @return {Array} - returns a list of created events
*/
eventList(ns = "/") {
if (!this.namespaces[ns]) return [];
return Object.keys(this.namespaces[ns].events);
}
/**
* Creates a JSON-RPC 2.0 compliant error
* @method
* @param {Number} code - indicates the error type that occurred
* @param {String} message - provides a short description of the error
* @param {String|Object} data - details containing additional information about the error
* @return {Object}
*/
createError(code, message, data) {
return {
code,
message,
data: data || null
};
}
/**
* Closes the server and terminates all clients.
* @method
* @return {Promise}
*/
close() {
return new Promise((resolve, reject) => {
try {
this.wss.close();
this.emit("close");
resolve();
} catch (error) {
reject(error);
}
});
}
/**
* Handles all WebSocket JSON RPC 2.0 requests.
* @private
* @param {Object} socket - ws socket instance
* @param {String} ns - namespaces identifier
* @return {Undefined}
*/
_handleRPC(socket, ns = "/") {
socket.on("message", async (data) => {
const msg_options = {};
if (data instanceof ArrayBuffer) {
msg_options.binary = true;
data = Buffer.from(data).toString();
}
if (socket.readyState !== 1) return;
let parsedData;
try {
parsedData = this.dataPack.decode(data);
} catch (error) {
return socket.send(
this.dataPack.encode({
jsonrpc: "2.0",
error: createError(-32700, error.toString()),
id: null
}),
msg_options
);
}
if (Array.isArray(parsedData)) {
if (!parsedData.length)
return socket.send(
this.dataPack.encode({
jsonrpc: "2.0",
error: createError(-32600, "Invalid array"),
id: null
}),
msg_options
);
const responses = [];
for (const message of parsedData) {
const response2 = await this._runMethod(message, socket._id, ns);
if (!response2) continue;
responses.push(response2);
}
if (!responses.length) return;
return socket.send(this.dataPack.encode(responses), msg_options);
}
const response = await this._runMethod(parsedData, socket._id, ns);
if (!response) return;
return socket.send(this.dataPack.encode(response), msg_options);
});
}
/**
* Runs a defined RPC method.
* @private
* @param {Object} message - a message received
* @param {Object} socket_id - user's socket id
* @param {String} ns - namespaces identifier
* @return {Object|undefined}
*/
async _runMethod(message, socket_id, ns = "/") {
if (typeof message !== "object" || message === null)
return {
jsonrpc: "2.0",
error: createError(-32600),
id: null
};
if (message.jsonrpc !== "2.0")
return {
jsonrpc: "2.0",
error: createError(-32600, "Invalid JSON RPC version"),
id: message.id || null
};
if (!message.method)
return {
jsonrpc: "2.0",
error: createError(-32602, "Method not specified"),
id: message.id || null
};
if (typeof message.method !== "string")
return {
jsonrpc: "2.0",
error: createError(-32600, "Invalid method name"),
id: message.id || null
};
if (message.params && typeof message.params === "string")
return {
jsonrpc: "2.0",
error: createError(-32600),
id: message.id || null
};
if (message.method === "rpc.on") {
if (!message.params)
return {
jsonrpc: "2.0",
error: createError(-32e3),
id: message.id || null
};
const results = {};
const event_names = Object.keys(this.namespaces[ns].events);
for (const name of message.params) {
const index = event_names.indexOf(name);
const namespace = this.namespaces[ns];
if (index === -1) {
results[name] = "provided event invalid";
continue;
}
if (namespace.events[event_names[index]].protected === true && namespace.clients.get(socket_id)["_authenticated"] === false) {
return {
jsonrpc: "2.0",
error: createError(-32606),
id: message.id || null
};
}
const socket_index = namespace.events[event_names[index]].sockets.indexOf(socket_id);
if (socket_index >= 0) {
results[name] = "socket has already been subscribed to event";
continue;
}
namespace.events[event_names[index]].sockets.push(socket_id);
results[name] = "ok";
}
return {
jsonrpc: "2.0",
result: results,
id: message.id || null
};
} else if (message.method === "rpc.off") {
if (!message.params)
return {
jsonrpc: "2.0",
error: createError(-32e3),
id: message.id || null
};
const results = {};
for (const name of message.params) {
if (!this.namespaces[ns].events[name]) {
results[name] = "provided event invalid";
continue;
}
const index = this.namespaces[ns].events[name].sockets.indexOf(socket_id);
if (index === -1) {
results[name] = "not subscribed";
continue;
}
this.namespaces[ns].events[name].sockets.splice(index, 1);
results[name] = "ok";
}
return {
jsonrpc: "2.0",
result: results,
id: message.id || null
};
} else if (message.method === "rpc.login") {
if (!message.params)
return {
jsonrpc: "2.0",
error: createError(-32604),
id: message.id || null
};
}
if (!this.namespaces[ns].rpc_methods[message.method]) {
return {
jsonrpc: "2.0",
error: createError(-32601),
id: message.id || null
};
}
let response = null;
if (this.namespaces[ns].rpc_methods[message.method].protected === true && this.namespaces[ns].clients.get(socket_id)["_authenticated"] === false) {
return {
jsonrpc: "2.0",
error: createError(-32605),
id: message.id || null
};
}
try {
response = await this.namespaces[ns].rpc_methods[message.method].fn(
message.params,
socket_id
);
} catch (error) {
if (!message.id) return;
if (error instanceof Error)
return {
jsonrpc: "2.0",
error: {
code: -32e3,
message: error.name,
data: error.message
},
id: message.id
};
return {
jsonrpc: "2.0",
error,
id: message.id
};
}
if (!message.id) return;
if (message.method === "rpc.login" && response === true) {
const s = this.namespaces[ns].clients.get(socket_id);
if (s) {
s["_authenticated"] = true;
this.namespaces[ns].clients.set(socket_id, s);
}
}
return {
jsonrpc: "2.0",
result: response,
id: message.id
};
}
/**
* Generate a new namespace store.
* Also preregister some special namespace methods.
* @private
* @param {String} name - namespaces identifier
* @return {undefined}
*/
_generateNamespace(name) {
this.namespaces[name] = {
rpc_methods: {
__listMethods: {
fn: () => Object.keys(this.namespaces[name].rpc_methods),
protected: false
}
},
clients: /* @__PURE__ */ new Map(),
events: {}
};
}
};
var RPC_ERRORS = /* @__PURE__ */ new Map([
[-32e3, "Event not provided"],
[-32600, "Invalid Request"],
[-32601, "Method not found"],
[-32602, "Invalid params"],
[-32603, "Internal error"],
[-32604, "Params not found"],
[-32605, "Method forbidden"],
[-32606, "Event forbidden"],
[-32700, "Parse error"]
]);
function createError(code, details) {
const error = {
code,
message: RPC_ERRORS.get(code) || "Internal Server Error"
};
if (details) error["data"] = details;
return error;
}
// src/index.ts
var Client = class extends CommonClient {
constructor(address = "ws://localhost:8080", {
autoconnect = true,
reconnect = true,
reconnect_interval = 1e3,
max_reconnects = 5,
...rest_options
} = {}, generate_request_id) {
super(
WebSocket,
address,
{
autoconnect,
reconnect,
reconnect_interval,
max_reconnects,
...rest_options
},
generate_request_id
);
}
};
exports.Client = Client;
exports.CommonClient = CommonClient;
exports.DefaultDataPack = DefaultDataPack;
exports.Server = Server;
exports.WebSocket = WebSocket;
exports.createError = createError;
//# sourceMappingURL=index.cjs.map
//# sourceMappingURL=index.cjs.map

1
node_modules/rpc-websockets/dist/index.cjs.map generated vendored Normal file

File diff suppressed because one or more lines are too long

452
node_modules/rpc-websockets/dist/index.d.mts generated vendored Normal file
View File

@@ -0,0 +1,452 @@
import { EventEmitter } from 'eventemitter3';
import NodeWebSocket, { WebSocketServer } from 'ws';
type BrowserWebSocketType = InstanceType<typeof WebSocket>;
type NodeWebSocketType = InstanceType<typeof NodeWebSocket>;
type NodeWebSocketTypeOptions = NodeWebSocket.ClientOptions;
interface IWSClientAdditionalOptions {
autoconnect?: boolean;
reconnect?: boolean;
reconnect_interval?: number;
max_reconnects?: number;
}
interface ICommonWebSocketFactory {
(address: string, options: IWSClientAdditionalOptions): ICommonWebSocket;
}
interface ICommonWebSocket {
send: (data: Parameters<BrowserWebSocketType["send"]>[0], optionsOrCallback: ((error?: Error) => void) | Parameters<NodeWebSocketType["send"]>[1], callback?: (error?: Error) => void) => void;
close: (code?: number, reason?: string) => void;
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
}
interface DataPack<T, R extends string | ArrayBufferLike | Blob | ArrayBufferView> {
encode(value: T): R;
decode(value: R): T;
}
declare class DefaultDataPack implements DataPack<Object, string> {
encode(value: Object): string;
decode(value: string): Object;
}
/**
* "Client" wraps "ws" or a browser-implemented "WebSocket" library
* according to the environment providing JSON RPC 2.0 support on top.
* @module Client
*/
interface IQueueElement {
promise: [
Parameters<ConstructorParameters<typeof Promise>[0]>[0],
Parameters<ConstructorParameters<typeof Promise>[0]>[1]
];
timeout?: ReturnType<typeof setTimeout>;
}
interface IQueue {
[x: number | string]: IQueueElement;
}
interface IWSRequestParams {
[x: string]: any;
[x: number]: any;
}
declare class CommonClient extends EventEmitter {
private address;
private rpc_id;
private queue;
private options;
private autoconnect;
private ready;
private reconnect;
private reconnect_timer_id;
private reconnect_interval;
private max_reconnects;
private rest_options;
private current_reconnects;
private generate_request_id;
private socket;
private webSocketFactory;
private dataPack;
/**
* Instantiate a Client class.
* @constructor
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket
* @param {String} address - url to a websocket server
* @param {Object} options - ws options object with reconnect parameters
* @param {Function} generate_request_id - custom generation request Id
* @param {DataPack} dataPack - data pack contains encoder and decoder
* @return {CommonClient}
*/
constructor(webSocketFactory: ICommonWebSocketFactory, address?: string, { autoconnect, reconnect, reconnect_interval, max_reconnects, ...rest_options }?: {
autoconnect?: boolean;
reconnect?: boolean;
reconnect_interval?: number;
max_reconnects?: number;
}, generate_request_id?: (method: string, params: object | Array<any>) => number | string, dataPack?: DataPack<object, string>);
/**
* Connects to a defined server if not connected already.
* @method
* @return {Undefined}
*/
connect(): void;
/**
* Calls a registered RPC method on server.
* @method
* @param {String} method - RPC method name
* @param {Object|Array} params - optional method parameters
* @param {Number} timeout - RPC reply timeout value
* @param {Object} ws_opts - options passed to ws
* @return {Promise}
*/
call(method: string, params?: IWSRequestParams, timeout?: number, ws_opts?: Parameters<NodeWebSocketType["send"]>[1]): Promise<unknown>;
/**
* Logins with the other side of the connection.
* @method
* @param {Object} params - Login credentials object
* @return {Promise}
*/
login(params: IWSRequestParams): Promise<unknown>;
/**
* Fetches a list of client's methods registered on server.
* @method
* @return {Array}
*/
listMethods(): Promise<unknown>;
/**
* Sends a JSON-RPC 2.0 notification to server.
* @method
* @param {String} method - RPC method name
* @param {Object} params - optional method parameters
* @return {Promise}
*/
notify(method: string, params?: IWSRequestParams): Promise<void>;
/**
* Subscribes for a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
subscribe(event: string | Array<string>): Promise<unknown>;
/**
* Unsubscribes from a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
unsubscribe(event: string | Array<string>): Promise<unknown>;
/**
* Closes a WebSocket connection gracefully.
* @method
* @param {Number} code - socket close code
* @param {String} data - optional data to be sent before closing
* @return {Undefined}
*/
close(code?: number, data?: string): void;
/**
* Enable / disable automatic reconnection.
* @method
* @param {Boolean} reconnect - enable / disable reconnection
* @return {Undefined}
*/
setAutoReconnect(reconnect: boolean): void;
/**
* Set the interval between reconnection attempts.
* @method
* @param {Number} interval - reconnection interval in milliseconds
* @return {Undefined}
*/
setReconnectInterval(interval: number): void;
/**
* Set the maximum number of reconnection attempts.
* @method
* @param {Number} max_reconnects - maximum reconnection attempts
* @return {Undefined}
*/
setMaxReconnects(max_reconnects: number): void;
/**
* Get the current number of reconnection attempts made.
* @method
* @return {Number} current reconnection attempts
*/
getCurrentReconnects(): number;
/**
* Get the maximum number of reconnection attempts.
* @method
* @return {Number} maximum reconnection attempts
*/
getMaxReconnects(): number;
/**
* Check if the client is currently attempting to reconnect.
* @method
* @return {Boolean} true if reconnection is in progress
*/
isReconnecting(): boolean;
/**
* Check if the client will attempt to reconnect on the next close event.
* @method
* @return {Boolean} true if reconnection will be attempted
*/
willReconnect(): boolean;
/**
* Connection/Message handler.
* @method
* @private
* @param {String} address - WebSocket API address
* @param {Object} options - ws options object
* @return {Undefined}
*/
private _connect;
}
/**
* factory method for common WebSocket instance
* @method
* @param {String} address - url to a websocket server
* @param {(Object)} options - websocket options
* @return {Undefined}
*/
declare function WebSocket$1(address: string, options: IWSClientAdditionalOptions & NodeWebSocket.ClientOptions): NodeWebSocket;
/**
* "Server" wraps the "ws" library providing JSON RPC 2.0 support on top.
* @module Server
*/
interface INamespaceEvent {
[x: string]: {
sockets: Array<string>;
protected: boolean;
};
}
interface IMethod {
public: () => void;
protected: () => void;
}
interface IEvent {
public: () => void;
protected: () => void;
}
interface IRPCError {
code: number;
message: string;
data?: string;
}
interface IRPCMethodParams {
[x: string]: any;
}
interface IRPCMethod {
[x: string]: {
fn: (params: IRPCMethodParams, socket_id: string) => any;
protected: boolean;
};
}
interface IClientWebSocket extends NodeWebSocket {
_id: string;
_authenticated: boolean;
}
declare class Server extends EventEmitter {
private namespaces;
private dataPack;
wss: InstanceType<typeof WebSocketServer>;
/**
* Instantiate a Server class.
* @constructor
* @param {Object} options - ws constructor's parameters with rpc
* @param {DataPack} dataPack - data pack contains encoder and decoder
* @return {Server} - returns a new Server instance
*/
constructor(options: NodeWebSocket.ServerOptions, dataPack?: DataPack<object, string>);
/**
* Registers an RPC method.
* @method
* @param {String} name - method name
* @param {Function} fn - a callee function
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Object} - returns an IMethod object
*/
register(name: string, fn: (params: IRPCMethodParams, socket_id: string) => void, ns?: string): IMethod;
/**
* Sets an auth method.
* @method
* @param {Function} fn - an arbitrary auth method
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Undefined}
*/
setAuth(fn: (params: IRPCMethodParams, socket_id: string) => Promise<boolean>, ns?: string): void;
/**
* Marks an RPC method as protected.
* @method
* @param {String} name - method name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
private _makeProtectedMethod;
/**
* Marks an RPC method as public.
* @method
* @param {String} name - method name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
private _makePublicMethod;
/**
* Marks an event as protected.
* @method
* @param {String} name - event name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
private _makeProtectedEvent;
/**
* Marks an event as public.
* @method
* @param {String} name - event name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
private _makePublicEvent;
/**
* Removes a namespace and closes all connections
* @method
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Undefined}
*/
closeNamespace(ns: string): void;
/**
* Creates a new event that can be emitted to clients.
* @method
* @param {String} name - event name
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Object} - returns an IEvent object
*/
event(name: string, ns?: string): IEvent;
/**
* Returns a requested namespace object
* @method
* @param {String} name - namespace identifier
* @throws {TypeError}
* @return {Object} - namespace object
*/
of(name: string): {
register(fn_name: string, fn: (params: IRPCMethodParams) => void): IMethod;
event(ev_name: string): IEvent;
readonly eventList: string[];
/**
* Emits a specified event to this namespace.
* @inner
* @method
* @param {String} event - event name
* @param {Array} params - event parameters
* @return {Undefined}
*/
emit(event: string, ...params: Array<string>): void;
/**
* Returns a name of this namespace.
* @inner
* @method
* @kind constant
* @return {String}
*/
readonly name: string;
/**
* Returns a hash of websocket objects connected to this namespace.
* @inner
* @method
* @return {Object}
*/
connected(): {};
/**
* Returns a list of client unique identifiers connected to this namespace.
* @inner
* @method
* @return {Array}
*/
clients(): {
rpc_methods: IRPCMethod;
clients: Map<string, IClientWebSocket>;
events: INamespaceEvent;
};
};
/**
* Lists all created events in a given namespace. Defaults to "/".
* @method
* @param {String} ns - namespaces identifier
* @readonly
* @return {Array} - returns a list of created events
*/
eventList(ns?: string): string[];
/**
* Creates a JSON-RPC 2.0 compliant error
* @method
* @param {Number} code - indicates the error type that occurred
* @param {String} message - provides a short description of the error
* @param {String|Object} data - details containing additional information about the error
* @return {Object}
*/
createError(code: number, message: string, data: string | object): {
code: number;
message: string;
data: string | object;
};
/**
* Closes the server and terminates all clients.
* @method
* @return {Promise}
*/
close(): Promise<void>;
/**
* Handles all WebSocket JSON RPC 2.0 requests.
* @private
* @param {Object} socket - ws socket instance
* @param {String} ns - namespaces identifier
* @return {Undefined}
*/
private _handleRPC;
/**
* Runs a defined RPC method.
* @private
* @param {Object} message - a message received
* @param {Object} socket_id - user's socket id
* @param {String} ns - namespaces identifier
* @return {Object|undefined}
*/
private _runMethod;
/**
* Generate a new namespace store.
* Also preregister some special namespace methods.
* @private
* @param {String} name - namespaces identifier
* @return {undefined}
*/
private _generateNamespace;
}
/**
* Creates a JSON-RPC 2.0-compliant error.
* @param {Number} code - error code
* @param {String} details - error details
* @return {Object}
*/
declare function createError(code: number, details?: string): IRPCError;
/**
* WebSocket implements a browser-side WebSocket specification.
* @module Client
*/
type WebSocketBrowserOptions = {
/**
* One or more protocols passed to the websocket constructor
* @link https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket
*/
protocols?: string | string[];
};
declare class Client extends CommonClient {
constructor(address?: string, { autoconnect, reconnect, reconnect_interval, max_reconnects, ...rest_options }?: IWSClientAdditionalOptions & NodeWebSocketTypeOptions, generate_request_id?: (method: string, params: object | Array<any>) => number | string);
}
export { type BrowserWebSocketType, Client, CommonClient, type DataPack, DefaultDataPack, type ICommonWebSocket, type ICommonWebSocketFactory, type IQueue, type IWSClientAdditionalOptions, type IWSRequestParams, type NodeWebSocketType, type NodeWebSocketTypeOptions, Server, WebSocket$1 as WebSocket, type WebSocketBrowserOptions, createError };

452
node_modules/rpc-websockets/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,452 @@
import { EventEmitter } from 'eventemitter3';
import NodeWebSocket, { WebSocketServer } from 'ws';
type BrowserWebSocketType = InstanceType<typeof WebSocket>;
type NodeWebSocketType = InstanceType<typeof NodeWebSocket>;
type NodeWebSocketTypeOptions = NodeWebSocket.ClientOptions;
interface IWSClientAdditionalOptions {
autoconnect?: boolean;
reconnect?: boolean;
reconnect_interval?: number;
max_reconnects?: number;
}
interface ICommonWebSocketFactory {
(address: string, options: IWSClientAdditionalOptions): ICommonWebSocket;
}
interface ICommonWebSocket {
send: (data: Parameters<BrowserWebSocketType["send"]>[0], optionsOrCallback: ((error?: Error) => void) | Parameters<NodeWebSocketType["send"]>[1], callback?: (error?: Error) => void) => void;
close: (code?: number, reason?: string) => void;
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
}
interface DataPack<T, R extends string | ArrayBufferLike | Blob | ArrayBufferView> {
encode(value: T): R;
decode(value: R): T;
}
declare class DefaultDataPack implements DataPack<Object, string> {
encode(value: Object): string;
decode(value: string): Object;
}
/**
* "Client" wraps "ws" or a browser-implemented "WebSocket" library
* according to the environment providing JSON RPC 2.0 support on top.
* @module Client
*/
interface IQueueElement {
promise: [
Parameters<ConstructorParameters<typeof Promise>[0]>[0],
Parameters<ConstructorParameters<typeof Promise>[0]>[1]
];
timeout?: ReturnType<typeof setTimeout>;
}
interface IQueue {
[x: number | string]: IQueueElement;
}
interface IWSRequestParams {
[x: string]: any;
[x: number]: any;
}
declare class CommonClient extends EventEmitter {
private address;
private rpc_id;
private queue;
private options;
private autoconnect;
private ready;
private reconnect;
private reconnect_timer_id;
private reconnect_interval;
private max_reconnects;
private rest_options;
private current_reconnects;
private generate_request_id;
private socket;
private webSocketFactory;
private dataPack;
/**
* Instantiate a Client class.
* @constructor
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket
* @param {String} address - url to a websocket server
* @param {Object} options - ws options object with reconnect parameters
* @param {Function} generate_request_id - custom generation request Id
* @param {DataPack} dataPack - data pack contains encoder and decoder
* @return {CommonClient}
*/
constructor(webSocketFactory: ICommonWebSocketFactory, address?: string, { autoconnect, reconnect, reconnect_interval, max_reconnects, ...rest_options }?: {
autoconnect?: boolean;
reconnect?: boolean;
reconnect_interval?: number;
max_reconnects?: number;
}, generate_request_id?: (method: string, params: object | Array<any>) => number | string, dataPack?: DataPack<object, string>);
/**
* Connects to a defined server if not connected already.
* @method
* @return {Undefined}
*/
connect(): void;
/**
* Calls a registered RPC method on server.
* @method
* @param {String} method - RPC method name
* @param {Object|Array} params - optional method parameters
* @param {Number} timeout - RPC reply timeout value
* @param {Object} ws_opts - options passed to ws
* @return {Promise}
*/
call(method: string, params?: IWSRequestParams, timeout?: number, ws_opts?: Parameters<NodeWebSocketType["send"]>[1]): Promise<unknown>;
/**
* Logins with the other side of the connection.
* @method
* @param {Object} params - Login credentials object
* @return {Promise}
*/
login(params: IWSRequestParams): Promise<unknown>;
/**
* Fetches a list of client's methods registered on server.
* @method
* @return {Array}
*/
listMethods(): Promise<unknown>;
/**
* Sends a JSON-RPC 2.0 notification to server.
* @method
* @param {String} method - RPC method name
* @param {Object} params - optional method parameters
* @return {Promise}
*/
notify(method: string, params?: IWSRequestParams): Promise<void>;
/**
* Subscribes for a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
subscribe(event: string | Array<string>): Promise<unknown>;
/**
* Unsubscribes from a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
unsubscribe(event: string | Array<string>): Promise<unknown>;
/**
* Closes a WebSocket connection gracefully.
* @method
* @param {Number} code - socket close code
* @param {String} data - optional data to be sent before closing
* @return {Undefined}
*/
close(code?: number, data?: string): void;
/**
* Enable / disable automatic reconnection.
* @method
* @param {Boolean} reconnect - enable / disable reconnection
* @return {Undefined}
*/
setAutoReconnect(reconnect: boolean): void;
/**
* Set the interval between reconnection attempts.
* @method
* @param {Number} interval - reconnection interval in milliseconds
* @return {Undefined}
*/
setReconnectInterval(interval: number): void;
/**
* Set the maximum number of reconnection attempts.
* @method
* @param {Number} max_reconnects - maximum reconnection attempts
* @return {Undefined}
*/
setMaxReconnects(max_reconnects: number): void;
/**
* Get the current number of reconnection attempts made.
* @method
* @return {Number} current reconnection attempts
*/
getCurrentReconnects(): number;
/**
* Get the maximum number of reconnection attempts.
* @method
* @return {Number} maximum reconnection attempts
*/
getMaxReconnects(): number;
/**
* Check if the client is currently attempting to reconnect.
* @method
* @return {Boolean} true if reconnection is in progress
*/
isReconnecting(): boolean;
/**
* Check if the client will attempt to reconnect on the next close event.
* @method
* @return {Boolean} true if reconnection will be attempted
*/
willReconnect(): boolean;
/**
* Connection/Message handler.
* @method
* @private
* @param {String} address - WebSocket API address
* @param {Object} options - ws options object
* @return {Undefined}
*/
private _connect;
}
/**
* factory method for common WebSocket instance
* @method
* @param {String} address - url to a websocket server
* @param {(Object)} options - websocket options
* @return {Undefined}
*/
declare function WebSocket$1(address: string, options: IWSClientAdditionalOptions & NodeWebSocket.ClientOptions): NodeWebSocket;
/**
* "Server" wraps the "ws" library providing JSON RPC 2.0 support on top.
* @module Server
*/
interface INamespaceEvent {
[x: string]: {
sockets: Array<string>;
protected: boolean;
};
}
interface IMethod {
public: () => void;
protected: () => void;
}
interface IEvent {
public: () => void;
protected: () => void;
}
interface IRPCError {
code: number;
message: string;
data?: string;
}
interface IRPCMethodParams {
[x: string]: any;
}
interface IRPCMethod {
[x: string]: {
fn: (params: IRPCMethodParams, socket_id: string) => any;
protected: boolean;
};
}
interface IClientWebSocket extends NodeWebSocket {
_id: string;
_authenticated: boolean;
}
declare class Server extends EventEmitter {
private namespaces;
private dataPack;
wss: InstanceType<typeof WebSocketServer>;
/**
* Instantiate a Server class.
* @constructor
* @param {Object} options - ws constructor's parameters with rpc
* @param {DataPack} dataPack - data pack contains encoder and decoder
* @return {Server} - returns a new Server instance
*/
constructor(options: NodeWebSocket.ServerOptions, dataPack?: DataPack<object, string>);
/**
* Registers an RPC method.
* @method
* @param {String} name - method name
* @param {Function} fn - a callee function
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Object} - returns an IMethod object
*/
register(name: string, fn: (params: IRPCMethodParams, socket_id: string) => void, ns?: string): IMethod;
/**
* Sets an auth method.
* @method
* @param {Function} fn - an arbitrary auth method
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Undefined}
*/
setAuth(fn: (params: IRPCMethodParams, socket_id: string) => Promise<boolean>, ns?: string): void;
/**
* Marks an RPC method as protected.
* @method
* @param {String} name - method name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
private _makeProtectedMethod;
/**
* Marks an RPC method as public.
* @method
* @param {String} name - method name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
private _makePublicMethod;
/**
* Marks an event as protected.
* @method
* @param {String} name - event name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
private _makeProtectedEvent;
/**
* Marks an event as public.
* @method
* @param {String} name - event name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
private _makePublicEvent;
/**
* Removes a namespace and closes all connections
* @method
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Undefined}
*/
closeNamespace(ns: string): void;
/**
* Creates a new event that can be emitted to clients.
* @method
* @param {String} name - event name
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Object} - returns an IEvent object
*/
event(name: string, ns?: string): IEvent;
/**
* Returns a requested namespace object
* @method
* @param {String} name - namespace identifier
* @throws {TypeError}
* @return {Object} - namespace object
*/
of(name: string): {
register(fn_name: string, fn: (params: IRPCMethodParams) => void): IMethod;
event(ev_name: string): IEvent;
readonly eventList: string[];
/**
* Emits a specified event to this namespace.
* @inner
* @method
* @param {String} event - event name
* @param {Array} params - event parameters
* @return {Undefined}
*/
emit(event: string, ...params: Array<string>): void;
/**
* Returns a name of this namespace.
* @inner
* @method
* @kind constant
* @return {String}
*/
readonly name: string;
/**
* Returns a hash of websocket objects connected to this namespace.
* @inner
* @method
* @return {Object}
*/
connected(): {};
/**
* Returns a list of client unique identifiers connected to this namespace.
* @inner
* @method
* @return {Array}
*/
clients(): {
rpc_methods: IRPCMethod;
clients: Map<string, IClientWebSocket>;
events: INamespaceEvent;
};
};
/**
* Lists all created events in a given namespace. Defaults to "/".
* @method
* @param {String} ns - namespaces identifier
* @readonly
* @return {Array} - returns a list of created events
*/
eventList(ns?: string): string[];
/**
* Creates a JSON-RPC 2.0 compliant error
* @method
* @param {Number} code - indicates the error type that occurred
* @param {String} message - provides a short description of the error
* @param {String|Object} data - details containing additional information about the error
* @return {Object}
*/
createError(code: number, message: string, data: string | object): {
code: number;
message: string;
data: string | object;
};
/**
* Closes the server and terminates all clients.
* @method
* @return {Promise}
*/
close(): Promise<void>;
/**
* Handles all WebSocket JSON RPC 2.0 requests.
* @private
* @param {Object} socket - ws socket instance
* @param {String} ns - namespaces identifier
* @return {Undefined}
*/
private _handleRPC;
/**
* Runs a defined RPC method.
* @private
* @param {Object} message - a message received
* @param {Object} socket_id - user's socket id
* @param {String} ns - namespaces identifier
* @return {Object|undefined}
*/
private _runMethod;
/**
* Generate a new namespace store.
* Also preregister some special namespace methods.
* @private
* @param {String} name - namespaces identifier
* @return {undefined}
*/
private _generateNamespace;
}
/**
* Creates a JSON-RPC 2.0-compliant error.
* @param {Number} code - error code
* @param {String} details - error details
* @return {Object}
*/
declare function createError(code: number, details?: string): IRPCError;
/**
* WebSocket implements a browser-side WebSocket specification.
* @module Client
*/
type WebSocketBrowserOptions = {
/**
* One or more protocols passed to the websocket constructor
* @link https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket
*/
protocols?: string | string[];
};
declare class Client extends CommonClient {
constructor(address?: string, { autoconnect, reconnect, reconnect_interval, max_reconnects, ...rest_options }?: IWSClientAdditionalOptions & NodeWebSocketTypeOptions, generate_request_id?: (method: string, params: object | Array<any>) => number | string);
}
export { type BrowserWebSocketType, Client, CommonClient, type DataPack, DefaultDataPack, type ICommonWebSocket, type ICommonWebSocketFactory, type IQueue, type IWSClientAdditionalOptions, type IWSRequestParams, type NodeWebSocketType, type NodeWebSocketTypeOptions, Server, WebSocket$1 as WebSocket, type WebSocketBrowserOptions, createError };

926
node_modules/rpc-websockets/dist/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,926 @@
import WebSocketImpl, { WebSocketServer } from 'ws';
import { EventEmitter } from 'eventemitter3';
import url from 'url';
import { v1 } from 'uuid';
// src/lib/client/websocket.ts
function WebSocket(address, options) {
return new WebSocketImpl(address, options);
}
// src/lib/utils.ts
var DefaultDataPack = class {
encode(value) {
return JSON.stringify(value);
}
decode(value) {
return JSON.parse(value);
}
};
// src/lib/client.ts
var CommonClient = class extends EventEmitter {
address;
rpc_id;
queue;
options;
autoconnect;
ready;
reconnect;
reconnect_timer_id;
reconnect_interval;
max_reconnects;
rest_options;
current_reconnects;
generate_request_id;
socket;
webSocketFactory;
dataPack;
/**
* Instantiate a Client class.
* @constructor
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket
* @param {String} address - url to a websocket server
* @param {Object} options - ws options object with reconnect parameters
* @param {Function} generate_request_id - custom generation request Id
* @param {DataPack} dataPack - data pack contains encoder and decoder
* @return {CommonClient}
*/
constructor(webSocketFactory, address = "ws://localhost:8080", {
autoconnect = true,
reconnect = true,
reconnect_interval = 1e3,
max_reconnects = 5,
...rest_options
} = {}, generate_request_id, dataPack) {
super();
this.webSocketFactory = webSocketFactory;
this.queue = {};
this.rpc_id = 0;
this.address = address;
this.autoconnect = autoconnect;
this.ready = false;
this.reconnect = reconnect;
this.reconnect_timer_id = void 0;
this.reconnect_interval = reconnect_interval;
this.max_reconnects = max_reconnects;
this.rest_options = rest_options;
this.current_reconnects = 0;
this.generate_request_id = generate_request_id || (() => typeof this.rpc_id === "number" ? ++this.rpc_id : Number(this.rpc_id) + 1);
if (!dataPack) this.dataPack = new DefaultDataPack();
else this.dataPack = dataPack;
if (this.autoconnect)
this._connect(this.address, {
autoconnect: this.autoconnect,
reconnect: this.reconnect,
reconnect_interval: this.reconnect_interval,
max_reconnects: this.max_reconnects,
...this.rest_options
});
}
/**
* Connects to a defined server if not connected already.
* @method
* @return {Undefined}
*/
connect() {
if (this.socket) return;
this._connect(this.address, {
autoconnect: this.autoconnect,
reconnect: this.reconnect,
reconnect_interval: this.reconnect_interval,
max_reconnects: this.max_reconnects,
...this.rest_options
});
}
/**
* Calls a registered RPC method on server.
* @method
* @param {String} method - RPC method name
* @param {Object|Array} params - optional method parameters
* @param {Number} timeout - RPC reply timeout value
* @param {Object} ws_opts - options passed to ws
* @return {Promise}
*/
call(method, params, timeout, ws_opts) {
if (!ws_opts && "object" === typeof timeout) {
ws_opts = timeout;
timeout = null;
}
return new Promise((resolve, reject) => {
if (!this.ready) return reject(new Error("socket not ready"));
const rpc_id = this.generate_request_id(method, params);
const message = {
jsonrpc: "2.0",
method,
params: params || void 0,
id: rpc_id
};
this.socket.send(this.dataPack.encode(message), ws_opts, (error) => {
if (error) return reject(error);
this.queue[rpc_id] = { promise: [resolve, reject] };
if (timeout) {
this.queue[rpc_id].timeout = setTimeout(() => {
delete this.queue[rpc_id];
reject(new Error("reply timeout"));
}, timeout);
}
});
});
}
/**
* Logins with the other side of the connection.
* @method
* @param {Object} params - Login credentials object
* @return {Promise}
*/
async login(params) {
const resp = await this.call("rpc.login", params);
if (!resp) throw new Error("authentication failed");
return resp;
}
/**
* Fetches a list of client's methods registered on server.
* @method
* @return {Array}
*/
async listMethods() {
return await this.call("__listMethods");
}
/**
* Sends a JSON-RPC 2.0 notification to server.
* @method
* @param {String} method - RPC method name
* @param {Object} params - optional method parameters
* @return {Promise}
*/
notify(method, params) {
return new Promise((resolve, reject) => {
if (!this.ready) return reject(new Error("socket not ready"));
const message = {
jsonrpc: "2.0",
method,
params
};
this.socket.send(this.dataPack.encode(message), (error) => {
if (error) return reject(error);
resolve();
});
});
}
/**
* Subscribes for a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
async subscribe(event) {
if (typeof event === "string") event = [event];
const result = await this.call("rpc.on", event);
if (typeof event === "string" && result[event] !== "ok")
throw new Error(
"Failed subscribing to an event '" + event + "' with: " + result[event]
);
return result;
}
/**
* Unsubscribes from a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
async unsubscribe(event) {
if (typeof event === "string") event = [event];
const result = await this.call("rpc.off", event);
if (typeof event === "string" && result[event] !== "ok")
throw new Error("Failed unsubscribing from an event with: " + result);
return result;
}
/**
* Closes a WebSocket connection gracefully.
* @method
* @param {Number} code - socket close code
* @param {String} data - optional data to be sent before closing
* @return {Undefined}
*/
close(code, data) {
if (this.socket) this.socket.close(code || 1e3, data);
}
/**
* Enable / disable automatic reconnection.
* @method
* @param {Boolean} reconnect - enable / disable reconnection
* @return {Undefined}
*/
setAutoReconnect(reconnect) {
this.reconnect = reconnect;
}
/**
* Set the interval between reconnection attempts.
* @method
* @param {Number} interval - reconnection interval in milliseconds
* @return {Undefined}
*/
setReconnectInterval(interval) {
this.reconnect_interval = interval;
}
/**
* Set the maximum number of reconnection attempts.
* @method
* @param {Number} max_reconnects - maximum reconnection attempts
* @return {Undefined}
*/
setMaxReconnects(max_reconnects) {
this.max_reconnects = max_reconnects;
}
/**
* Get the current number of reconnection attempts made.
* @method
* @return {Number} current reconnection attempts
*/
getCurrentReconnects() {
return this.current_reconnects;
}
/**
* Get the maximum number of reconnection attempts.
* @method
* @return {Number} maximum reconnection attempts
*/
getMaxReconnects() {
return this.max_reconnects;
}
/**
* Check if the client is currently attempting to reconnect.
* @method
* @return {Boolean} true if reconnection is in progress
*/
isReconnecting() {
return this.reconnect_timer_id !== void 0;
}
/**
* Check if the client will attempt to reconnect on the next close event.
* @method
* @return {Boolean} true if reconnection will be attempted
*/
willReconnect() {
return this.reconnect && (this.max_reconnects === 0 || this.current_reconnects < this.max_reconnects);
}
/**
* Connection/Message handler.
* @method
* @private
* @param {String} address - WebSocket API address
* @param {Object} options - ws options object
* @return {Undefined}
*/
_connect(address, options) {
clearTimeout(this.reconnect_timer_id);
this.socket = this.webSocketFactory(address, options);
this.socket.addEventListener("open", () => {
this.ready = true;
this.emit("open");
this.current_reconnects = 0;
});
this.socket.addEventListener("message", ({ data: message }) => {
if (message instanceof ArrayBuffer)
message = Buffer.from(message).toString();
try {
message = this.dataPack.decode(message);
} catch (_error) {
return;
}
if (message.notification && this.listeners(message.notification).length) {
if (!Object.keys(message.params).length)
return this.emit(message.notification);
const args = [message.notification];
if (message.params.constructor === Object) args.push(message.params);
else
for (let i = 0; i < message.params.length; i++)
args.push(message.params[i]);
return Promise.resolve().then(() => {
this.emit.apply(this, args);
});
}
if (!this.queue[message.id]) {
if (message.method) {
return Promise.resolve().then(() => {
this.emit(message.method, message?.params);
});
}
return;
}
if ("error" in message === "result" in message)
this.queue[message.id].promise[1](
new Error(
'Server response malformed. Response must include either "result" or "error", but not both.'
)
);
if (this.queue[message.id].timeout)
clearTimeout(this.queue[message.id].timeout);
if (message.error) this.queue[message.id].promise[1](message.error);
else this.queue[message.id].promise[0](message.result);
delete this.queue[message.id];
});
this.socket.addEventListener("error", (error) => this.emit("error", error));
this.socket.addEventListener("close", ({ code, reason }) => {
if (this.ready)
setTimeout(() => this.emit("close", code, reason), 0);
this.ready = false;
this.socket = void 0;
if (code === 1e3) return;
this.current_reconnects++;
if (this.reconnect && (this.max_reconnects > this.current_reconnects || this.max_reconnects === 0))
this.reconnect_timer_id = setTimeout(
() => this._connect(address, options),
this.reconnect_interval
);
else if (this.reconnect && this.max_reconnects > 0 && this.current_reconnects >= this.max_reconnects) {
setTimeout(() => this.emit("max_reconnects_reached", code, reason), 1);
}
});
}
};
var Server = class extends EventEmitter {
namespaces;
dataPack;
wss;
/**
* Instantiate a Server class.
* @constructor
* @param {Object} options - ws constructor's parameters with rpc
* @param {DataPack} dataPack - data pack contains encoder and decoder
* @return {Server} - returns a new Server instance
*/
constructor(options, dataPack) {
super();
this.namespaces = {};
if (!dataPack) this.dataPack = new DefaultDataPack();
else this.dataPack = dataPack;
this.wss = new WebSocketServer(options);
this.wss.on("listening", () => this.emit("listening"));
this.wss.on("connection", (socket, request) => {
const u = url.parse(request.url, true);
const ns = u.pathname;
if (u.query.socket_id) socket._id = u.query.socket_id;
else socket._id = v1();
socket["_authenticated"] = false;
socket.on("error", (error) => this.emit("socket-error", socket, error));
socket.on("close", () => {
this.namespaces[ns].clients.delete(socket._id);
for (const event of Object.keys(this.namespaces[ns].events)) {
const index = this.namespaces[ns].events[event].sockets.indexOf(
socket._id
);
if (index >= 0)
this.namespaces[ns].events[event].sockets.splice(index, 1);
}
this.emit("disconnection", socket);
});
if (!this.namespaces[ns]) this._generateNamespace(ns);
this.namespaces[ns].clients.set(socket._id, socket);
this.emit("connection", socket, request);
return this._handleRPC(socket, ns);
});
this.wss.on("error", (error) => this.emit("error", error));
}
/**
* Registers an RPC method.
* @method
* @param {String} name - method name
* @param {Function} fn - a callee function
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Object} - returns an IMethod object
*/
register(name, fn, ns = "/") {
if (!this.namespaces[ns]) this._generateNamespace(ns);
this.namespaces[ns].rpc_methods[name] = {
fn,
protected: false
};
return {
protected: () => this._makeProtectedMethod(name, ns),
public: () => this._makePublicMethod(name, ns)
};
}
/**
* Sets an auth method.
* @method
* @param {Function} fn - an arbitrary auth method
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Undefined}
*/
setAuth(fn, ns = "/") {
this.register("rpc.login", fn, ns);
}
/**
* Marks an RPC method as protected.
* @method
* @param {String} name - method name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
_makeProtectedMethod(name, ns = "/") {
this.namespaces[ns].rpc_methods[name].protected = true;
}
/**
* Marks an RPC method as public.
* @method
* @param {String} name - method name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
_makePublicMethod(name, ns = "/") {
this.namespaces[ns].rpc_methods[name].protected = false;
}
/**
* Marks an event as protected.
* @method
* @param {String} name - event name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
_makeProtectedEvent(name, ns = "/") {
this.namespaces[ns].events[name].protected = true;
}
/**
* Marks an event as public.
* @method
* @param {String} name - event name
* @param {String} ns - namespace identifier
* @return {Undefined}
*/
_makePublicEvent(name, ns = "/") {
this.namespaces[ns].events[name].protected = false;
}
/**
* Removes a namespace and closes all connections
* @method
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Undefined}
*/
closeNamespace(ns) {
const namespace = this.namespaces[ns];
if (namespace) {
delete namespace.rpc_methods;
delete namespace.events;
for (const socket of namespace.clients.values()) socket.close();
delete this.namespaces[ns];
}
}
/**
* Creates a new event that can be emitted to clients.
* @method
* @param {String} name - event name
* @param {String} ns - namespace identifier
* @throws {TypeError}
* @return {Object} - returns an IEvent object
*/
event(name, ns = "/") {
if (!this.namespaces[ns]) this._generateNamespace(ns);
else {
const index = this.namespaces[ns].events[name];
if (index !== void 0)
throw new Error(`Already registered event ${ns}${name}`);
}
this.namespaces[ns].events[name] = {
sockets: [],
protected: false
};
this.on(name, (...params) => {
if (params.length === 1 && params[0] instanceof Object)
params = params[0];
for (const socket_id of this.namespaces[ns].events[name].sockets) {
const socket = this.namespaces[ns].clients.get(socket_id);
if (!socket) continue;
socket.send(
this.dataPack.encode({
notification: name,
params
})
);
}
});
return {
protected: () => this._makeProtectedEvent(name, ns),
public: () => this._makePublicEvent(name, ns)
};
}
/**
* Returns a requested namespace object
* @method
* @param {String} name - namespace identifier
* @throws {TypeError}
* @return {Object} - namespace object
*/
of(name) {
if (!this.namespaces[name]) this._generateNamespace(name);
const self = this;
return {
// self.register convenience method
register(fn_name, fn) {
if (arguments.length !== 2)
throw new Error("must provide exactly two arguments");
if (typeof fn_name !== "string")
throw new Error("name must be a string");
if (typeof fn !== "function")
throw new Error("handler must be a function");
return self.register(fn_name, fn, name);
},
// self.event convenience method
event(ev_name) {
if (arguments.length !== 1)
throw new Error("must provide exactly one argument");
if (typeof ev_name !== "string")
throw new Error("name must be a string");
return self.event(ev_name, name);
},
// self.eventList convenience method
get eventList() {
return Object.keys(self.namespaces[name].events);
},
/**
* Emits a specified event to this namespace.
* @inner
* @method
* @param {String} event - event name
* @param {Array} params - event parameters
* @return {Undefined}
*/
emit(event, ...params) {
const nsEvent = self.namespaces[name].events[event];
if (nsEvent)
for (const socket_id of nsEvent.sockets) {
const socket = self.namespaces[name].clients.get(socket_id);
if (!socket) continue;
socket.send(
self.dataPack.encode({
notification: event,
params
})
);
}
},
/**
* Returns a name of this namespace.
* @inner
* @method
* @kind constant
* @return {String}
*/
get name() {
return name;
},
/**
* Returns a hash of websocket objects connected to this namespace.
* @inner
* @method
* @return {Object}
*/
connected() {
const socket_ids = [...self.namespaces[name].clients.keys()];
return socket_ids.reduce(
(acc, curr) => ({
...acc,
[curr]: self.namespaces[name].clients.get(curr)
}),
{}
);
},
/**
* Returns a list of client unique identifiers connected to this namespace.
* @inner
* @method
* @return {Array}
*/
clients() {
return self.namespaces[name];
}
};
}
/**
* Lists all created events in a given namespace. Defaults to "/".
* @method
* @param {String} ns - namespaces identifier
* @readonly
* @return {Array} - returns a list of created events
*/
eventList(ns = "/") {
if (!this.namespaces[ns]) return [];
return Object.keys(this.namespaces[ns].events);
}
/**
* Creates a JSON-RPC 2.0 compliant error
* @method
* @param {Number} code - indicates the error type that occurred
* @param {String} message - provides a short description of the error
* @param {String|Object} data - details containing additional information about the error
* @return {Object}
*/
createError(code, message, data) {
return {
code,
message,
data: data || null
};
}
/**
* Closes the server and terminates all clients.
* @method
* @return {Promise}
*/
close() {
return new Promise((resolve, reject) => {
try {
this.wss.close();
this.emit("close");
resolve();
} catch (error) {
reject(error);
}
});
}
/**
* Handles all WebSocket JSON RPC 2.0 requests.
* @private
* @param {Object} socket - ws socket instance
* @param {String} ns - namespaces identifier
* @return {Undefined}
*/
_handleRPC(socket, ns = "/") {
socket.on("message", async (data) => {
const msg_options = {};
if (data instanceof ArrayBuffer) {
msg_options.binary = true;
data = Buffer.from(data).toString();
}
if (socket.readyState !== 1) return;
let parsedData;
try {
parsedData = this.dataPack.decode(data);
} catch (error) {
return socket.send(
this.dataPack.encode({
jsonrpc: "2.0",
error: createError(-32700, error.toString()),
id: null
}),
msg_options
);
}
if (Array.isArray(parsedData)) {
if (!parsedData.length)
return socket.send(
this.dataPack.encode({
jsonrpc: "2.0",
error: createError(-32600, "Invalid array"),
id: null
}),
msg_options
);
const responses = [];
for (const message of parsedData) {
const response2 = await this._runMethod(message, socket._id, ns);
if (!response2) continue;
responses.push(response2);
}
if (!responses.length) return;
return socket.send(this.dataPack.encode(responses), msg_options);
}
const response = await this._runMethod(parsedData, socket._id, ns);
if (!response) return;
return socket.send(this.dataPack.encode(response), msg_options);
});
}
/**
* Runs a defined RPC method.
* @private
* @param {Object} message - a message received
* @param {Object} socket_id - user's socket id
* @param {String} ns - namespaces identifier
* @return {Object|undefined}
*/
async _runMethod(message, socket_id, ns = "/") {
if (typeof message !== "object" || message === null)
return {
jsonrpc: "2.0",
error: createError(-32600),
id: null
};
if (message.jsonrpc !== "2.0")
return {
jsonrpc: "2.0",
error: createError(-32600, "Invalid JSON RPC version"),
id: message.id || null
};
if (!message.method)
return {
jsonrpc: "2.0",
error: createError(-32602, "Method not specified"),
id: message.id || null
};
if (typeof message.method !== "string")
return {
jsonrpc: "2.0",
error: createError(-32600, "Invalid method name"),
id: message.id || null
};
if (message.params && typeof message.params === "string")
return {
jsonrpc: "2.0",
error: createError(-32600),
id: message.id || null
};
if (message.method === "rpc.on") {
if (!message.params)
return {
jsonrpc: "2.0",
error: createError(-32e3),
id: message.id || null
};
const results = {};
const event_names = Object.keys(this.namespaces[ns].events);
for (const name of message.params) {
const index = event_names.indexOf(name);
const namespace = this.namespaces[ns];
if (index === -1) {
results[name] = "provided event invalid";
continue;
}
if (namespace.events[event_names[index]].protected === true && namespace.clients.get(socket_id)["_authenticated"] === false) {
return {
jsonrpc: "2.0",
error: createError(-32606),
id: message.id || null
};
}
const socket_index = namespace.events[event_names[index]].sockets.indexOf(socket_id);
if (socket_index >= 0) {
results[name] = "socket has already been subscribed to event";
continue;
}
namespace.events[event_names[index]].sockets.push(socket_id);
results[name] = "ok";
}
return {
jsonrpc: "2.0",
result: results,
id: message.id || null
};
} else if (message.method === "rpc.off") {
if (!message.params)
return {
jsonrpc: "2.0",
error: createError(-32e3),
id: message.id || null
};
const results = {};
for (const name of message.params) {
if (!this.namespaces[ns].events[name]) {
results[name] = "provided event invalid";
continue;
}
const index = this.namespaces[ns].events[name].sockets.indexOf(socket_id);
if (index === -1) {
results[name] = "not subscribed";
continue;
}
this.namespaces[ns].events[name].sockets.splice(index, 1);
results[name] = "ok";
}
return {
jsonrpc: "2.0",
result: results,
id: message.id || null
};
} else if (message.method === "rpc.login") {
if (!message.params)
return {
jsonrpc: "2.0",
error: createError(-32604),
id: message.id || null
};
}
if (!this.namespaces[ns].rpc_methods[message.method]) {
return {
jsonrpc: "2.0",
error: createError(-32601),
id: message.id || null
};
}
let response = null;
if (this.namespaces[ns].rpc_methods[message.method].protected === true && this.namespaces[ns].clients.get(socket_id)["_authenticated"] === false) {
return {
jsonrpc: "2.0",
error: createError(-32605),
id: message.id || null
};
}
try {
response = await this.namespaces[ns].rpc_methods[message.method].fn(
message.params,
socket_id
);
} catch (error) {
if (!message.id) return;
if (error instanceof Error)
return {
jsonrpc: "2.0",
error: {
code: -32e3,
message: error.name,
data: error.message
},
id: message.id
};
return {
jsonrpc: "2.0",
error,
id: message.id
};
}
if (!message.id) return;
if (message.method === "rpc.login" && response === true) {
const s = this.namespaces[ns].clients.get(socket_id);
if (s) {
s["_authenticated"] = true;
this.namespaces[ns].clients.set(socket_id, s);
}
}
return {
jsonrpc: "2.0",
result: response,
id: message.id
};
}
/**
* Generate a new namespace store.
* Also preregister some special namespace methods.
* @private
* @param {String} name - namespaces identifier
* @return {undefined}
*/
_generateNamespace(name) {
this.namespaces[name] = {
rpc_methods: {
__listMethods: {
fn: () => Object.keys(this.namespaces[name].rpc_methods),
protected: false
}
},
clients: /* @__PURE__ */ new Map(),
events: {}
};
}
};
var RPC_ERRORS = /* @__PURE__ */ new Map([
[-32e3, "Event not provided"],
[-32600, "Invalid Request"],
[-32601, "Method not found"],
[-32602, "Invalid params"],
[-32603, "Internal error"],
[-32604, "Params not found"],
[-32605, "Method forbidden"],
[-32606, "Event forbidden"],
[-32700, "Parse error"]
]);
function createError(code, details) {
const error = {
code,
message: RPC_ERRORS.get(code) || "Internal Server Error"
};
if (details) error["data"] = details;
return error;
}
// src/index.ts
var Client = class extends CommonClient {
constructor(address = "ws://localhost:8080", {
autoconnect = true,
reconnect = true,
reconnect_interval = 1e3,
max_reconnects = 5,
...rest_options
} = {}, generate_request_id) {
super(
WebSocket,
address,
{
autoconnect,
reconnect,
reconnect_interval,
max_reconnects,
...rest_options
},
generate_request_id
);
}
};
export { Client, CommonClient, DefaultDataPack, Server, WebSocket, createError };
//# sourceMappingURL=index.mjs.map
//# sourceMappingURL=index.mjs.map

1
node_modules/rpc-websockets/dist/index.mjs.map generated vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,73 @@
# Authors
#### Ordered by first contribution.
- Romain Beauxis (toots@rastageeks.org)
- Tobias Koppers (tobias.koppers@googlemail.com)
- Janus (ysangkok@gmail.com)
- Rainer Dreyer (rdrey1@gmail.com)
- Tõnis Tiigi (tonistiigi@gmail.com)
- James Halliday (mail@substack.net)
- Michael Williamson (mike@zwobble.org)
- elliottcable (github@elliottcable.name)
- rafael (rvalle@livelens.net)
- Andrew Kelley (superjoe30@gmail.com)
- Andreas Madsen (amwebdk@gmail.com)
- Mike Brevoort (mike.brevoort@pearson.com)
- Brian White (mscdex@mscdex.net)
- Feross Aboukhadijeh (feross@feross.org)
- Ruben Verborgh (ruben@verborgh.org)
- eliang (eliang.cs@gmail.com)
- Jesse Tane (jesse.tane@gmail.com)
- Alfonso Boza (alfonso@cloud.com)
- Mathias Buus (mathiasbuus@gmail.com)
- Devon Govett (devongovett@gmail.com)
- Daniel Cousens (github@dcousens.com)
- Joseph Dykstra (josephdykstra@gmail.com)
- Parsha Pourkhomami (parshap+git@gmail.com)
- Damjan Košir (damjan.kosir@gmail.com)
- daverayment (dave.rayment@gmail.com)
- kawanet (u-suke@kawa.net)
- Linus Unnebäck (linus@folkdatorn.se)
- Nolan Lawson (nolan.lawson@gmail.com)
- Calvin Metcalf (calvin.metcalf@gmail.com)
- Koki Takahashi (hakatasiloving@gmail.com)
- Guy Bedford (guybedford@gmail.com)
- Jan Schär (jscissr@gmail.com)
- RaulTsc (tomescu.raul@gmail.com)
- Matthieu Monsch (monsch@alum.mit.edu)
- Dan Ehrenberg (littledan@chromium.org)
- Kirill Fomichev (fanatid@ya.ru)
- Yusuke Kawasaki (u-suke@kawa.net)
- DC (dcposch@dcpos.ch)
- John-David Dalton (john.david.dalton@gmail.com)
- adventure-yunfei (adventure030@gmail.com)
- Emil Bay (github@tixz.dk)
- Sam Sudar (sudar.sam@gmail.com)
- Volker Mische (volker.mische@gmail.com)
- David Walton (support@geekstocks.com)
- Сковорода Никита Андреевич (chalkerx@gmail.com)
- greenkeeper[bot] (greenkeeper[bot]@users.noreply.github.com)
- ukstv (sergey.ukustov@machinomy.com)
- Renée Kooi (renee@kooi.me)
- ranbochen (ranbochen@qq.com)
- Vladimir Borovik (bobahbdb@gmail.com)
- greenkeeper[bot] (23040076+greenkeeper[bot]@users.noreply.github.com)
- kumavis (aaron@kumavis.me)
- Sergey Ukustov (sergey.ukustov@machinomy.com)
- Fei Liu (liu.feiwood@gmail.com)
- Blaine Bublitz (blaine.bublitz@gmail.com)
- clement (clement@seald.io)
- Koushik Dutta (koushd@gmail.com)
- Jordan Harband (ljharb@gmail.com)
- Niklas Mischkulnig (mischnic@users.noreply.github.com)
- Nikolai Vavilov (vvnicholas@gmail.com)
- Fedor Nezhivoi (gyzerok@users.noreply.github.com)
- shuse2 (shus.toda@gmail.com)
- Peter Newman (peternewman@users.noreply.github.com)
- mathmakgakpak (44949126+mathmakgakpak@users.noreply.github.com)
- jkkang (jkkang@smartauth.kr)
- Deklan Webster (deklanw@gmail.com)
- Martin Heidegger (martin.heidegger@gmail.com)
#### Generated by bin/update-authors.sh.

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Feross Aboukhadijeh, and other contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,410 @@
# buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url]
[travis-image]: https://img.shields.io/travis/feross/buffer/master.svg
[travis-url]: https://travis-ci.org/feross/buffer
[npm-image]: https://img.shields.io/npm/v/buffer.svg
[npm-url]: https://npmjs.org/package/buffer
[downloads-image]: https://img.shields.io/npm/dm/buffer.svg
[downloads-url]: https://npmjs.org/package/buffer
[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg
[standard-url]: https://standardjs.com
#### The buffer module from [node.js](https://nodejs.org/), for the browser.
[![saucelabs][saucelabs-image]][saucelabs-url]
[saucelabs-image]: https://saucelabs.com/browser-matrix/buffer.svg
[saucelabs-url]: https://saucelabs.com/u/buffer
With [browserify](http://browserify.org), simply `require('buffer')` or use the `Buffer` global and you will get this module.
The goal is to provide an API that is 100% identical to
[node's Buffer API](https://nodejs.org/api/buffer.html). Read the
[official docs](https://nodejs.org/api/buffer.html) for the full list of properties,
instance methods, and class methods that are supported.
## features
- Manipulate binary data like a boss, in all browsers!
- Super fast. Backed by Typed Arrays (`Uint8Array`/`ArrayBuffer`, not `Object`)
- Extremely small bundle size (**6.75KB minified + gzipped**, 51.9KB with comments)
- Excellent browser support (Chrome, Firefox, Edge, Safari 11+, iOS 11+, Android, etc.)
- Preserves Node API exactly, with one minor difference (see below)
- Square-bracket `buf[4]` notation works!
- Does not modify any browser prototypes or put anything on `window`
- Comprehensive test suite (including all buffer tests from node.js core)
## install
To use this module directly (without browserify), install it:
```bash
npm install buffer
```
This module was previously called **native-buffer-browserify**, but please use **buffer**
from now on.
If you do not use a bundler, you can use the [standalone script](https://bundle.run/buffer).
## usage
The module's API is identical to node's `Buffer` API. Read the
[official docs](https://nodejs.org/api/buffer.html) for the full list of properties,
instance methods, and class methods that are supported.
As mentioned above, `require('buffer')` or use the `Buffer` global with
[browserify](http://browserify.org) and this module will automatically be included
in your bundle. Almost any npm module will work in the browser, even if it assumes that
the node `Buffer` API will be available.
To depend on this module explicitly (without browserify), require it like this:
```js
var Buffer = require('buffer/').Buffer // note: the trailing slash is important!
```
To require this module explicitly, use `require('buffer/')` which tells the node.js module
lookup algorithm (also used by browserify) to use the **npm module** named `buffer`
instead of the **node.js core** module named `buffer`!
## how does it work?
The Buffer constructor returns instances of `Uint8Array` that have their prototype
changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of `Uint8Array`,
so the returned instances will have all the node `Buffer` methods and the
`Uint8Array` methods. Square bracket notation works as expected -- it returns a
single octet.
The `Uint8Array` prototype remains unmodified.
## tracking the latest node api
This module tracks the Buffer API in the latest (unstable) version of node.js. The Buffer
API is considered **stable** in the
[node stability index](https://nodejs.org/docs/latest/api/documentation.html#documentation_stability_index),
so it is unlikely that there will ever be breaking changes.
Nonetheless, when/if the Buffer API changes in node, this module's API will change
accordingly.
## related packages
- [`buffer-reverse`](https://www.npmjs.com/package/buffer-reverse) - Reverse a buffer
- [`buffer-xor`](https://www.npmjs.com/package/buffer-xor) - Bitwise xor a buffer
- [`is-buffer`](https://www.npmjs.com/package/is-buffer) - Determine if an object is a Buffer without including the whole `Buffer` package
## conversion packages
### convert typed array to buffer
Use [`typedarray-to-buffer`](https://www.npmjs.com/package/typedarray-to-buffer) to convert any kind of typed array to a `Buffer`. Does not perform a copy, so it's super fast.
### convert buffer to typed array
`Buffer` is a subclass of `Uint8Array` (which is a typed array). So there is no need to explicitly convert to typed array. Just use the buffer as a `Uint8Array`.
### convert blob to buffer
Use [`blob-to-buffer`](https://www.npmjs.com/package/blob-to-buffer) to convert a `Blob` to a `Buffer`.
### convert buffer to blob
To convert a `Buffer` to a `Blob`, use the `Blob` constructor:
```js
var blob = new Blob([ buffer ])
```
Optionally, specify a mimetype:
```js
var blob = new Blob([ buffer ], { type: 'text/html' })
```
### convert arraybuffer to buffer
To convert an `ArrayBuffer` to a `Buffer`, use the `Buffer.from` function. Does not perform a copy, so it's super fast.
```js
var buffer = Buffer.from(arrayBuffer)
```
### convert buffer to arraybuffer
To convert a `Buffer` to an `ArrayBuffer`, use the `.buffer` property (which is present on all `Uint8Array` objects):
```js
var arrayBuffer = buffer.buffer.slice(
buffer.byteOffset, buffer.byteOffset + buffer.byteLength
)
```
Alternatively, use the [`to-arraybuffer`](https://www.npmjs.com/package/to-arraybuffer) module.
## performance
See perf tests in `/perf`.
`BrowserBuffer` is the browser `buffer` module (this repo). `Uint8Array` is included as a
sanity check (since `BrowserBuffer` uses `Uint8Array` under the hood, `Uint8Array` will
always be at least a bit faster). Finally, `NodeBuffer` is the node.js buffer module,
which is included to compare against.
NOTE: Performance has improved since these benchmarks were taken. PR welcome to update the README.
### Chrome 38
| Method | Operations | Accuracy | Sampled | Fastest |
|:-------|:-----------|:---------|:--------|:-------:|
| BrowserBuffer#bracket-notation | 11,457,464 ops/sec | ±0.86% | 66 | ✓ |
| Uint8Array#bracket-notation | 10,824,332 ops/sec | ±0.74% | 65 | |
| | | | |
| BrowserBuffer#concat | 450,532 ops/sec | ±0.76% | 68 | |
| Uint8Array#concat | 1,368,911 ops/sec | ±1.50% | 62 | ✓ |
| | | | |
| BrowserBuffer#copy(16000) | 903,001 ops/sec | ±0.96% | 67 | |
| Uint8Array#copy(16000) | 1,422,441 ops/sec | ±1.04% | 66 | ✓ |
| | | | |
| BrowserBuffer#copy(16) | 11,431,358 ops/sec | ±0.46% | 69 | |
| Uint8Array#copy(16) | 13,944,163 ops/sec | ±1.12% | 68 | ✓ |
| | | | |
| BrowserBuffer#new(16000) | 106,329 ops/sec | ±6.70% | 44 | |
| Uint8Array#new(16000) | 131,001 ops/sec | ±2.85% | 31 | ✓ |
| | | | |
| BrowserBuffer#new(16) | 1,554,491 ops/sec | ±1.60% | 65 | |
| Uint8Array#new(16) | 6,623,930 ops/sec | ±1.66% | 65 | ✓ |
| | | | |
| BrowserBuffer#readDoubleBE | 112,830 ops/sec | ±0.51% | 69 | ✓ |
| DataView#getFloat64 | 93,500 ops/sec | ±0.57% | 68 | |
| | | | |
| BrowserBuffer#readFloatBE | 146,678 ops/sec | ±0.95% | 68 | ✓ |
| DataView#getFloat32 | 99,311 ops/sec | ±0.41% | 67 | |
| | | | |
| BrowserBuffer#readUInt32LE | 843,214 ops/sec | ±0.70% | 69 | ✓ |
| DataView#getUint32 | 103,024 ops/sec | ±0.64% | 67 | |
| | | | |
| BrowserBuffer#slice | 1,013,941 ops/sec | ±0.75% | 67 | |
| Uint8Array#subarray | 1,903,928 ops/sec | ±0.53% | 67 | ✓ |
| | | | |
| BrowserBuffer#writeFloatBE | 61,387 ops/sec | ±0.90% | 67 | |
| DataView#setFloat32 | 141,249 ops/sec | ±0.40% | 66 | ✓ |
### Firefox 33
| Method | Operations | Accuracy | Sampled | Fastest |
|:-------|:-----------|:---------|:--------|:-------:|
| BrowserBuffer#bracket-notation | 20,800,421 ops/sec | ±1.84% | 60 | |
| Uint8Array#bracket-notation | 20,826,235 ops/sec | ±2.02% | 61 | ✓ |
| | | | |
| BrowserBuffer#concat | 153,076 ops/sec | ±2.32% | 61 | |
| Uint8Array#concat | 1,255,674 ops/sec | ±8.65% | 52 | ✓ |
| | | | |
| BrowserBuffer#copy(16000) | 1,105,312 ops/sec | ±1.16% | 63 | |
| Uint8Array#copy(16000) | 1,615,911 ops/sec | ±0.55% | 66 | ✓ |
| | | | |
| BrowserBuffer#copy(16) | 16,357,599 ops/sec | ±0.73% | 68 | |
| Uint8Array#copy(16) | 31,436,281 ops/sec | ±1.05% | 68 | ✓ |
| | | | |
| BrowserBuffer#new(16000) | 52,995 ops/sec | ±6.01% | 35 | |
| Uint8Array#new(16000) | 87,686 ops/sec | ±5.68% | 45 | ✓ |
| | | | |
| BrowserBuffer#new(16) | 252,031 ops/sec | ±1.61% | 66 | |
| Uint8Array#new(16) | 8,477,026 ops/sec | ±0.49% | 68 | ✓ |
| | | | |
| BrowserBuffer#readDoubleBE | 99,871 ops/sec | ±0.41% | 69 | |
| DataView#getFloat64 | 285,663 ops/sec | ±0.70% | 68 | ✓ |
| | | | |
| BrowserBuffer#readFloatBE | 115,540 ops/sec | ±0.42% | 69 | |
| DataView#getFloat32 | 288,722 ops/sec | ±0.82% | 68 | ✓ |
| | | | |
| BrowserBuffer#readUInt32LE | 633,926 ops/sec | ±1.08% | 67 | ✓ |
| DataView#getUint32 | 294,808 ops/sec | ±0.79% | 64 | |
| | | | |
| BrowserBuffer#slice | 349,425 ops/sec | ±0.46% | 69 | |
| Uint8Array#subarray | 5,965,819 ops/sec | ±0.60% | 65 | ✓ |
| | | | |
| BrowserBuffer#writeFloatBE | 59,980 ops/sec | ±0.41% | 67 | |
| DataView#setFloat32 | 317,634 ops/sec | ±0.63% | 68 | ✓ |
### Safari 8
| Method | Operations | Accuracy | Sampled | Fastest |
|:-------|:-----------|:---------|:--------|:-------:|
| BrowserBuffer#bracket-notation | 10,279,729 ops/sec | ±2.25% | 56 | ✓ |
| Uint8Array#bracket-notation | 10,030,767 ops/sec | ±2.23% | 59 | |
| | | | |
| BrowserBuffer#concat | 144,138 ops/sec | ±1.38% | 65 | |
| Uint8Array#concat | 4,950,764 ops/sec | ±1.70% | 63 | ✓ |
| | | | |
| BrowserBuffer#copy(16000) | 1,058,548 ops/sec | ±1.51% | 64 | |
| Uint8Array#copy(16000) | 1,409,666 ops/sec | ±1.17% | 65 | ✓ |
| | | | |
| BrowserBuffer#copy(16) | 6,282,529 ops/sec | ±1.88% | 58 | |
| Uint8Array#copy(16) | 11,907,128 ops/sec | ±2.87% | 58 | ✓ |
| | | | |
| BrowserBuffer#new(16000) | 101,663 ops/sec | ±3.89% | 57 | |
| Uint8Array#new(16000) | 22,050,818 ops/sec | ±6.51% | 46 | ✓ |
| | | | |
| BrowserBuffer#new(16) | 176,072 ops/sec | ±2.13% | 64 | |
| Uint8Array#new(16) | 24,385,731 ops/sec | ±5.01% | 51 | ✓ |
| | | | |
| BrowserBuffer#readDoubleBE | 41,341 ops/sec | ±1.06% | 67 | |
| DataView#getFloat64 | 322,280 ops/sec | ±0.84% | 68 | ✓ |
| | | | |
| BrowserBuffer#readFloatBE | 46,141 ops/sec | ±1.06% | 65 | |
| DataView#getFloat32 | 337,025 ops/sec | ±0.43% | 69 | ✓ |
| | | | |
| BrowserBuffer#readUInt32LE | 151,551 ops/sec | ±1.02% | 66 | |
| DataView#getUint32 | 308,278 ops/sec | ±0.94% | 67 | ✓ |
| | | | |
| BrowserBuffer#slice | 197,365 ops/sec | ±0.95% | 66 | |
| Uint8Array#subarray | 9,558,024 ops/sec | ±3.08% | 58 | ✓ |
| | | | |
| BrowserBuffer#writeFloatBE | 17,518 ops/sec | ±1.03% | 63 | |
| DataView#setFloat32 | 319,751 ops/sec | ±0.48% | 68 | ✓ |
### Node 0.11.14
| Method | Operations | Accuracy | Sampled | Fastest |
|:-------|:-----------|:---------|:--------|:-------:|
| BrowserBuffer#bracket-notation | 10,489,828 ops/sec | ±3.25% | 90 | |
| Uint8Array#bracket-notation | 10,534,884 ops/sec | ±0.81% | 92 | ✓ |
| NodeBuffer#bracket-notation | 10,389,910 ops/sec | ±0.97% | 87 | |
| | | | |
| BrowserBuffer#concat | 487,830 ops/sec | ±2.58% | 88 | |
| Uint8Array#concat | 1,814,327 ops/sec | ±1.28% | 88 | ✓ |
| NodeBuffer#concat | 1,636,523 ops/sec | ±1.88% | 73 | |
| | | | |
| BrowserBuffer#copy(16000) | 1,073,665 ops/sec | ±0.77% | 90 | |
| Uint8Array#copy(16000) | 1,348,517 ops/sec | ±0.84% | 89 | ✓ |
| NodeBuffer#copy(16000) | 1,289,533 ops/sec | ±0.82% | 93 | |
| | | | |
| BrowserBuffer#copy(16) | 12,782,706 ops/sec | ±0.74% | 85 | |
| Uint8Array#copy(16) | 14,180,427 ops/sec | ±0.93% | 92 | ✓ |
| NodeBuffer#copy(16) | 11,083,134 ops/sec | ±1.06% | 89 | |
| | | | |
| BrowserBuffer#new(16000) | 141,678 ops/sec | ±3.30% | 67 | |
| Uint8Array#new(16000) | 161,491 ops/sec | ±2.96% | 60 | |
| NodeBuffer#new(16000) | 292,699 ops/sec | ±3.20% | 55 | ✓ |
| | | | |
| BrowserBuffer#new(16) | 1,655,466 ops/sec | ±2.41% | 82 | |
| Uint8Array#new(16) | 14,399,926 ops/sec | ±0.91% | 94 | ✓ |
| NodeBuffer#new(16) | 3,894,696 ops/sec | ±0.88% | 92 | |
| | | | |
| BrowserBuffer#readDoubleBE | 109,582 ops/sec | ±0.75% | 93 | ✓ |
| DataView#getFloat64 | 91,235 ops/sec | ±0.81% | 90 | |
| NodeBuffer#readDoubleBE | 88,593 ops/sec | ±0.96% | 81 | |
| | | | |
| BrowserBuffer#readFloatBE | 139,854 ops/sec | ±1.03% | 85 | ✓ |
| DataView#getFloat32 | 98,744 ops/sec | ±0.80% | 89 | |
| NodeBuffer#readFloatBE | 92,769 ops/sec | ±0.94% | 93 | |
| | | | |
| BrowserBuffer#readUInt32LE | 710,861 ops/sec | ±0.82% | 92 | |
| DataView#getUint32 | 117,893 ops/sec | ±0.84% | 91 | |
| NodeBuffer#readUInt32LE | 851,412 ops/sec | ±0.72% | 93 | ✓ |
| | | | |
| BrowserBuffer#slice | 1,673,877 ops/sec | ±0.73% | 94 | |
| Uint8Array#subarray | 6,919,243 ops/sec | ±0.67% | 90 | ✓ |
| NodeBuffer#slice | 4,617,604 ops/sec | ±0.79% | 93 | |
| | | | |
| BrowserBuffer#writeFloatBE | 66,011 ops/sec | ±0.75% | 93 | |
| DataView#setFloat32 | 127,760 ops/sec | ±0.72% | 93 | ✓ |
| NodeBuffer#writeFloatBE | 103,352 ops/sec | ±0.83% | 93 | |
### iojs 1.8.1
| Method | Operations | Accuracy | Sampled | Fastest |
|:-------|:-----------|:---------|:--------|:-------:|
| BrowserBuffer#bracket-notation | 10,990,488 ops/sec | ±1.11% | 91 | |
| Uint8Array#bracket-notation | 11,268,757 ops/sec | ±0.65% | 97 | |
| NodeBuffer#bracket-notation | 11,353,260 ops/sec | ±0.83% | 94 | ✓ |
| | | | |
| BrowserBuffer#concat | 378,954 ops/sec | ±0.74% | 94 | |
| Uint8Array#concat | 1,358,288 ops/sec | ±0.97% | 87 | |
| NodeBuffer#concat | 1,934,050 ops/sec | ±1.11% | 78 | ✓ |
| | | | |
| BrowserBuffer#copy(16000) | 894,538 ops/sec | ±0.56% | 84 | |
| Uint8Array#copy(16000) | 1,442,656 ops/sec | ±0.71% | 96 | |
| NodeBuffer#copy(16000) | 1,457,898 ops/sec | ±0.53% | 92 | ✓ |
| | | | |
| BrowserBuffer#copy(16) | 12,870,457 ops/sec | ±0.67% | 95 | |
| Uint8Array#copy(16) | 16,643,989 ops/sec | ±0.61% | 93 | ✓ |
| NodeBuffer#copy(16) | 14,885,848 ops/sec | ±0.74% | 94 | |
| | | | |
| BrowserBuffer#new(16000) | 109,264 ops/sec | ±4.21% | 63 | |
| Uint8Array#new(16000) | 138,916 ops/sec | ±1.87% | 61 | |
| NodeBuffer#new(16000) | 281,449 ops/sec | ±3.58% | 51 | ✓ |
| | | | |
| BrowserBuffer#new(16) | 1,362,935 ops/sec | ±0.56% | 99 | |
| Uint8Array#new(16) | 6,193,090 ops/sec | ±0.64% | 95 | ✓ |
| NodeBuffer#new(16) | 4,745,425 ops/sec | ±1.56% | 90 | |
| | | | |
| BrowserBuffer#readDoubleBE | 118,127 ops/sec | ±0.59% | 93 | ✓ |
| DataView#getFloat64 | 107,332 ops/sec | ±0.65% | 91 | |
| NodeBuffer#readDoubleBE | 116,274 ops/sec | ±0.94% | 95 | |
| | | | |
| BrowserBuffer#readFloatBE | 150,326 ops/sec | ±0.58% | 95 | ✓ |
| DataView#getFloat32 | 110,541 ops/sec | ±0.57% | 98 | |
| NodeBuffer#readFloatBE | 121,599 ops/sec | ±0.60% | 87 | |
| | | | |
| BrowserBuffer#readUInt32LE | 814,147 ops/sec | ±0.62% | 93 | |
| DataView#getUint32 | 137,592 ops/sec | ±0.64% | 90 | |
| NodeBuffer#readUInt32LE | 931,650 ops/sec | ±0.71% | 96 | ✓ |
| | | | |
| BrowserBuffer#slice | 878,590 ops/sec | ±0.68% | 93 | |
| Uint8Array#subarray | 2,843,308 ops/sec | ±1.02% | 90 | |
| NodeBuffer#slice | 4,998,316 ops/sec | ±0.68% | 90 | ✓ |
| | | | |
| BrowserBuffer#writeFloatBE | 65,927 ops/sec | ±0.74% | 93 | |
| DataView#setFloat32 | 139,823 ops/sec | ±0.97% | 89 | ✓ |
| NodeBuffer#writeFloatBE | 135,763 ops/sec | ±0.65% | 96 | |
| | | | |
## Testing the project
First, install the project:
npm install
Then, to run tests in Node.js, run:
npm run test-node
To test locally in a browser, you can run:
npm run test-browser-es5-local # For ES5 browsers that don't support ES6
npm run test-browser-es6-local # For ES6 compliant browsers
This will print out a URL that you can then open in a browser to run the tests, using [airtap](https://www.npmjs.com/package/airtap).
To run automated browser tests using Saucelabs, ensure that your `SAUCE_USERNAME` and `SAUCE_ACCESS_KEY` environment variables are set, then run:
npm test
This is what's run in Travis, to check against various browsers. The list of browsers is kept in the `bin/airtap-es5.yml` and `bin/airtap-es6.yml` files.
## JavaScript Standard Style
This module uses [JavaScript Standard Style](https://github.com/feross/standard).
[![JavaScript Style Guide](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)
To test that the code conforms to the style, `npm install` and run:
./node_modules/.bin/standard
## credit
This was originally forked from [buffer-browserify](https://github.com/toots/buffer-browserify).
## Security Policies and Procedures
The `buffer` team and community take all security bugs in `buffer` seriously. Please see our [security policies and procedures](https://github.com/feross/security) document to learn how to report issues.
## license
MIT. Copyright (C) [Feross Aboukhadijeh](http://feross.org), and other contributors. Originally forked from an MIT-licensed module by Romain Beauxis.

View File

@@ -0,0 +1,194 @@
export class Buffer extends Uint8Array {
length: number
write(string: string, offset?: number, length?: number, encoding?: string): number;
toString(encoding?: string, start?: number, end?: number): string;
toJSON(): { type: 'Buffer', data: any[] };
equals(otherBuffer: Buffer): boolean;
compare(otherBuffer: Uint8Array, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number;
copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number;
slice(start?: number, end?: number): Buffer;
writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number;
readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number;
readIntLE(offset: number, byteLength: number, noAssert?: boolean): number;
readIntBE(offset: number, byteLength: number, noAssert?: boolean): number;
readUInt8(offset: number, noAssert?: boolean): number;
readUInt16LE(offset: number, noAssert?: boolean): number;
readUInt16BE(offset: number, noAssert?: boolean): number;
readUInt32LE(offset: number, noAssert?: boolean): number;
readUInt32BE(offset: number, noAssert?: boolean): number;
readBigUInt64LE(offset: number): BigInt;
readBigUInt64BE(offset: number): BigInt;
readInt8(offset: number, noAssert?: boolean): number;
readInt16LE(offset: number, noAssert?: boolean): number;
readInt16BE(offset: number, noAssert?: boolean): number;
readInt32LE(offset: number, noAssert?: boolean): number;
readInt32BE(offset: number, noAssert?: boolean): number;
readBigInt64LE(offset: number): BigInt;
readBigInt64BE(offset: number): BigInt;
readFloatLE(offset: number, noAssert?: boolean): number;
readFloatBE(offset: number, noAssert?: boolean): number;
readDoubleLE(offset: number, noAssert?: boolean): number;
readDoubleBE(offset: number, noAssert?: boolean): number;
reverse(): this;
swap16(): Buffer;
swap32(): Buffer;
swap64(): Buffer;
writeUInt8(value: number, offset: number, noAssert?: boolean): number;
writeUInt16LE(value: number, offset: number, noAssert?: boolean): number;
writeUInt16BE(value: number, offset: number, noAssert?: boolean): number;
writeUInt32LE(value: number, offset: number, noAssert?: boolean): number;
writeUInt32BE(value: number, offset: number, noAssert?: boolean): number;
writeBigUInt64LE(value: number, offset: number): BigInt;
writeBigUInt64BE(value: number, offset: number): BigInt;
writeInt8(value: number, offset: number, noAssert?: boolean): number;
writeInt16LE(value: number, offset: number, noAssert?: boolean): number;
writeInt16BE(value: number, offset: number, noAssert?: boolean): number;
writeInt32LE(value: number, offset: number, noAssert?: boolean): number;
writeInt32BE(value: number, offset: number, noAssert?: boolean): number;
writeBigInt64LE(value: number, offset: number): BigInt;
writeBigInt64BE(value: number, offset: number): BigInt;
writeFloatLE(value: number, offset: number, noAssert?: boolean): number;
writeFloatBE(value: number, offset: number, noAssert?: boolean): number;
writeDoubleLE(value: number, offset: number, noAssert?: boolean): number;
writeDoubleBE(value: number, offset: number, noAssert?: boolean): number;
fill(value: any, offset?: number, end?: number): this;
indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number;
lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number;
includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean;
/**
* Allocates a new buffer containing the given {str}.
*
* @param str String to store in buffer.
* @param encoding encoding to use, optional. Default is 'utf8'
*/
constructor (str: string, encoding?: string);
/**
* Allocates a new buffer of {size} octets.
*
* @param size count of octets to allocate.
*/
constructor (size: number);
/**
* Allocates a new buffer containing the given {array} of octets.
*
* @param array The octets to store.
*/
constructor (array: Uint8Array);
/**
* Produces a Buffer backed by the same allocated memory as
* the given {ArrayBuffer}.
*
*
* @param arrayBuffer The ArrayBuffer with which to share memory.
*/
constructor (arrayBuffer: ArrayBuffer);
/**
* Allocates a new buffer containing the given {array} of octets.
*
* @param array The octets to store.
*/
constructor (array: any[]);
/**
* Copies the passed {buffer} data onto a new {Buffer} instance.
*
* @param buffer The buffer to copy.
*/
constructor (buffer: Buffer);
prototype: Buffer;
/**
* Allocates a new Buffer using an {array} of octets.
*
* @param array
*/
static from(array: any[]): Buffer;
/**
* When passed a reference to the .buffer property of a TypedArray instance,
* the newly created Buffer will share the same allocated memory as the TypedArray.
* The optional {byteOffset} and {length} arguments specify a memory range
* within the {arrayBuffer} that will be shared by the Buffer.
*
* @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer()
* @param byteOffset
* @param length
*/
static from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer;
/**
* Copies the passed {buffer} data onto a new Buffer instance.
*
* @param buffer
*/
static from(buffer: Buffer | Uint8Array): Buffer;
/**
* Creates a new Buffer containing the given JavaScript string {str}.
* If provided, the {encoding} parameter identifies the character encoding.
* If not provided, {encoding} defaults to 'utf8'.
*
* @param str
*/
static from(str: string, encoding?: string): Buffer;
/**
* Returns true if {obj} is a Buffer
*
* @param obj object to test.
*/
static isBuffer(obj: any): obj is Buffer;
/**
* Returns true if {encoding} is a valid encoding argument.
* Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex'
*
* @param encoding string to test.
*/
static isEncoding(encoding: string): boolean;
/**
* Gives the actual byte length of a string. encoding defaults to 'utf8'.
* This is not the same as String.prototype.length since that returns the number of characters in a string.
*
* @param string string to test.
* @param encoding encoding used to evaluate (defaults to 'utf8')
*/
static byteLength(string: string, encoding?: string): number;
/**
* Returns a buffer which is the result of concatenating all the buffers in the list together.
*
* If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer.
* If the list has exactly one item, then the first item of the list is returned.
* If the list has more than one item, then a new Buffer is created.
*
* @param list An array of Buffer objects to concatenate
* @param totalLength Total length of the buffers when concatenated.
* If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly.
*/
static concat(list: Uint8Array[], totalLength?: number): Buffer;
/**
* The same as buf1.compare(buf2).
*/
static compare(buf1: Uint8Array, buf2: Uint8Array): number;
/**
* Allocates a new buffer of {size} octets.
*
* @param size count of octets to allocate.
* @param fill if specified, buffer will be initialized by calling buf.fill(fill).
* If parameter is omitted, buffer will be filled with zeros.
* @param encoding encoding used for call to buf.fill while initializing
*/
static alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer;
/**
* Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents
* of the newly created Buffer are unknown and may contain sensitive data.
*
* @param size count of octets to allocate
*/
static allocUnsafe(size: number): Buffer;
/**
* Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents
* of the newly created Buffer are unknown and may contain sensitive data.
*
* @param size count of octets to allocate
*/
static allocUnsafeSlow(size: number): Buffer;
}

2106
node_modules/rpc-websockets/node_modules/buffer/index.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,93 @@
{
"name": "buffer",
"description": "Node.js Buffer API, for the browser",
"version": "6.0.3",
"author": {
"name": "Feross Aboukhadijeh",
"email": "feross@feross.org",
"url": "https://feross.org"
},
"bugs": {
"url": "https://github.com/feross/buffer/issues"
},
"contributors": [
"Romain Beauxis <toots@rastageeks.org>",
"James Halliday <mail@substack.net>"
],
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
},
"devDependencies": {
"airtap": "^3.0.0",
"benchmark": "^2.1.4",
"browserify": "^17.0.0",
"concat-stream": "^2.0.0",
"hyperquest": "^2.1.3",
"is-buffer": "^2.0.5",
"is-nan": "^1.3.0",
"split": "^1.0.1",
"standard": "*",
"tape": "^5.0.1",
"through2": "^4.0.2",
"uglify-js": "^3.11.5"
},
"homepage": "https://github.com/feross/buffer",
"jspm": {
"map": {
"./index.js": {
"node": "@node/buffer"
}
}
},
"keywords": [
"arraybuffer",
"browser",
"browserify",
"buffer",
"compatible",
"dataview",
"uint8array"
],
"license": "MIT",
"main": "index.js",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "git://github.com/feross/buffer.git"
},
"scripts": {
"perf": "browserify --debug perf/bracket-notation.js > perf/bundle.js && open perf/index.html",
"perf-node": "node perf/bracket-notation.js && node perf/concat.js && node perf/copy-big.js && node perf/copy.js && node perf/new-big.js && node perf/new.js && node perf/readDoubleBE.js && node perf/readFloatBE.js && node perf/readUInt32LE.js && node perf/slice.js && node perf/writeFloatBE.js",
"size": "browserify -r ./ | uglifyjs -c -m | gzip | wc -c",
"test": "standard && node ./bin/test.js",
"test-browser-old": "airtap -- test/*.js",
"test-browser-old-local": "airtap --local -- test/*.js",
"test-browser-new": "airtap -- test/*.js test/node/*.js",
"test-browser-new-local": "airtap --local -- test/*.js test/node/*.js",
"test-node": "tape test/*.js test/node/*.js",
"update-authors": "./bin/update-authors.sh"
},
"standard": {
"ignore": [
"test/node/**/*.js",
"test/common.js",
"test/_polyfill.js",
"perf/**/*.js"
]
},
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
}

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Arnout Kazemier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,85 @@
# EventEmitter3
[![Version npm](https://img.shields.io/npm/v/eventemitter3.svg?style=flat-square)](https://www.npmjs.com/package/eventemitter3)[![CI](https://img.shields.io/github/actions/workflow/status/primus/eventemitter3/ci.yml?branch=master&label=CI&style=flat-square)](https://github.com/primus/eventemitter3/actions?query=workflow%3ACI+branch%3Amaster)[![Coverage Status](https://img.shields.io/coveralls/primus/eventemitter3/master.svg?style=flat-square)](https://coveralls.io/r/primus/eventemitter3?branch=master)
EventEmitter3 is a high performance EventEmitter. It has been micro-optimized
for various of code paths making this, one of, if not the fastest EventEmitter
available for Node.js and browsers. The module is API compatible with the
EventEmitter that ships by default with Node.js but there are some slight
differences:
- Domain support has been removed.
- We do not `throw` an error when you emit an `error` event and nobody is
listening.
- The `newListener` and `removeListener` events have been removed as they
are useful only in some uncommon use-cases.
- The `setMaxListeners`, `getMaxListeners`, `prependListener` and
`prependOnceListener` methods are not available.
- Support for custom context for events so there is no need to use `fn.bind`.
- The `removeListener` method removes all matching listeners, not only the
first.
It's a drop in replacement for existing EventEmitters, but just faster. Free
performance, who wouldn't want that? The EventEmitter is written in EcmaScript 3
so it will work in the oldest browsers and node versions that you need to
support.
## Installation
```bash
$ npm install --save eventemitter3
```
## CDN
Recommended CDN:
```text
https://unpkg.com/eventemitter3@latest/dist/eventemitter3.umd.min.js
```
## Usage
After installation the only thing you need to do is require the module:
```js
var EventEmitter = require('eventemitter3');
```
And you're ready to create your own EventEmitter instances. For the API
documentation, please follow the official Node.js documentation:
http://nodejs.org/api/events.html
### Contextual emits
We've upgraded the API of the `EventEmitter.on`, `EventEmitter.once` and
`EventEmitter.removeListener` to accept an extra argument which is the `context`
or `this` value that should be set for the emitted events. This means you no
longer have the overhead of an event that required `fn.bind` in order to get a
custom `this` value.
```js
var EE = new EventEmitter()
, context = { foo: 'bar' };
function emitted() {
console.log(this === context); // true
}
EE.once('event-name', emitted, context);
EE.on('another-event', emitted, context);
EE.removeListener('another-event', emitted, context);
```
### Tests and benchmarks
To run tests run `npm test`. To run the benchmarks run `npm run benchmark`.
Tests and benchmarks are not included in the npm package. If you want to play
with them you have to clone the GitHub repository. Note that you will have to
run an additional `npm i` in the benchmarks folder before `npm run benchmark`.
## License
[MIT](LICENSE)

View File

@@ -0,0 +1,355 @@
function getDefaultExportFromCjs (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
var eventemitter3 = {exports: {}};
var hasRequiredEventemitter3;
function requireEventemitter3 () {
if (hasRequiredEventemitter3) return eventemitter3.exports;
hasRequiredEventemitter3 = 1;
(function (module) {
var has = Object.prototype.hasOwnProperty
, prefix = '~';
/**
* Constructor to create a storage for our `EE` objects.
* An `Events` instance is a plain object whose properties are event names.
*
* @constructor
* @private
*/
function Events() {}
//
// We try to not inherit from `Object.prototype`. In some engines creating an
// instance in this way is faster than calling `Object.create(null)` directly.
// If `Object.create(null)` is not supported we prefix the event names with a
// character to make sure that the built-in object properties are not
// overridden or used as an attack vector.
//
if (Object.create) {
Events.prototype = Object.create(null);
//
// This hack is needed because the `__proto__` property is still inherited in
// some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
//
if (!new Events().__proto__) prefix = false;
}
/**
* Representation of a single event listener.
*
* @param {Function} fn The listener function.
* @param {*} context The context to invoke the listener with.
* @param {Boolean} [once=false] Specify if the listener is a one-time listener.
* @constructor
* @private
*/
function EE(fn, context, once) {
this.fn = fn;
this.context = context;
this.once = once || false;
}
/**
* Add a listener for a given event.
*
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} context The context to invoke the listener with.
* @param {Boolean} once Specify if the listener is a one-time listener.
* @returns {EventEmitter}
* @private
*/
function addListener(emitter, event, fn, context, once) {
if (typeof fn !== 'function') {
throw new TypeError('The listener must be a function');
}
var listener = new EE(fn, context || emitter, once)
, evt = prefix ? prefix + event : event;
if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
else emitter._events[evt] = [emitter._events[evt], listener];
return emitter;
}
/**
* Clear event by name.
*
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
* @param {(String|Symbol)} evt The Event name.
* @private
*/
function clearEvent(emitter, evt) {
if (--emitter._eventsCount === 0) emitter._events = new Events();
else delete emitter._events[evt];
}
/**
* Minimal `EventEmitter` interface that is molded against the Node.js
* `EventEmitter` interface.
*
* @constructor
* @public
*/
function EventEmitter() {
this._events = new Events();
this._eventsCount = 0;
}
/**
* Return an array listing the events for which the emitter has registered
* listeners.
*
* @returns {Array}
* @public
*/
EventEmitter.prototype.eventNames = function eventNames() {
var names = []
, events
, name;
if (this._eventsCount === 0) return names;
for (name in (events = this._events)) {
if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
}
if (Object.getOwnPropertySymbols) {
return names.concat(Object.getOwnPropertySymbols(events));
}
return names;
};
/**
* Return the listeners registered for a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Array} The registered listeners.
* @public
*/
EventEmitter.prototype.listeners = function listeners(event) {
var evt = prefix ? prefix + event : event
, handlers = this._events[evt];
if (!handlers) return [];
if (handlers.fn) return [handlers.fn];
for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
ee[i] = handlers[i].fn;
}
return ee;
};
/**
* Return the number of listeners listening to a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Number} The number of listeners.
* @public
*/
EventEmitter.prototype.listenerCount = function listenerCount(event) {
var evt = prefix ? prefix + event : event
, listeners = this._events[evt];
if (!listeners) return 0;
if (listeners.fn) return 1;
return listeners.length;
};
/**
* Calls each of the listeners registered for a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Boolean} `true` if the event had listeners, else `false`.
* @public
*/
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
var evt = prefix ? prefix + event : event;
if (!this._events[evt]) return false;
var listeners = this._events[evt]
, len = arguments.length
, args
, i;
if (listeners.fn) {
if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
switch (len) {
case 1: return listeners.fn.call(listeners.context), true;
case 2: return listeners.fn.call(listeners.context, a1), true;
case 3: return listeners.fn.call(listeners.context, a1, a2), true;
case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
}
for (i = 1, args = new Array(len -1); i < len; i++) {
args[i - 1] = arguments[i];
}
listeners.fn.apply(listeners.context, args);
} else {
var length = listeners.length
, j;
for (i = 0; i < length; i++) {
if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
switch (len) {
case 1: listeners[i].fn.call(listeners[i].context); break;
case 2: listeners[i].fn.call(listeners[i].context, a1); break;
case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
default:
if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
args[j - 1] = arguments[j];
}
listeners[i].fn.apply(listeners[i].context, args);
}
}
}
return true;
};
/**
* Add a listener for a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} [context=this] The context to invoke the listener with.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.on = function on(event, fn, context) {
return addListener(this, event, fn, context, false);
};
/**
* Add a one-time listener for a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} [context=this] The context to invoke the listener with.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.once = function once(event, fn, context) {
return addListener(this, event, fn, context, true);
};
/**
* Remove the listeners of a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn Only remove the listeners that match this function.
* @param {*} context Only remove the listeners that have this context.
* @param {Boolean} once Only remove one-time listeners.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
var evt = prefix ? prefix + event : event;
if (!this._events[evt]) return this;
if (!fn) {
clearEvent(this, evt);
return this;
}
var listeners = this._events[evt];
if (listeners.fn) {
if (
listeners.fn === fn &&
(!once || listeners.once) &&
(!context || listeners.context === context)
) {
clearEvent(this, evt);
}
} else {
for (var i = 0, events = [], length = listeners.length; i < length; i++) {
if (
listeners[i].fn !== fn ||
(once && !listeners[i].once) ||
(context && listeners[i].context !== context)
) {
events.push(listeners[i]);
}
}
//
// Reset the array, or remove it completely if we have no more listeners.
//
if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
else clearEvent(this, evt);
}
return this;
};
/**
* Remove all listeners, or those of the specified event.
*
* @param {(String|Symbol)} [event] The event name.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
var evt;
if (event) {
evt = prefix ? prefix + event : event;
if (this._events[evt]) clearEvent(this, evt);
} else {
this._events = new Events();
this._eventsCount = 0;
}
return this;
};
//
// Alias methods names because people roll like that.
//
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
//
// Expose the prefix.
//
EventEmitter.prefixed = prefix;
//
// Allow `EventEmitter` to be imported as module namespace.
//
EventEmitter.EventEmitter = EventEmitter;
//
// Expose the module.
//
{
module.exports = EventEmitter;
}
} (eventemitter3));
return eventemitter3.exports;
}
var eventemitter3Exports = requireEventemitter3();
var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
export { EventEmitter, EventEmitter as default };

View File

@@ -0,0 +1 @@
function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var t,n={exports:{}};var r=(t||(t=1,function(e){var t=Object.prototype.hasOwnProperty,n="~";function r(){}function o(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function s(e,t,r,s,i){if("function"!=typeof r)throw new TypeError("The listener must be a function");var c=new o(r,s||e,i),f=n?n+t:t;return e._events[f]?e._events[f].fn?e._events[f]=[e._events[f],c]:e._events[f].push(c):(e._events[f]=c,e._eventsCount++),e}function i(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function c(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(n=!1)),c.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},c.prototype.listeners=function(e){var t=n?n+e:e,r=this._events[t];if(!r)return[];if(r.fn)return[r.fn];for(var o=0,s=r.length,i=new Array(s);o<s;o++)i[o]=r[o].fn;return i},c.prototype.listenerCount=function(e){var t=n?n+e:e,r=this._events[t];return r?r.fn?1:r.length:0},c.prototype.emit=function(e,t,r,o,s,i){var c=n?n+e:e;if(!this._events[c])return!1;var f,a,u=this._events[c],l=arguments.length;if(u.fn){switch(u.once&&this.removeListener(e,u.fn,void 0,!0),l){case 1:return u.fn.call(u.context),!0;case 2:return u.fn.call(u.context,t),!0;case 3:return u.fn.call(u.context,t,r),!0;case 4:return u.fn.call(u.context,t,r,o),!0;case 5:return u.fn.call(u.context,t,r,o,s),!0;case 6:return u.fn.call(u.context,t,r,o,s,i),!0}for(a=1,f=new Array(l-1);a<l;a++)f[a-1]=arguments[a];u.fn.apply(u.context,f)}else{var p,v=u.length;for(a=0;a<v;a++)switch(u[a].once&&this.removeListener(e,u[a].fn,void 0,!0),l){case 1:u[a].fn.call(u[a].context);break;case 2:u[a].fn.call(u[a].context,t);break;case 3:u[a].fn.call(u[a].context,t,r);break;case 4:u[a].fn.call(u[a].context,t,r,o);break;default:if(!f)for(p=1,f=new Array(l-1);p<l;p++)f[p-1]=arguments[p];u[a].fn.apply(u[a].context,f)}}return!0},c.prototype.on=function(e,t,n){return s(this,e,t,n,!1)},c.prototype.once=function(e,t,n){return s(this,e,t,n,!0)},c.prototype.removeListener=function(e,t,r,o){var s=n?n+e:e;if(!this._events[s])return this;if(!t)return i(this,s),this;var c=this._events[s];if(c.fn)c.fn!==t||o&&!c.once||r&&c.context!==r||i(this,s);else{for(var f=0,a=[],u=c.length;f<u;f++)(c[f].fn!==t||o&&!c[f].once||r&&c[f].context!==r)&&a.push(c[f]);a.length?this._events[s]=1===a.length?a[0]:a:i(this,s)}return this},c.prototype.removeAllListeners=function(e){var t;return e?(t=n?n+e:e,this._events[t]&&i(this,t)):(this._events=new r,this._eventsCount=0),this},c.prototype.off=c.prototype.removeListener,c.prototype.addListener=c.prototype.on,c.prefixed=n,c.EventEmitter=c,e.exports=c}(n)),n.exports),o=e(r);export{o as EventEmitter,o as default};//# sourceMappingURL=eventemitter3.esm.min.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,363 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.EventEmitter3 = factory());
})(this, (function () { 'use strict';
function getDefaultExportFromCjs (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
var eventemitter3 = {exports: {}};
var hasRequiredEventemitter3;
function requireEventemitter3 () {
if (hasRequiredEventemitter3) return eventemitter3.exports;
hasRequiredEventemitter3 = 1;
(function (module) {
var has = Object.prototype.hasOwnProperty
, prefix = '~';
/**
* Constructor to create a storage for our `EE` objects.
* An `Events` instance is a plain object whose properties are event names.
*
* @constructor
* @private
*/
function Events() {}
//
// We try to not inherit from `Object.prototype`. In some engines creating an
// instance in this way is faster than calling `Object.create(null)` directly.
// If `Object.create(null)` is not supported we prefix the event names with a
// character to make sure that the built-in object properties are not
// overridden or used as an attack vector.
//
if (Object.create) {
Events.prototype = Object.create(null);
//
// This hack is needed because the `__proto__` property is still inherited in
// some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
//
if (!new Events().__proto__) prefix = false;
}
/**
* Representation of a single event listener.
*
* @param {Function} fn The listener function.
* @param {*} context The context to invoke the listener with.
* @param {Boolean} [once=false] Specify if the listener is a one-time listener.
* @constructor
* @private
*/
function EE(fn, context, once) {
this.fn = fn;
this.context = context;
this.once = once || false;
}
/**
* Add a listener for a given event.
*
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} context The context to invoke the listener with.
* @param {Boolean} once Specify if the listener is a one-time listener.
* @returns {EventEmitter}
* @private
*/
function addListener(emitter, event, fn, context, once) {
if (typeof fn !== 'function') {
throw new TypeError('The listener must be a function');
}
var listener = new EE(fn, context || emitter, once)
, evt = prefix ? prefix + event : event;
if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
else emitter._events[evt] = [emitter._events[evt], listener];
return emitter;
}
/**
* Clear event by name.
*
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
* @param {(String|Symbol)} evt The Event name.
* @private
*/
function clearEvent(emitter, evt) {
if (--emitter._eventsCount === 0) emitter._events = new Events();
else delete emitter._events[evt];
}
/**
* Minimal `EventEmitter` interface that is molded against the Node.js
* `EventEmitter` interface.
*
* @constructor
* @public
*/
function EventEmitter() {
this._events = new Events();
this._eventsCount = 0;
}
/**
* Return an array listing the events for which the emitter has registered
* listeners.
*
* @returns {Array}
* @public
*/
EventEmitter.prototype.eventNames = function eventNames() {
var names = []
, events
, name;
if (this._eventsCount === 0) return names;
for (name in (events = this._events)) {
if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
}
if (Object.getOwnPropertySymbols) {
return names.concat(Object.getOwnPropertySymbols(events));
}
return names;
};
/**
* Return the listeners registered for a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Array} The registered listeners.
* @public
*/
EventEmitter.prototype.listeners = function listeners(event) {
var evt = prefix ? prefix + event : event
, handlers = this._events[evt];
if (!handlers) return [];
if (handlers.fn) return [handlers.fn];
for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
ee[i] = handlers[i].fn;
}
return ee;
};
/**
* Return the number of listeners listening to a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Number} The number of listeners.
* @public
*/
EventEmitter.prototype.listenerCount = function listenerCount(event) {
var evt = prefix ? prefix + event : event
, listeners = this._events[evt];
if (!listeners) return 0;
if (listeners.fn) return 1;
return listeners.length;
};
/**
* Calls each of the listeners registered for a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Boolean} `true` if the event had listeners, else `false`.
* @public
*/
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
var evt = prefix ? prefix + event : event;
if (!this._events[evt]) return false;
var listeners = this._events[evt]
, len = arguments.length
, args
, i;
if (listeners.fn) {
if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
switch (len) {
case 1: return listeners.fn.call(listeners.context), true;
case 2: return listeners.fn.call(listeners.context, a1), true;
case 3: return listeners.fn.call(listeners.context, a1, a2), true;
case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
}
for (i = 1, args = new Array(len -1); i < len; i++) {
args[i - 1] = arguments[i];
}
listeners.fn.apply(listeners.context, args);
} else {
var length = listeners.length
, j;
for (i = 0; i < length; i++) {
if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
switch (len) {
case 1: listeners[i].fn.call(listeners[i].context); break;
case 2: listeners[i].fn.call(listeners[i].context, a1); break;
case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
default:
if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
args[j - 1] = arguments[j];
}
listeners[i].fn.apply(listeners[i].context, args);
}
}
}
return true;
};
/**
* Add a listener for a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} [context=this] The context to invoke the listener with.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.on = function on(event, fn, context) {
return addListener(this, event, fn, context, false);
};
/**
* Add a one-time listener for a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} [context=this] The context to invoke the listener with.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.once = function once(event, fn, context) {
return addListener(this, event, fn, context, true);
};
/**
* Remove the listeners of a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn Only remove the listeners that match this function.
* @param {*} context Only remove the listeners that have this context.
* @param {Boolean} once Only remove one-time listeners.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
var evt = prefix ? prefix + event : event;
if (!this._events[evt]) return this;
if (!fn) {
clearEvent(this, evt);
return this;
}
var listeners = this._events[evt];
if (listeners.fn) {
if (
listeners.fn === fn &&
(!once || listeners.once) &&
(!context || listeners.context === context)
) {
clearEvent(this, evt);
}
} else {
for (var i = 0, events = [], length = listeners.length; i < length; i++) {
if (
listeners[i].fn !== fn ||
(once && !listeners[i].once) ||
(context && listeners[i].context !== context)
) {
events.push(listeners[i]);
}
}
//
// Reset the array, or remove it completely if we have no more listeners.
//
if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
else clearEvent(this, evt);
}
return this;
};
/**
* Remove all listeners, or those of the specified event.
*
* @param {(String|Symbol)} [event] The event name.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
var evt;
if (event) {
evt = prefix ? prefix + event : event;
if (this._events[evt]) clearEvent(this, evt);
} else {
this._events = new Events();
this._eventsCount = 0;
}
return this;
};
//
// Alias methods names because people roll like that.
//
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
//
// Expose the prefix.
//
EventEmitter.prefixed = prefix;
//
// Allow `EventEmitter` to be imported as module namespace.
//
EventEmitter.EventEmitter = EventEmitter;
//
// Expose the module.
//
{
module.exports = EventEmitter;
}
} (eventemitter3));
return eventemitter3.exports;
}
var eventemitter3Exports = requireEventemitter3();
var index = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
return index;
}));

View File

@@ -0,0 +1 @@
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).EventEmitter3=t()}(this,function(){"use strict";function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var t,n={exports:{}};var r=(t||(t=1,function(e){var t=Object.prototype.hasOwnProperty,n="~";function r(){}function o(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function s(e,t,r,s,i){if("function"!=typeof r)throw new TypeError("The listener must be a function");var c=new o(r,s||e,i),f=n?n+t:t;return e._events[f]?e._events[f].fn?e._events[f]=[e._events[f],c]:e._events[f].push(c):(e._events[f]=c,e._eventsCount++),e}function i(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function c(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(n=!1)),c.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},c.prototype.listeners=function(e){var t=n?n+e:e,r=this._events[t];if(!r)return[];if(r.fn)return[r.fn];for(var o=0,s=r.length,i=new Array(s);o<s;o++)i[o]=r[o].fn;return i},c.prototype.listenerCount=function(e){var t=n?n+e:e,r=this._events[t];return r?r.fn?1:r.length:0},c.prototype.emit=function(e,t,r,o,s,i){var c=n?n+e:e;if(!this._events[c])return!1;var f,u,a=this._events[c],l=arguments.length;if(a.fn){switch(a.once&&this.removeListener(e,a.fn,void 0,!0),l){case 1:return a.fn.call(a.context),!0;case 2:return a.fn.call(a.context,t),!0;case 3:return a.fn.call(a.context,t,r),!0;case 4:return a.fn.call(a.context,t,r,o),!0;case 5:return a.fn.call(a.context,t,r,o,s),!0;case 6:return a.fn.call(a.context,t,r,o,s,i),!0}for(u=1,f=new Array(l-1);u<l;u++)f[u-1]=arguments[u];a.fn.apply(a.context,f)}else{var p,v=a.length;for(u=0;u<v;u++)switch(a[u].once&&this.removeListener(e,a[u].fn,void 0,!0),l){case 1:a[u].fn.call(a[u].context);break;case 2:a[u].fn.call(a[u].context,t);break;case 3:a[u].fn.call(a[u].context,t,r);break;case 4:a[u].fn.call(a[u].context,t,r,o);break;default:if(!f)for(p=1,f=new Array(l-1);p<l;p++)f[p-1]=arguments[p];a[u].fn.apply(a[u].context,f)}}return!0},c.prototype.on=function(e,t,n){return s(this,e,t,n,!1)},c.prototype.once=function(e,t,n){return s(this,e,t,n,!0)},c.prototype.removeListener=function(e,t,r,o){var s=n?n+e:e;if(!this._events[s])return this;if(!t)return i(this,s),this;var c=this._events[s];if(c.fn)c.fn!==t||o&&!c.once||r&&c.context!==r||i(this,s);else{for(var f=0,u=[],a=c.length;f<a;f++)(c[f].fn!==t||o&&!c[f].once||r&&c[f].context!==r)&&u.push(c[f]);u.length?this._events[s]=1===u.length?u[0]:u:i(this,s)}return this},c.prototype.removeAllListeners=function(e){var t;return e?(t=n?n+e:e,this._events[t]&&i(this,t)):(this._events=new r,this._eventsCount=0),this},c.prototype.off=c.prototype.removeListener,c.prototype.addListener=c.prototype.on,c.prefixed=n,c.EventEmitter=c,e.exports=c}(n)),n.exports);return e(r)});//# sourceMappingURL=eventemitter3.umd.min.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,135 @@
/**
* Minimal `EventEmitter` interface that is molded against the Node.js
* `EventEmitter` interface.
*/
declare class EventEmitter<
EventTypes extends EventEmitter.ValidEventTypes = string | symbol,
Context extends any = any
> {
static prefixed: string | boolean;
/**
* Return an array listing the events for which the emitter has registered
* listeners.
*/
eventNames(): Array<EventEmitter.EventNames<EventTypes>>;
/**
* Return the listeners registered for a given event.
*/
listeners<T extends EventEmitter.EventNames<EventTypes>>(
event: T
): Array<EventEmitter.EventListener<EventTypes, T>>;
/**
* Return the number of listeners listening to a given event.
*/
listenerCount(event: EventEmitter.EventNames<EventTypes>): number;
/**
* Calls each of the listeners registered for a given event.
*/
emit<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
...args: EventEmitter.EventArgs<EventTypes, T>
): boolean;
/**
* Add a listener for a given event.
*/
on<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn: EventEmitter.EventListener<EventTypes, T>,
context?: Context
): this;
addListener<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn: EventEmitter.EventListener<EventTypes, T>,
context?: Context
): this;
/**
* Add a one-time listener for a given event.
*/
once<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn: EventEmitter.EventListener<EventTypes, T>,
context?: Context
): this;
/**
* Remove the listeners of a given event.
*/
removeListener<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn?: EventEmitter.EventListener<EventTypes, T>,
context?: Context,
once?: boolean
): this;
off<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn?: EventEmitter.EventListener<EventTypes, T>,
context?: Context,
once?: boolean
): this;
/**
* Remove all listeners, or those of the specified event.
*/
removeAllListeners(event?: EventEmitter.EventNames<EventTypes>): this;
}
declare namespace EventEmitter {
export interface ListenerFn<Args extends any[] = any[]> {
(...args: Args): void;
}
export interface EventEmitterStatic {
new <
EventTypes extends ValidEventTypes = string | symbol,
Context = any
>(): EventEmitter<EventTypes, Context>;
}
/**
* `object` should be in either of the following forms:
* ```
* interface EventTypes {
* 'event-with-parameters': any[]
* 'event-with-example-handler': (...args: any[]) => void
* }
* ```
*/
export type ValidEventTypes = string | symbol | object;
export type EventNames<T extends ValidEventTypes> = T extends string | symbol
? T
: keyof T;
export type ArgumentMap<T extends object> = {
[K in keyof T]: T[K] extends (...args: any[]) => void
? Parameters<T[K]>
: T[K] extends any[]
? T[K]
: any[];
};
export type EventListener<
T extends ValidEventTypes,
K extends EventNames<T>
> = T extends string | symbol
? (...args: any[]) => void
: (
...args: ArgumentMap<Exclude<T, string | symbol>>[Extract<K, keyof T>]
) => void;
export type EventArgs<
T extends ValidEventTypes,
K extends EventNames<T>
> = Parameters<EventListener<T, K>>;
export const EventEmitter: EventEmitterStatic;
}
export { EventEmitter }
export default EventEmitter;

View File

@@ -0,0 +1,336 @@
'use strict';
var has = Object.prototype.hasOwnProperty
, prefix = '~';
/**
* Constructor to create a storage for our `EE` objects.
* An `Events` instance is a plain object whose properties are event names.
*
* @constructor
* @private
*/
function Events() {}
//
// We try to not inherit from `Object.prototype`. In some engines creating an
// instance in this way is faster than calling `Object.create(null)` directly.
// If `Object.create(null)` is not supported we prefix the event names with a
// character to make sure that the built-in object properties are not
// overridden or used as an attack vector.
//
if (Object.create) {
Events.prototype = Object.create(null);
//
// This hack is needed because the `__proto__` property is still inherited in
// some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
//
if (!new Events().__proto__) prefix = false;
}
/**
* Representation of a single event listener.
*
* @param {Function} fn The listener function.
* @param {*} context The context to invoke the listener with.
* @param {Boolean} [once=false] Specify if the listener is a one-time listener.
* @constructor
* @private
*/
function EE(fn, context, once) {
this.fn = fn;
this.context = context;
this.once = once || false;
}
/**
* Add a listener for a given event.
*
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} context The context to invoke the listener with.
* @param {Boolean} once Specify if the listener is a one-time listener.
* @returns {EventEmitter}
* @private
*/
function addListener(emitter, event, fn, context, once) {
if (typeof fn !== 'function') {
throw new TypeError('The listener must be a function');
}
var listener = new EE(fn, context || emitter, once)
, evt = prefix ? prefix + event : event;
if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
else emitter._events[evt] = [emitter._events[evt], listener];
return emitter;
}
/**
* Clear event by name.
*
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
* @param {(String|Symbol)} evt The Event name.
* @private
*/
function clearEvent(emitter, evt) {
if (--emitter._eventsCount === 0) emitter._events = new Events();
else delete emitter._events[evt];
}
/**
* Minimal `EventEmitter` interface that is molded against the Node.js
* `EventEmitter` interface.
*
* @constructor
* @public
*/
function EventEmitter() {
this._events = new Events();
this._eventsCount = 0;
}
/**
* Return an array listing the events for which the emitter has registered
* listeners.
*
* @returns {Array}
* @public
*/
EventEmitter.prototype.eventNames = function eventNames() {
var names = []
, events
, name;
if (this._eventsCount === 0) return names;
for (name in (events = this._events)) {
if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
}
if (Object.getOwnPropertySymbols) {
return names.concat(Object.getOwnPropertySymbols(events));
}
return names;
};
/**
* Return the listeners registered for a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Array} The registered listeners.
* @public
*/
EventEmitter.prototype.listeners = function listeners(event) {
var evt = prefix ? prefix + event : event
, handlers = this._events[evt];
if (!handlers) return [];
if (handlers.fn) return [handlers.fn];
for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
ee[i] = handlers[i].fn;
}
return ee;
};
/**
* Return the number of listeners listening to a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Number} The number of listeners.
* @public
*/
EventEmitter.prototype.listenerCount = function listenerCount(event) {
var evt = prefix ? prefix + event : event
, listeners = this._events[evt];
if (!listeners) return 0;
if (listeners.fn) return 1;
return listeners.length;
};
/**
* Calls each of the listeners registered for a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Boolean} `true` if the event had listeners, else `false`.
* @public
*/
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
var evt = prefix ? prefix + event : event;
if (!this._events[evt]) return false;
var listeners = this._events[evt]
, len = arguments.length
, args
, i;
if (listeners.fn) {
if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
switch (len) {
case 1: return listeners.fn.call(listeners.context), true;
case 2: return listeners.fn.call(listeners.context, a1), true;
case 3: return listeners.fn.call(listeners.context, a1, a2), true;
case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
}
for (i = 1, args = new Array(len -1); i < len; i++) {
args[i - 1] = arguments[i];
}
listeners.fn.apply(listeners.context, args);
} else {
var length = listeners.length
, j;
for (i = 0; i < length; i++) {
if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
switch (len) {
case 1: listeners[i].fn.call(listeners[i].context); break;
case 2: listeners[i].fn.call(listeners[i].context, a1); break;
case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
default:
if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
args[j - 1] = arguments[j];
}
listeners[i].fn.apply(listeners[i].context, args);
}
}
}
return true;
};
/**
* Add a listener for a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} [context=this] The context to invoke the listener with.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.on = function on(event, fn, context) {
return addListener(this, event, fn, context, false);
};
/**
* Add a one-time listener for a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} [context=this] The context to invoke the listener with.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.once = function once(event, fn, context) {
return addListener(this, event, fn, context, true);
};
/**
* Remove the listeners of a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn Only remove the listeners that match this function.
* @param {*} context Only remove the listeners that have this context.
* @param {Boolean} once Only remove one-time listeners.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
var evt = prefix ? prefix + event : event;
if (!this._events[evt]) return this;
if (!fn) {
clearEvent(this, evt);
return this;
}
var listeners = this._events[evt];
if (listeners.fn) {
if (
listeners.fn === fn &&
(!once || listeners.once) &&
(!context || listeners.context === context)
) {
clearEvent(this, evt);
}
} else {
for (var i = 0, events = [], length = listeners.length; i < length; i++) {
if (
listeners[i].fn !== fn ||
(once && !listeners[i].once) ||
(context && listeners[i].context !== context)
) {
events.push(listeners[i]);
}
}
//
// Reset the array, or remove it completely if we have no more listeners.
//
if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
else clearEvent(this, evt);
}
return this;
};
/**
* Remove all listeners, or those of the specified event.
*
* @param {(String|Symbol)} [event] The event name.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
var evt;
if (event) {
evt = prefix ? prefix + event : event;
if (this._events[evt]) clearEvent(this, evt);
} else {
this._events = new Events();
this._eventsCount = 0;
}
return this;
};
//
// Alias methods names because people roll like that.
//
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
//
// Expose the prefix.
//
EventEmitter.prefixed = prefix;
//
// Allow `EventEmitter` to be imported as module namespace.
//
EventEmitter.EventEmitter = EventEmitter;
//
// Expose the module.
//
if ('undefined' !== typeof module) {
module.exports = EventEmitter;
}

View File

@@ -0,0 +1,4 @@
import EventEmitter from './index.js'
export { EventEmitter }
export default EventEmitter

View File

@@ -0,0 +1,62 @@
{
"name": "eventemitter3",
"version": "5.0.4",
"description": "EventEmitter3 focuses on performance while maintaining a Node.js AND browser compatible interface.",
"exports": {
".": {
"types": "./index.d.ts",
"import": "./index.mjs",
"require": "./index.js"
},
"./package.json": "./package.json"
},
"main": "index.js",
"types": "index.d.ts",
"scripts": {
"rollup": "rm -rf dist && rollup -c",
"benchmark": "find benchmarks/run -name '*.js' -exec benchmarks/start.sh {} \\;",
"test": "c8 --reporter=lcov --reporter=text mocha test/test.js",
"test-esm": "mocha test/test.mjs",
"prepublishOnly": "npm run rollup"
},
"files": [
"index.js",
"index.mjs",
"index.d.ts",
"dist"
],
"repository": {
"type": "git",
"url": "git://github.com/primus/eventemitter3.git"
},
"keywords": [
"EventEmitter",
"EventEmitter2",
"EventEmitter3",
"Events",
"addEventListener",
"addListener",
"emit",
"emits",
"emitter",
"event",
"once",
"pub/sub",
"publish",
"reactor",
"subscribe"
],
"author": "Arnout Kazemier",
"license": "MIT",
"bugs": {
"url": "https://github.com/primus/eventemitter3/issues"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^29.0.0",
"@rollup/plugin-terser": "^0.4.0",
"assume": "^2.2.0",
"c8": "^10.1.3",
"mocha": "^11.7.5",
"rollup": "^4.5.2"
}
}

View File

@@ -0,0 +1,9 @@
The MIT License (MIT)
Copyright (c) 2010-2020 Robert Kieffer and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

510
node_modules/rpc-websockets/node_modules/uuid/README.md generated vendored Normal file
View File

@@ -0,0 +1,510 @@
<!--
-- This file is auto-generated from README_js.md. Changes should be made there.
-->
# uuid [![CI](https://github.com/uuidjs/uuid/workflows/CI/badge.svg)](https://github.com/uuidjs/uuid/actions?query=workflow%3ACI) [![Browser](https://github.com/uuidjs/uuid/workflows/Browser/badge.svg)](https://github.com/uuidjs/uuid/actions/workflows/browser.yml)
For the creation of [RFC9562](https://www.rfc-editor.org/rfc/rfc9562.html) (formerly [RFC4122](https://www.rfc-editor.org/rfc/rfc4122.html)) UUIDs
- **Complete** - Support for all RFC9562 UUID versions
- **Cross-platform** - Support for...
- ESM & Common JS
- [Typescript](#support)
- [Chrome, Safari, Firefox, and Edge](#support)
- [NodeJS](#support)
- [React Native / Expo](#react-native--expo)
- **Secure** - Uses modern `crypto` API for random values
- **Compact** - Zero-dependency, [tree-shakable](https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking)
- **CLI** - [`uuid` command line](#command-line) utility
<!-- prettier-ignore -->
> [!NOTE]
> `uuid@11` is now available: See the [CHANGELOG](./CHANGELOG.md) for details. TL;DR:
> * TypeScript support is now included (remove `@types/uuid` from your dependencies)
> * Subtle changes to how the `options` arg is interpreted for `v1()`, `v6()`, and `v7()`. [See details](#options-handling-for-timestamp-uuids)
> * Binary UUIDs are now `Uint8Array`s. (May impact callers of `parse()`, `stringify()`, or that pass an `option#buf` argument to `v1()`-`v7()`.)
## Quickstart
**1. Install**
```shell
npm install uuid
```
**2. Create a UUID**
ESM-syntax (must use named exports):
```javascript
import { v4 as uuidv4 } from 'uuid';
uuidv4(); // ⇨ '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'
```
... CommonJS:
```javascript
const { v4: uuidv4 } = require('uuid');
uuidv4(); // ⇨ '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed'
```
For timestamp UUIDs, namespace UUIDs, and other options read on ...
## API Summary
| | | |
| --- | --- | --- |
| [`uuid.NIL`](#uuidnil) | The nil UUID string (all zeros) | New in `uuid@8.3` |
| [`uuid.MAX`](#uuidmax) | The max UUID string (all ones) | New in `uuid@9.1` |
| [`uuid.parse()`](#uuidparsestr) | Convert UUID string to array of bytes | New in `uuid@8.3` |
| [`uuid.stringify()`](#uuidstringifyarr-offset) | Convert array of bytes to UUID string | New in `uuid@8.3` |
| [`uuid.v1()`](#uuidv1options-buffer-offset) | Create a version 1 (timestamp) UUID | |
| [`uuid.v1ToV6()`](#uuidv1tov6uuid) | Create a version 6 UUID from a version 1 UUID | New in `uuid@10` |
| [`uuid.v3()`](#uuidv3name-namespace-buffer-offset) | Create a version 3 (namespace w/ MD5) UUID | |
| [`uuid.v4()`](#uuidv4options-buffer-offset) | Create a version 4 (random) UUID | |
| [`uuid.v5()`](#uuidv5name-namespace-buffer-offset) | Create a version 5 (namespace w/ SHA-1) UUID | |
| [`uuid.v6()`](#uuidv6options-buffer-offset) | Create a version 6 (timestamp, reordered) UUID | New in `uuid@10` |
| [`uuid.v6ToV1()`](#uuidv6tov1uuid) | Create a version 1 UUID from a version 6 UUID | New in `uuid@10` |
| [`uuid.v7()`](#uuidv7options-buffer-offset) | Create a version 7 (Unix Epoch time-based) UUID | New in `uuid@10` |
| ~~[`uuid.v8()`](#uuidv8)~~ | "Intentionally left blank" | |
| [`uuid.validate()`](#uuidvalidatestr) | Test a string to see if it is a valid UUID | New in `uuid@8.3` |
| [`uuid.version()`](#uuidversionstr) | Detect RFC version of a UUID | New in `uuid@8.3` |
## API
### uuid.NIL
The nil UUID string (all zeros).
Example:
```javascript
import { NIL as NIL_UUID } from 'uuid';
NIL_UUID; // ⇨ '00000000-0000-0000-0000-000000000000'
```
### uuid.MAX
The max UUID string (all ones).
Example:
```javascript
import { MAX as MAX_UUID } from 'uuid';
MAX_UUID; // ⇨ 'ffffffff-ffff-ffff-ffff-ffffffffffff'
```
### uuid.parse(str)
Convert UUID string to array of bytes
| | |
| --------- | ---------------------------------------- |
| `str` | A valid UUID `String` |
| _returns_ | `Uint8Array[16]` |
| _throws_ | `TypeError` if `str` is not a valid UUID |
<!-- prettier-ignore -->
> [!NOTE]
> Ordering of values in the byte arrays used by `parse()` and `stringify()` follows the left &Rarr; right order of hex-pairs in UUID strings. As shown in the example below.
Example:
```javascript
import { parse as uuidParse } from 'uuid';
// Parse a UUID
uuidParse('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'); // ⇨
// Uint8Array(16) [
// 110, 192, 189, 127, 17,
// 192, 67, 218, 151, 94,
// 42, 138, 217, 235, 174,
// 11
// ]
```
### uuid.stringify(arr[, offset])
Convert array of bytes to UUID string
| | |
| -------------- | ---------------------------------------------------------------------------- |
| `arr` | `Array`-like collection of 16 values (starting from `offset`) between 0-255. |
| [`offset` = 0] | `Number` Starting index in the Array |
| _returns_ | `String` |
| _throws_ | `TypeError` if a valid UUID string cannot be generated |
<!-- prettier-ignore -->
> [!NOTE]
> Ordering of values in the byte arrays used by `parse()` and `stringify()` follows the left &Rarr; right order of hex-pairs in UUID strings. As shown in the example below.
Example:
```javascript
import { stringify as uuidStringify } from 'uuid';
const uuidBytes = Uint8Array.of(
0x6e,
0xc0,
0xbd,
0x7f,
0x11,
0xc0,
0x43,
0xda,
0x97,
0x5e,
0x2a,
0x8a,
0xd9,
0xeb,
0xae,
0x0b
);
uuidStringify(uuidBytes); // ⇨ '6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'
```
### uuid.v1([options[, buffer[, offset]]])
Create an RFC version 1 (timestamp) UUID
| | |
| --- | --- |
| [`options`] | `Object` with one or more of the following properties: |
| [`options.node = (random)` ] | RFC "node" field as an `Array[6]` of byte values (per 4.1.6) |
| [`options.clockseq = (random)`] | RFC "clock sequence" as a `Number` between 0 - 0x3fff |
| [`options.msecs = (current time)`] | RFC "timestamp" field (`Number` of milliseconds, unix epoch) |
| [`options.nsecs = 0`] | RFC "timestamp" field (`Number` of nanoseconds to add to `msecs`, should be 0-10,000) |
| [`options.random = (random)`] | `Array` of 16 random bytes (0-255) used to generate other fields, above |
| [`options.rng`] | Alternative to `options.random`, a `Function` that returns an `Array` of 16 random bytes (0-255) |
| [`buffer`] | `Uint8Array` or `Uint8Array` subtype (e.g. Node.js `Buffer`). If provided, binary UUID is written into the array, starting at `offset` |
| [`offset` = 0] | `Number` Index to start writing UUID bytes in `buffer` |
| _returns_ | UUID `String` if no `buffer` is specified, otherwise returns `buffer` |
| _throws_ | `Error` if more than 10M UUIDs/sec are requested |
<!-- prettier-ignore -->
> [!NOTE]
> The default [node id](https://datatracker.ietf.org/doc/html/rfc9562#section-5.1) (the last 12 digits in the UUID) is generated once, randomly, on process startup, and then remains unchanged for the duration of the process.
<!-- prettier-ignore -->
> [!NOTE]
> `options.random` and `options.rng` are only meaningful on the very first call to `v1()`, where they may be passed to initialize the internal `node` and `clockseq` fields.
Example:
```javascript
import { v1 as uuidv1 } from 'uuid';
uuidv1(); // ⇨ '2c5ea4c0-4067-11e9-9bdd-2b0d7b3dcb6d'
```
Example using `options`:
```javascript
import { v1 as uuidv1 } from 'uuid';
const options = {
node: Uint8Array.of(0x01, 0x23, 0x45, 0x67, 0x89, 0xab),
clockseq: 0x1234,
msecs: new Date('2011-11-01').getTime(),
nsecs: 5678,
};
uuidv1(options); // ⇨ '710b962e-041c-11e1-9234-0123456789ab'
```
### uuid.v1ToV6(uuid)
Convert a UUID from version 1 to version 6
```javascript
import { v1ToV6 } from 'uuid';
v1ToV6('92f62d9e-22c4-11ef-97e9-325096b39f47'); // ⇨ '1ef22c49-2f62-6d9e-97e9-325096b39f47'
```
### uuid.v3(name, namespace[, buffer[, offset]])
Create an RFC version 3 (namespace w/ MD5) UUID
API is identical to `v5()`, but uses "v3" instead.
<!-- prettier-ignore -->
> [!IMPORTANT]
> Per the RFC, "_If backward compatibility is not an issue, SHA-1 [Version 5] is preferred_."
### uuid.v4([options[, buffer[, offset]]])
Create an RFC version 4 (random) UUID
| | |
| --- | --- |
| [`options`] | `Object` with one or more of the following properties: |
| [`options.random`] | `Array` of 16 random bytes (0-255) |
| [`options.rng`] | Alternative to `options.random`, a `Function` that returns an `Array` of 16 random bytes (0-255) |
| [`buffer`] | `Uint8Array` or `Uint8Array` subtype (e.g. Node.js `Buffer`). If provided, binary UUID is written into the array, starting at `offset` |
| [`offset` = 0] | `Number` Index to start writing UUID bytes in `buffer` |
| _returns_ | UUID `String` if no `buffer` is specified, otherwise returns `buffer` |
Example:
```javascript
import { v4 as uuidv4 } from 'uuid';
uuidv4(); // ⇨ '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'
```
Example using predefined `random` values:
```javascript
import { v4 as uuidv4 } from 'uuid';
const v4options = {
random: Uint8Array.of(
0x10,
0x91,
0x56,
0xbe,
0xc4,
0xfb,
0xc1,
0xea,
0x71,
0xb4,
0xef,
0xe1,
0x67,
0x1c,
0x58,
0x36
),
};
uuidv4(v4options); // ⇨ '109156be-c4fb-41ea-b1b4-efe1671c5836'
```
### uuid.v5(name, namespace[, buffer[, offset]])
Create an RFC version 5 (namespace w/ SHA-1) UUID
| | |
| --- | --- |
| `name` | `String \| Array` |
| `namespace` | `String \| Array[16]` Namespace UUID |
| [`buffer`] | `Uint8Array` or `Uint8Array` subtype (e.g. Node.js `Buffer`). If provided, binary UUID is written into the array, starting at `offset` |
| [`offset` = 0] | `Number` Index to start writing UUID bytes in `buffer` |
| _returns_ | UUID `String` if no `buffer` is specified, otherwise returns `buffer` |
<!-- prettier-ignore -->
> [!NOTE]
> The RFC `DNS` and `URL` namespaces are available as `v5.DNS` and `v5.URL`.
Example with custom namespace:
```javascript
import { v5 as uuidv5 } from 'uuid';
// Define a custom namespace. Readers, create your own using something like
// https://www.uuidgenerator.net/
const MY_NAMESPACE = '1b671a64-40d5-491e-99b0-da01ff1f3341';
uuidv5('Hello, World!', MY_NAMESPACE); // ⇨ '630eb68f-e0fa-5ecc-887a-7c7a62614681'
```
Example with RFC `URL` namespace:
```javascript
import { v5 as uuidv5 } from 'uuid';
uuidv5('https://www.w3.org/', uuidv5.URL); // ⇨ 'c106a26a-21bb-5538-8bf2-57095d1976c1'
```
### uuid.v6([options[, buffer[, offset]]])
Create an RFC version 6 (timestamp, reordered) UUID
This method takes the same arguments as uuid.v1().
```javascript
import { v6 as uuidv6 } from 'uuid';
uuidv6(); // ⇨ '1e940672-c5ea-64c0-9b5d-ab8dfbbd4bed'
```
Example using `options`:
```javascript
import { v6 as uuidv6 } from 'uuid';
const options = {
node: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab],
clockseq: 0x1234,
msecs: new Date('2011-11-01').getTime(),
nsecs: 5678,
};
uuidv6(options); // ⇨ '1e1041c7-10b9-662e-9234-0123456789ab'
```
### uuid.v6ToV1(uuid)
Convert a UUID from version 6 to version 1
```javascript
import { v6ToV1 } from 'uuid';
v6ToV1('1ef22c49-2f62-6d9e-97e9-325096b39f47'); // ⇨ '92f62d9e-22c4-11ef-97e9-325096b39f47'
```
### uuid.v7([options[, buffer[, offset]]])
Create an RFC version 7 (random) UUID
| | |
| --- | --- |
| [`options`] | `Object` with one or more of the following properties: |
| [`options.msecs = (current time)`] | RFC "timestamp" field (`Number` of milliseconds, unix epoch) |
| [`options.random = (random)`] | `Array` of 16 random bytes (0-255) used to generate other fields, above |
| [`options.rng`] | Alternative to `options.random`, a `Function` that returns an `Array` of 16 random bytes (0-255) |
| [`options.seq = (random)`] | 32-bit sequence `Number` between 0 - 0xffffffff. This may be provided to help ensure uniqueness for UUIDs generated within the same millisecond time interval. Default = random value. |
| [`buffer`] | `Uint8Array` or `Uint8Array` subtype (e.g. Node.js `Buffer`). If provided, binary UUID is written into the array, starting at `offset` |
| [`offset` = 0] | `Number` Index to start writing UUID bytes in `buffer` |
| _returns_ | UUID `String` if no `buffer` is specified, otherwise returns `buffer` |
Example:
```javascript
import { v7 as uuidv7 } from 'uuid';
uuidv7(); // ⇨ '01695553-c90c-705a-b56d-778dfbbd4bed'
```
### ~~uuid.v8()~~
**_"Intentionally left blank"_**
<!-- prettier-ignore -->
> [!NOTE]
> Version 8 (experimental) UUIDs are "[for experimental or vendor-specific use cases](https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-8)". The RFC does not define a creation algorithm for them, which is why this package does not offer a `v8()` method. The `validate()` and `version()` methods do work with such UUIDs, however.
### uuid.validate(str)
Test a string to see if it is a valid UUID
| | |
| --------- | --------------------------------------------------- |
| `str` | `String` to validate |
| _returns_ | `true` if string is a valid UUID, `false` otherwise |
Example:
```javascript
import { validate as uuidValidate } from 'uuid';
uuidValidate('not a UUID'); // ⇨ false
uuidValidate('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'); // ⇨ true
```
Using `validate` and `version` together it is possible to do per-version validation, e.g. validate for only v4 UUIds.
```javascript
import { version as uuidVersion } from 'uuid';
import { validate as uuidValidate } from 'uuid';
function uuidValidateV4(uuid) {
return uuidValidate(uuid) && uuidVersion(uuid) === 4;
}
const v1Uuid = 'd9428888-122b-11e1-b85c-61cd3cbb3210';
const v4Uuid = '109156be-c4fb-41ea-b1b4-efe1671c5836';
uuidValidateV4(v4Uuid); // ⇨ true
uuidValidateV4(v1Uuid); // ⇨ false
```
### uuid.version(str)
Detect RFC version of a UUID
| | |
| --------- | ---------------------------------------- |
| `str` | A valid UUID `String` |
| _returns_ | `Number` The RFC version of the UUID |
| _throws_ | `TypeError` if `str` is not a valid UUID |
Example:
```javascript
import { version as uuidVersion } from 'uuid';
uuidVersion('45637ec4-c85f-11ea-87d0-0242ac130003'); // ⇨ 1
uuidVersion('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'); // ⇨ 4
```
<!-- prettier-ignore -->
> [!NOTE]
> This method returns `0` for the `NIL` UUID, and `15` for the `MAX` UUID.
## Command Line
UUIDs can be generated from the command line using `uuid`.
```shell
$ npx uuid
ddeb27fb-d9a0-4624-be4d-4615062daed4
```
The default is to generate version 4 UUIDS, however the other versions are supported. Type `uuid --help` for details:
```shell
$ npx uuid --help
Usage:
uuid
uuid v1
uuid v3 <name> <namespace uuid>
uuid v4
uuid v5 <name> <namespace uuid>
uuid v7
uuid --help
Note: <namespace uuid> may be "URL" or "DNS" to use the corresponding UUIDs
defined by RFC9562
```
## `options` Handling for Timestamp UUIDs
Prior to `uuid@11`, it was possible for `options` state to interfere with the internal state used to ensure uniqueness of timestamp-based UUIDs (the `v1()`, `v6()`, and `v7()` methods). Starting with `uuid@11`, this issue has been addressed by using the presence of the `options` argument as a flag to select between two possible behaviors:
- Without `options`: Internal state is utilized to improve UUID uniqueness.
- With `options`: Internal state is **NOT** used and, instead, appropriate defaults are applied as needed.
## Support
**Browsers**: `uuid` [builds are tested](/uuidjs/uuid/blob/main/wdio.conf.js) against the latest version of desktop Chrome, Safari, Firefox, and Edge. Mobile versions of these same browsers are expected to work but aren't currently tested.
**Node**: `uuid` [builds are tested](https://github.com/uuidjs/uuid/blob/main/.github/workflows/ci.yml#L26-L27) against node ([LTS releases](https://github.com/nodejs/Release)), plus one prior. E.g. `node@18` is in maintainence mode, and `node@22` is the current LTS release. So `uuid` supports `node@16`-`node@22`.
**Typescript**: TS versions released within the past two years are supported. [source](https://github.com/microsoft/TypeScript/issues/49088#issuecomment-2468723715)
## Known issues
<!-- This header is referenced as an anchor in src/rng-browser.ts -->
### "getRandomValues() not supported"
This error occurs in environments where the standard [`crypto.getRandomValues()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) API is not supported. This issue can be resolved by adding an appropriate polyfill:
#### React Native / Expo
1. Install [`react-native-get-random-values`](https://github.com/LinusU/react-native-get-random-values#readme)
1. Import it _before_ `uuid`. Since `uuid` might also appear as a transitive dependency of some other imports it's safest to just import `react-native-get-random-values` as the very first thing in your entry point:
```javascript
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';
```
---
Markdown generated from [README_js.md](README_js.md) by <a href="https://github.com/broofa/runmd"><image height="13" src="https://camo.githubusercontent.com/5c7c603cd1e6a43370b0a5063d457e0dabb74cf317adc7baba183acb686ee8d0/687474703a2f2f692e696d6775722e636f6d2f634a4b6f3662552e706e67" /></a>

View File

@@ -0,0 +1,15 @@
export type * from './types.js';
export { default as MAX } from './max.js';
export { default as NIL } from './nil.js';
export { default as parse } from './parse.js';
export { default as stringify } from './stringify.js';
export { default as v1 } from './v1.js';
export { default as v1ToV6 } from './v1ToV6.js';
export { default as v3 } from './v3.js';
export { default as v4 } from './v4.js';
export { default as v5 } from './v5.js';
export { default as v6 } from './v6.js';
export { default as v6ToV1 } from './v6ToV1.js';
export { default as v7 } from './v7.js';
export { default as validate } from './validate.js';
export { default as version } from './version.js';

View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.version = exports.validate = exports.v7 = exports.v6ToV1 = exports.v6 = exports.v5 = exports.v4 = exports.v3 = exports.v1ToV6 = exports.v1 = exports.stringify = exports.parse = exports.NIL = exports.MAX = void 0;
var max_js_1 = require("./max.js");
Object.defineProperty(exports, "MAX", { enumerable: true, get: function () { return max_js_1.default; } });
var nil_js_1 = require("./nil.js");
Object.defineProperty(exports, "NIL", { enumerable: true, get: function () { return nil_js_1.default; } });
var parse_js_1 = require("./parse.js");
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parse_js_1.default; } });
var stringify_js_1 = require("./stringify.js");
Object.defineProperty(exports, "stringify", { enumerable: true, get: function () { return stringify_js_1.default; } });
var v1_js_1 = require("./v1.js");
Object.defineProperty(exports, "v1", { enumerable: true, get: function () { return v1_js_1.default; } });
var v1ToV6_js_1 = require("./v1ToV6.js");
Object.defineProperty(exports, "v1ToV6", { enumerable: true, get: function () { return v1ToV6_js_1.default; } });
var v3_js_1 = require("./v3.js");
Object.defineProperty(exports, "v3", { enumerable: true, get: function () { return v3_js_1.default; } });
var v4_js_1 = require("./v4.js");
Object.defineProperty(exports, "v4", { enumerable: true, get: function () { return v4_js_1.default; } });
var v5_js_1 = require("./v5.js");
Object.defineProperty(exports, "v5", { enumerable: true, get: function () { return v5_js_1.default; } });
var v6_js_1 = require("./v6.js");
Object.defineProperty(exports, "v6", { enumerable: true, get: function () { return v6_js_1.default; } });
var v6ToV1_js_1 = require("./v6ToV1.js");
Object.defineProperty(exports, "v6ToV1", { enumerable: true, get: function () { return v6ToV1_js_1.default; } });
var v7_js_1 = require("./v7.js");
Object.defineProperty(exports, "v7", { enumerable: true, get: function () { return v7_js_1.default; } });
var validate_js_1 = require("./validate.js");
Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return validate_js_1.default; } });
var version_js_1 = require("./version.js");
Object.defineProperty(exports, "version", { enumerable: true, get: function () { return version_js_1.default; } });

View File

@@ -0,0 +1,2 @@
declare const _default: "ffffffff-ffff-ffff-ffff-ffffffffffff";
export default _default;

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = 'ffffffff-ffff-ffff-ffff-ffffffffffff';

View File

@@ -0,0 +1,2 @@
declare function md5(bytes: Uint8Array): Uint8Array;
export default md5;

View File

@@ -0,0 +1,137 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function md5(bytes) {
const words = uint8ToUint32(bytes);
const md5Bytes = wordsToMd5(words, bytes.length * 8);
return uint32ToUint8(md5Bytes);
}
function uint32ToUint8(input) {
const bytes = new Uint8Array(input.length * 4);
for (let i = 0; i < input.length * 4; i++) {
bytes[i] = (input[i >> 2] >>> ((i % 4) * 8)) & 0xff;
}
return bytes;
}
function getOutputLength(inputLength8) {
return (((inputLength8 + 64) >>> 9) << 4) + 14 + 1;
}
function wordsToMd5(x, len) {
const xpad = new Uint32Array(getOutputLength(len)).fill(0);
xpad.set(x);
xpad[len >> 5] |= 0x80 << len % 32;
xpad[xpad.length - 1] = len;
x = xpad;
let a = 1732584193;
let b = -271733879;
let c = -1732584194;
let d = 271733878;
for (let i = 0; i < x.length; i += 16) {
const olda = a;
const oldb = b;
const oldc = c;
const oldd = d;
a = md5ff(a, b, c, d, x[i], 7, -680876936);
d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
b = md5gg(b, c, d, a, x[i], 20, -373897302);
a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
d = md5hh(d, a, b, c, x[i], 11, -358537222);
c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
a = md5ii(a, b, c, d, x[i], 6, -198630844);
d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
a = safeAdd(a, olda);
b = safeAdd(b, oldb);
c = safeAdd(c, oldc);
d = safeAdd(d, oldd);
}
return Uint32Array.of(a, b, c, d);
}
function uint8ToUint32(input) {
if (input.length === 0) {
return new Uint32Array();
}
const output = new Uint32Array(getOutputLength(input.length * 8)).fill(0);
for (let i = 0; i < input.length; i++) {
output[i >> 2] |= (input[i] & 0xff) << ((i % 4) * 8);
}
return output;
}
function safeAdd(x, y) {
const lsw = (x & 0xffff) + (y & 0xffff);
const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xffff);
}
function bitRotateLeft(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
}
function md5cmn(q, a, b, x, s, t) {
return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
}
function md5ff(a, b, c, d, x, s, t) {
return md5cmn((b & c) | (~b & d), a, b, x, s, t);
}
function md5gg(a, b, c, d, x, s, t) {
return md5cmn((b & d) | (c & ~d), a, b, x, s, t);
}
function md5hh(a, b, c, d, x, s, t) {
return md5cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5ii(a, b, c, d, x, s, t) {
return md5cmn(c ^ (b | ~d), a, b, x, s, t);
}
exports.default = md5;

View File

@@ -0,0 +1,4 @@
declare const _default: {
randomUUID: false | (() => `${string}-${string}-${string}-${string}-${string}`);
};
export default _default;

View File

@@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);
exports.default = { randomUUID };

View File

@@ -0,0 +1,2 @@
declare const _default: "00000000-0000-0000-0000-000000000000";
export default _default;

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = '00000000-0000-0000-0000-000000000000';

View File

@@ -0,0 +1 @@
{"type":"commonjs"}

View File

@@ -0,0 +1,2 @@
declare function parse(uuid: string): Uint8Array;
export default parse;

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const validate_js_1 = require("./validate.js");
function parse(uuid) {
if (!(0, validate_js_1.default)(uuid)) {
throw TypeError('Invalid UUID');
}
let v;
return Uint8Array.of((v = parseInt(uuid.slice(0, 8), 16)) >>> 24, (v >>> 16) & 0xff, (v >>> 8) & 0xff, v & 0xff, (v = parseInt(uuid.slice(9, 13), 16)) >>> 8, v & 0xff, (v = parseInt(uuid.slice(14, 18), 16)) >>> 8, v & 0xff, (v = parseInt(uuid.slice(19, 23), 16)) >>> 8, v & 0xff, ((v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000) & 0xff, (v / 0x100000000) & 0xff, (v >>> 24) & 0xff, (v >>> 16) & 0xff, (v >>> 8) & 0xff, v & 0xff);
}
exports.default = parse;

View File

@@ -0,0 +1,2 @@
declare const _default: RegExp;
export default _default;

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;

View File

@@ -0,0 +1 @@
export default function rng(): Uint8Array;

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
let getRandomValues;
const rnds8 = new Uint8Array(16);
function rng() {
if (!getRandomValues) {
if (typeof crypto === 'undefined' || !crypto.getRandomValues) {
throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
}
getRandomValues = crypto.getRandomValues.bind(crypto);
}
return getRandomValues(rnds8);
}
exports.default = rng;

View File

@@ -0,0 +1,2 @@
declare function sha1(bytes: Uint8Array): Uint8Array;
export default sha1;

View File

@@ -0,0 +1,72 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function f(s, x, y, z) {
switch (s) {
case 0:
return (x & y) ^ (~x & z);
case 1:
return x ^ y ^ z;
case 2:
return (x & y) ^ (x & z) ^ (y & z);
case 3:
return x ^ y ^ z;
}
}
function ROTL(x, n) {
return (x << n) | (x >>> (32 - n));
}
function sha1(bytes) {
const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
const newBytes = new Uint8Array(bytes.length + 1);
newBytes.set(bytes);
newBytes[bytes.length] = 0x80;
bytes = newBytes;
const l = bytes.length / 4 + 2;
const N = Math.ceil(l / 16);
const M = new Array(N);
for (let i = 0; i < N; ++i) {
const arr = new Uint32Array(16);
for (let j = 0; j < 16; ++j) {
arr[j] =
(bytes[i * 64 + j * 4] << 24) |
(bytes[i * 64 + j * 4 + 1] << 16) |
(bytes[i * 64 + j * 4 + 2] << 8) |
bytes[i * 64 + j * 4 + 3];
}
M[i] = arr;
}
M[N - 1][14] = ((bytes.length - 1) * 8) / Math.pow(2, 32);
M[N - 1][14] = Math.floor(M[N - 1][14]);
M[N - 1][15] = ((bytes.length - 1) * 8) & 0xffffffff;
for (let i = 0; i < N; ++i) {
const W = new Uint32Array(80);
for (let t = 0; t < 16; ++t) {
W[t] = M[i][t];
}
for (let t = 16; t < 80; ++t) {
W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
}
let a = H[0];
let b = H[1];
let c = H[2];
let d = H[3];
let e = H[4];
for (let t = 0; t < 80; ++t) {
const s = Math.floor(t / 20);
const T = (ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t]) >>> 0;
e = d;
d = c;
c = ROTL(b, 30) >>> 0;
b = a;
a = T;
}
H[0] = (H[0] + a) >>> 0;
H[1] = (H[1] + b) >>> 0;
H[2] = (H[2] + c) >>> 0;
H[3] = (H[3] + d) >>> 0;
H[4] = (H[4] + e) >>> 0;
}
return Uint8Array.of(H[0] >> 24, H[0] >> 16, H[0] >> 8, H[0], H[1] >> 24, H[1] >> 16, H[1] >> 8, H[1], H[2] >> 24, H[2] >> 16, H[2] >> 8, H[2], H[3] >> 24, H[3] >> 16, H[3] >> 8, H[3], H[4] >> 24, H[4] >> 16, H[4] >> 8, H[4]);
}
exports.default = sha1;

View File

@@ -0,0 +1,3 @@
export declare function unsafeStringify(arr: Uint8Array, offset?: number): string;
declare function stringify(arr: Uint8Array, offset?: number): string;
export default stringify;

View File

@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.unsafeStringify = void 0;
const validate_js_1 = require("./validate.js");
const byteToHex = [];
for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 0x100).toString(16).slice(1));
}
function unsafeStringify(arr, offset = 0) {
return (byteToHex[arr[offset + 0]] +
byteToHex[arr[offset + 1]] +
byteToHex[arr[offset + 2]] +
byteToHex[arr[offset + 3]] +
'-' +
byteToHex[arr[offset + 4]] +
byteToHex[arr[offset + 5]] +
'-' +
byteToHex[arr[offset + 6]] +
byteToHex[arr[offset + 7]] +
'-' +
byteToHex[arr[offset + 8]] +
byteToHex[arr[offset + 9]] +
'-' +
byteToHex[arr[offset + 10]] +
byteToHex[arr[offset + 11]] +
byteToHex[arr[offset + 12]] +
byteToHex[arr[offset + 13]] +
byteToHex[arr[offset + 14]] +
byteToHex[arr[offset + 15]]).toLowerCase();
}
exports.unsafeStringify = unsafeStringify;
function stringify(arr, offset = 0) {
const uuid = unsafeStringify(arr, offset);
if (!(0, validate_js_1.default)(uuid)) {
throw TypeError('Stringified UUID is invalid');
}
return uuid;
}
exports.default = stringify;

View File

@@ -0,0 +1,21 @@
export type UUIDTypes<TBuf extends Uint8Array = Uint8Array> = string | TBuf;
export type Version1Options = {
node?: Uint8Array;
clockseq?: number;
random?: Uint8Array;
rng?: () => Uint8Array;
msecs?: number;
nsecs?: number;
_v6?: boolean;
};
export type Version4Options = {
random?: Uint8Array;
rng?: () => Uint8Array;
};
export type Version6Options = Version1Options;
export type Version7Options = {
random?: Uint8Array;
msecs?: number;
seq?: number;
rng?: () => Uint8Array;
};

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1 @@
export {};

View File

@@ -0,0 +1,72 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const v1_js_1 = require("./v1.js");
const v3_js_1 = require("./v3.js");
const v4_js_1 = require("./v4.js");
const v5_js_1 = require("./v5.js");
const v6_js_1 = require("./v6.js");
const v7_js_1 = require("./v7.js");
function usage() {
console.log('Usage:');
console.log(' uuid');
console.log(' uuid v1');
console.log(' uuid v3 <name> <namespace uuid>');
console.log(' uuid v4');
console.log(' uuid v5 <name> <namespace uuid>');
console.log(' uuid v6');
console.log(' uuid v7');
console.log(' uuid --help');
console.log('\nNote: <namespace uuid> may be "URL" or "DNS" to use the corresponding UUIDs defined by RFC9562');
}
const args = process.argv.slice(2);
if (args.indexOf('--help') >= 0) {
usage();
process.exit(0);
}
const version = args.shift() || 'v4';
switch (version) {
case 'v1':
console.log((0, v1_js_1.default)());
break;
case 'v3': {
const name = args.shift();
let namespace = args.shift();
assert.ok(name != null, 'v3 name not specified');
assert.ok(namespace != null, 'v3 namespace not specified');
if (namespace === 'URL') {
namespace = v3_js_1.default.URL;
}
if (namespace === 'DNS') {
namespace = v3_js_1.default.DNS;
}
console.log((0, v3_js_1.default)(name, namespace));
break;
}
case 'v4':
console.log((0, v4_js_1.default)());
break;
case 'v5': {
const name = args.shift();
let namespace = args.shift();
assert.ok(name != null, 'v5 name not specified');
assert.ok(namespace != null, 'v5 namespace not specified');
if (namespace === 'URL') {
namespace = v5_js_1.default.URL;
}
if (namespace === 'DNS') {
namespace = v5_js_1.default.DNS;
}
console.log((0, v5_js_1.default)(name, namespace));
break;
}
case 'v6':
console.log((0, v6_js_1.default)());
break;
case 'v7':
console.log((0, v7_js_1.default)());
break;
default:
usage();
process.exit(1);
}

View File

@@ -0,0 +1,11 @@
import { Version1Options } from './types.js';
type V1State = {
node?: Uint8Array;
clockseq?: number;
msecs?: number;
nsecs?: number;
};
declare function v1(options?: Version1Options, buf?: undefined, offset?: number): string;
declare function v1<Buf extends Uint8Array = Uint8Array>(options: Version1Options | undefined, buf: Buf, offset?: number): Buf;
export declare function updateV1State(state: V1State, now: number, rnds: Uint8Array): V1State;
export default v1;

View File

@@ -0,0 +1,87 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateV1State = void 0;
const rng_js_1 = require("./rng.js");
const stringify_js_1 = require("./stringify.js");
const _state = {};
function v1(options, buf, offset) {
let bytes;
const isV6 = options?._v6 ?? false;
if (options) {
const optionsKeys = Object.keys(options);
if (optionsKeys.length === 1 && optionsKeys[0] === '_v6') {
options = undefined;
}
}
if (options) {
bytes = v1Bytes(options.random ?? options.rng?.() ?? (0, rng_js_1.default)(), options.msecs, options.nsecs, options.clockseq, options.node, buf, offset);
}
else {
const now = Date.now();
const rnds = (0, rng_js_1.default)();
updateV1State(_state, now, rnds);
bytes = v1Bytes(rnds, _state.msecs, _state.nsecs, isV6 ? undefined : _state.clockseq, isV6 ? undefined : _state.node, buf, offset);
}
return buf ?? (0, stringify_js_1.unsafeStringify)(bytes);
}
function updateV1State(state, now, rnds) {
state.msecs ??= -Infinity;
state.nsecs ??= 0;
if (now === state.msecs) {
state.nsecs++;
if (state.nsecs >= 10000) {
state.node = undefined;
state.nsecs = 0;
}
}
else if (now > state.msecs) {
state.nsecs = 0;
}
else if (now < state.msecs) {
state.node = undefined;
}
if (!state.node) {
state.node = rnds.slice(10, 16);
state.node[0] |= 0x01;
state.clockseq = ((rnds[8] << 8) | rnds[9]) & 0x3fff;
}
state.msecs = now;
return state;
}
exports.updateV1State = updateV1State;
function v1Bytes(rnds, msecs, nsecs, clockseq, node, buf, offset = 0) {
if (rnds.length < 16) {
throw new Error('Random bytes length must be >= 16');
}
if (!buf) {
buf = new Uint8Array(16);
offset = 0;
}
else {
if (offset < 0 || offset + 16 > buf.length) {
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
}
}
msecs ??= Date.now();
nsecs ??= 0;
clockseq ??= ((rnds[8] << 8) | rnds[9]) & 0x3fff;
node ??= rnds.slice(10, 16);
msecs += 12219292800000;
const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
buf[offset++] = (tl >>> 24) & 0xff;
buf[offset++] = (tl >>> 16) & 0xff;
buf[offset++] = (tl >>> 8) & 0xff;
buf[offset++] = tl & 0xff;
const tmh = ((msecs / 0x100000000) * 10000) & 0xfffffff;
buf[offset++] = (tmh >>> 8) & 0xff;
buf[offset++] = tmh & 0xff;
buf[offset++] = ((tmh >>> 24) & 0xf) | 0x10;
buf[offset++] = (tmh >>> 16) & 0xff;
buf[offset++] = (clockseq >>> 8) | 0x80;
buf[offset++] = clockseq & 0xff;
for (let n = 0; n < 6; ++n) {
buf[offset++] = node[n];
}
return buf;
}
exports.default = v1;

View File

@@ -0,0 +1,2 @@
export default function v1ToV6(uuid: string): string;
export default function v1ToV6(uuid: Uint8Array): Uint8Array;

View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const parse_js_1 = require("./parse.js");
const stringify_js_1 = require("./stringify.js");
function v1ToV6(uuid) {
const v1Bytes = typeof uuid === 'string' ? (0, parse_js_1.default)(uuid) : uuid;
const v6Bytes = _v1ToV6(v1Bytes);
return typeof uuid === 'string' ? (0, stringify_js_1.unsafeStringify)(v6Bytes) : v6Bytes;
}
exports.default = v1ToV6;
function _v1ToV6(v1Bytes) {
return Uint8Array.of(((v1Bytes[6] & 0x0f) << 4) | ((v1Bytes[7] >> 4) & 0x0f), ((v1Bytes[7] & 0x0f) << 4) | ((v1Bytes[4] & 0xf0) >> 4), ((v1Bytes[4] & 0x0f) << 4) | ((v1Bytes[5] & 0xf0) >> 4), ((v1Bytes[5] & 0x0f) << 4) | ((v1Bytes[0] & 0xf0) >> 4), ((v1Bytes[0] & 0x0f) << 4) | ((v1Bytes[1] & 0xf0) >> 4), ((v1Bytes[1] & 0x0f) << 4) | ((v1Bytes[2] & 0xf0) >> 4), 0x60 | (v1Bytes[2] & 0x0f), v1Bytes[3], v1Bytes[8], v1Bytes[9], v1Bytes[10], v1Bytes[11], v1Bytes[12], v1Bytes[13], v1Bytes[14], v1Bytes[15]);
}

View File

@@ -0,0 +1,9 @@
import { UUIDTypes } from './types.js';
export { DNS, URL } from './v35.js';
declare function v3(value: string | Uint8Array, namespace: UUIDTypes, buf?: undefined, offset?: number): string;
declare function v3<TBuf extends Uint8Array = Uint8Array>(value: string | Uint8Array, namespace: UUIDTypes, buf: TBuf, offset?: number): TBuf;
declare namespace v3 {
var DNS: string;
var URL: string;
}
export default v3;

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.URL = exports.DNS = void 0;
const md5_js_1 = require("./md5.js");
const v35_js_1 = require("./v35.js");
var v35_js_2 = require("./v35.js");
Object.defineProperty(exports, "DNS", { enumerable: true, get: function () { return v35_js_2.DNS; } });
Object.defineProperty(exports, "URL", { enumerable: true, get: function () { return v35_js_2.URL; } });
function v3(value, namespace, buf, offset) {
return (0, v35_js_1.default)(0x30, md5_js_1.default, value, namespace, buf, offset);
}
v3.DNS = v35_js_1.DNS;
v3.URL = v35_js_1.URL;
exports.default = v3;

View File

@@ -0,0 +1,7 @@
import { UUIDTypes } from './types.js';
export declare function stringToBytes(str: string): Uint8Array;
export declare const DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
export declare const URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
type HashFunction = (bytes: Uint8Array) => Uint8Array;
export default function v35<TBuf extends Uint8Array = Uint8Array>(version: 0x30 | 0x50, hash: HashFunction, value: string | Uint8Array, namespace: UUIDTypes, buf?: TBuf, offset?: number): UUIDTypes<TBuf>;
export {};

View File

@@ -0,0 +1,41 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.URL = exports.DNS = exports.stringToBytes = void 0;
const parse_js_1 = require("./parse.js");
const stringify_js_1 = require("./stringify.js");
function stringToBytes(str) {
str = unescape(encodeURIComponent(str));
const bytes = new Uint8Array(str.length);
for (let i = 0; i < str.length; ++i) {
bytes[i] = str.charCodeAt(i);
}
return bytes;
}
exports.stringToBytes = stringToBytes;
exports.DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
exports.URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
function v35(version, hash, value, namespace, buf, offset) {
const valueBytes = typeof value === 'string' ? stringToBytes(value) : value;
const namespaceBytes = typeof namespace === 'string' ? (0, parse_js_1.default)(namespace) : namespace;
if (typeof namespace === 'string') {
namespace = (0, parse_js_1.default)(namespace);
}
if (namespace?.length !== 16) {
throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');
}
let bytes = new Uint8Array(16 + valueBytes.length);
bytes.set(namespaceBytes);
bytes.set(valueBytes, namespaceBytes.length);
bytes = hash(bytes);
bytes[6] = (bytes[6] & 0x0f) | version;
bytes[8] = (bytes[8] & 0x3f) | 0x80;
if (buf) {
offset = offset || 0;
for (let i = 0; i < 16; ++i) {
buf[offset + i] = bytes[i];
}
return buf;
}
return (0, stringify_js_1.unsafeStringify)(bytes);
}
exports.default = v35;

View File

@@ -0,0 +1,4 @@
import { Version4Options } from './types.js';
declare function v4(options?: Version4Options, buf?: undefined, offset?: number): string;
declare function v4<TBuf extends Uint8Array = Uint8Array>(options: Version4Options | undefined, buf: TBuf, offset?: number): TBuf;
export default v4;

View File

@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const native_js_1 = require("./native.js");
const rng_js_1 = require("./rng.js");
const stringify_js_1 = require("./stringify.js");
function v4(options, buf, offset) {
if (native_js_1.default.randomUUID && !buf && !options) {
return native_js_1.default.randomUUID();
}
options = options || {};
const rnds = options.random ?? options.rng?.() ?? (0, rng_js_1.default)();
if (rnds.length < 16) {
throw new Error('Random bytes length must be >= 16');
}
rnds[6] = (rnds[6] & 0x0f) | 0x40;
rnds[8] = (rnds[8] & 0x3f) | 0x80;
if (buf) {
offset = offset || 0;
if (offset < 0 || offset + 16 > buf.length) {
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
}
for (let i = 0; i < 16; ++i) {
buf[offset + i] = rnds[i];
}
return buf;
}
return (0, stringify_js_1.unsafeStringify)(rnds);
}
exports.default = v4;

View File

@@ -0,0 +1,9 @@
import { UUIDTypes } from './types.js';
export { DNS, URL } from './v35.js';
declare function v5(value: string | Uint8Array, namespace: UUIDTypes, buf?: undefined, offset?: number): string;
declare function v5<TBuf extends Uint8Array = Uint8Array>(value: string | Uint8Array, namespace: UUIDTypes, buf: TBuf, offset?: number): TBuf;
declare namespace v5 {
var DNS: string;
var URL: string;
}
export default v5;

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.URL = exports.DNS = void 0;
const sha1_js_1 = require("./sha1.js");
const v35_js_1 = require("./v35.js");
var v35_js_2 = require("./v35.js");
Object.defineProperty(exports, "DNS", { enumerable: true, get: function () { return v35_js_2.DNS; } });
Object.defineProperty(exports, "URL", { enumerable: true, get: function () { return v35_js_2.URL; } });
function v5(value, namespace, buf, offset) {
return (0, v35_js_1.default)(0x50, sha1_js_1.default, value, namespace, buf, offset);
}
v5.DNS = v35_js_1.DNS;
v5.URL = v35_js_1.URL;
exports.default = v5;

View File

@@ -0,0 +1,4 @@
import { Version6Options } from './types.js';
declare function v6(options?: Version6Options, buf?: undefined, offset?: number): string;
declare function v6<TBuf extends Uint8Array = Uint8Array>(options: Version6Options | undefined, buf: TBuf, offset?: number): TBuf;
export default v6;

View File

@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const stringify_js_1 = require("./stringify.js");
const v1_js_1 = require("./v1.js");
const v1ToV6_js_1 = require("./v1ToV6.js");
function v6(options, buf, offset) {
options ??= {};
offset ??= 0;
let bytes = (0, v1_js_1.default)({ ...options, _v6: true }, new Uint8Array(16));
bytes = (0, v1ToV6_js_1.default)(bytes);
if (buf) {
for (let i = 0; i < 16; i++) {
buf[offset + i] = bytes[i];
}
return buf;
}
return (0, stringify_js_1.unsafeStringify)(bytes);
}
exports.default = v6;

View File

@@ -0,0 +1,2 @@
export default function v6ToV1(uuid: string): string;
export default function v6ToV1(uuid: Uint8Array): Uint8Array;

View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const parse_js_1 = require("./parse.js");
const stringify_js_1 = require("./stringify.js");
function v6ToV1(uuid) {
const v6Bytes = typeof uuid === 'string' ? (0, parse_js_1.default)(uuid) : uuid;
const v1Bytes = _v6ToV1(v6Bytes);
return typeof uuid === 'string' ? (0, stringify_js_1.unsafeStringify)(v1Bytes) : v1Bytes;
}
exports.default = v6ToV1;
function _v6ToV1(v6Bytes) {
return Uint8Array.of(((v6Bytes[3] & 0x0f) << 4) | ((v6Bytes[4] >> 4) & 0x0f), ((v6Bytes[4] & 0x0f) << 4) | ((v6Bytes[5] & 0xf0) >> 4), ((v6Bytes[5] & 0x0f) << 4) | (v6Bytes[6] & 0x0f), v6Bytes[7], ((v6Bytes[1] & 0x0f) << 4) | ((v6Bytes[2] & 0xf0) >> 4), ((v6Bytes[2] & 0x0f) << 4) | ((v6Bytes[3] & 0xf0) >> 4), 0x10 | ((v6Bytes[0] & 0xf0) >> 4), ((v6Bytes[0] & 0x0f) << 4) | ((v6Bytes[1] & 0xf0) >> 4), v6Bytes[8], v6Bytes[9], v6Bytes[10], v6Bytes[11], v6Bytes[12], v6Bytes[13], v6Bytes[14], v6Bytes[15]);
}

View File

@@ -0,0 +1,9 @@
import { Version7Options } from './types.js';
type V7State = {
msecs?: number;
seq?: number;
};
declare function v7(options?: Version7Options, buf?: undefined, offset?: number): string;
declare function v7<TBuf extends Uint8Array = Uint8Array>(options: Version7Options | undefined, buf: TBuf, offset?: number): TBuf;
export declare function updateV7State(state: V7State, now: number, rnds: Uint8Array): V7State;
export default v7;

View File

@@ -0,0 +1,69 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateV7State = void 0;
const rng_js_1 = require("./rng.js");
const stringify_js_1 = require("./stringify.js");
const _state = {};
function v7(options, buf, offset) {
let bytes;
if (options) {
bytes = v7Bytes(options.random ?? options.rng?.() ?? (0, rng_js_1.default)(), options.msecs, options.seq, buf, offset);
}
else {
const now = Date.now();
const rnds = (0, rng_js_1.default)();
updateV7State(_state, now, rnds);
bytes = v7Bytes(rnds, _state.msecs, _state.seq, buf, offset);
}
return buf ?? (0, stringify_js_1.unsafeStringify)(bytes);
}
function updateV7State(state, now, rnds) {
state.msecs ??= -Infinity;
state.seq ??= 0;
if (now > state.msecs) {
state.seq = (rnds[6] << 23) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9];
state.msecs = now;
}
else {
state.seq = (state.seq + 1) | 0;
if (state.seq === 0) {
state.msecs++;
}
}
return state;
}
exports.updateV7State = updateV7State;
function v7Bytes(rnds, msecs, seq, buf, offset = 0) {
if (rnds.length < 16) {
throw new Error('Random bytes length must be >= 16');
}
if (!buf) {
buf = new Uint8Array(16);
offset = 0;
}
else {
if (offset < 0 || offset + 16 > buf.length) {
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
}
}
msecs ??= Date.now();
seq ??= ((rnds[6] * 0x7f) << 24) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9];
buf[offset++] = (msecs / 0x10000000000) & 0xff;
buf[offset++] = (msecs / 0x100000000) & 0xff;
buf[offset++] = (msecs / 0x1000000) & 0xff;
buf[offset++] = (msecs / 0x10000) & 0xff;
buf[offset++] = (msecs / 0x100) & 0xff;
buf[offset++] = msecs & 0xff;
buf[offset++] = 0x70 | ((seq >>> 28) & 0x0f);
buf[offset++] = (seq >>> 20) & 0xff;
buf[offset++] = 0x80 | ((seq >>> 14) & 0x3f);
buf[offset++] = (seq >>> 6) & 0xff;
buf[offset++] = ((seq << 2) & 0xff) | (rnds[10] & 0x03);
buf[offset++] = rnds[11];
buf[offset++] = rnds[12];
buf[offset++] = rnds[13];
buf[offset++] = rnds[14];
buf[offset++] = rnds[15];
return buf;
}
exports.default = v7;

View File

@@ -0,0 +1,2 @@
declare function validate(uuid: unknown): boolean;
export default validate;

View File

@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const regex_js_1 = require("./regex.js");
function validate(uuid) {
return typeof uuid === 'string' && regex_js_1.default.test(uuid);
}
exports.default = validate;

View File

@@ -0,0 +1,2 @@
declare function version(uuid: string): number;
export default version;

View File

@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const validate_js_1 = require("./validate.js");
function version(uuid) {
if (!(0, validate_js_1.default)(uuid)) {
throw TypeError('Invalid UUID');
}
return parseInt(uuid.slice(14, 15), 16);
}
exports.default = version;

View File

@@ -0,0 +1,15 @@
export type * from './types.js';
export { default as MAX } from './max.js';
export { default as NIL } from './nil.js';
export { default as parse } from './parse.js';
export { default as stringify } from './stringify.js';
export { default as v1 } from './v1.js';
export { default as v1ToV6 } from './v1ToV6.js';
export { default as v3 } from './v3.js';
export { default as v4 } from './v4.js';
export { default as v5 } from './v5.js';
export { default as v6 } from './v6.js';
export { default as v6ToV1 } from './v6ToV1.js';
export { default as v7 } from './v7.js';
export { default as validate } from './validate.js';
export { default as version } from './version.js';

View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.version = exports.validate = exports.v7 = exports.v6ToV1 = exports.v6 = exports.v5 = exports.v4 = exports.v3 = exports.v1ToV6 = exports.v1 = exports.stringify = exports.parse = exports.NIL = exports.MAX = void 0;
var max_js_1 = require("./max.js");
Object.defineProperty(exports, "MAX", { enumerable: true, get: function () { return max_js_1.default; } });
var nil_js_1 = require("./nil.js");
Object.defineProperty(exports, "NIL", { enumerable: true, get: function () { return nil_js_1.default; } });
var parse_js_1 = require("./parse.js");
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parse_js_1.default; } });
var stringify_js_1 = require("./stringify.js");
Object.defineProperty(exports, "stringify", { enumerable: true, get: function () { return stringify_js_1.default; } });
var v1_js_1 = require("./v1.js");
Object.defineProperty(exports, "v1", { enumerable: true, get: function () { return v1_js_1.default; } });
var v1ToV6_js_1 = require("./v1ToV6.js");
Object.defineProperty(exports, "v1ToV6", { enumerable: true, get: function () { return v1ToV6_js_1.default; } });
var v3_js_1 = require("./v3.js");
Object.defineProperty(exports, "v3", { enumerable: true, get: function () { return v3_js_1.default; } });
var v4_js_1 = require("./v4.js");
Object.defineProperty(exports, "v4", { enumerable: true, get: function () { return v4_js_1.default; } });
var v5_js_1 = require("./v5.js");
Object.defineProperty(exports, "v5", { enumerable: true, get: function () { return v5_js_1.default; } });
var v6_js_1 = require("./v6.js");
Object.defineProperty(exports, "v6", { enumerable: true, get: function () { return v6_js_1.default; } });
var v6ToV1_js_1 = require("./v6ToV1.js");
Object.defineProperty(exports, "v6ToV1", { enumerable: true, get: function () { return v6ToV1_js_1.default; } });
var v7_js_1 = require("./v7.js");
Object.defineProperty(exports, "v7", { enumerable: true, get: function () { return v7_js_1.default; } });
var validate_js_1 = require("./validate.js");
Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return validate_js_1.default; } });
var version_js_1 = require("./version.js");
Object.defineProperty(exports, "version", { enumerable: true, get: function () { return version_js_1.default; } });

View File

@@ -0,0 +1,2 @@
declare const _default: "ffffffff-ffff-ffff-ffff-ffffffffffff";
export default _default;

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = 'ffffffff-ffff-ffff-ffff-ffffffffffff';

View File

@@ -0,0 +1,4 @@
/// <reference types="node" />
/// <reference types="node" />
declare function md5(bytes: Uint8Array): Buffer;
export default md5;

View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const crypto_1 = require("crypto");
function md5(bytes) {
if (Array.isArray(bytes)) {
bytes = Buffer.from(bytes);
}
else if (typeof bytes === 'string') {
bytes = Buffer.from(bytes, 'utf8');
}
return (0, crypto_1.createHash)('md5').update(bytes).digest();
}
exports.default = md5;

View File

@@ -0,0 +1,6 @@
/// <reference types="node" />
import { randomUUID } from 'crypto';
declare const _default: {
randomUUID: typeof randomUUID;
};
export default _default;

View File

@@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const crypto_1 = require("crypto");
exports.default = { randomUUID: crypto_1.randomUUID };

View File

@@ -0,0 +1,2 @@
declare const _default: "00000000-0000-0000-0000-000000000000";
export default _default;

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = '00000000-0000-0000-0000-000000000000';

View File

@@ -0,0 +1 @@
{"type":"commonjs"}

View File

@@ -0,0 +1,2 @@
declare function parse(uuid: string): Uint8Array;
export default parse;

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const validate_js_1 = require("./validate.js");
function parse(uuid) {
if (!(0, validate_js_1.default)(uuid)) {
throw TypeError('Invalid UUID');
}
let v;
return Uint8Array.of((v = parseInt(uuid.slice(0, 8), 16)) >>> 24, (v >>> 16) & 0xff, (v >>> 8) & 0xff, v & 0xff, (v = parseInt(uuid.slice(9, 13), 16)) >>> 8, v & 0xff, (v = parseInt(uuid.slice(14, 18), 16)) >>> 8, v & 0xff, (v = parseInt(uuid.slice(19, 23), 16)) >>> 8, v & 0xff, ((v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000) & 0xff, (v / 0x100000000) & 0xff, (v >>> 24) & 0xff, (v >>> 16) & 0xff, (v >>> 8) & 0xff, v & 0xff);
}
exports.default = parse;

View File

@@ -0,0 +1,2 @@
declare const _default: RegExp;
export default _default;

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;

View File

@@ -0,0 +1 @@
export default function rng(): Uint8Array;

View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const crypto_1 = require("crypto");
const rnds8Pool = new Uint8Array(256);
let poolPtr = rnds8Pool.length;
function rng() {
if (poolPtr > rnds8Pool.length - 16) {
(0, crypto_1.randomFillSync)(rnds8Pool);
poolPtr = 0;
}
return rnds8Pool.slice(poolPtr, (poolPtr += 16));
}
exports.default = rng;

View File

@@ -0,0 +1,4 @@
/// <reference types="node" />
/// <reference types="node" />
declare function sha1(bytes: Uint8Array): Buffer;
export default sha1;

Some files were not shown because too many files have changed in this diff Show More