first commit

This commit is contained in:
2024-01-19 11:09:11 +01:00
commit b18af7a943
29473 changed files with 4500547 additions and 0 deletions

22
node_modules/engine.io-client/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2014-2015 Automattic <dev@cloudup.com>
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.

333
node_modules/engine.io-client/README.md generated vendored Normal file
View File

@@ -0,0 +1,333 @@
# Engine.IO client
[![Build Status](https://github.com/socketio/engine.io-client/workflows/CI/badge.svg?branch=main)](https://github.com/socketio/engine.io-client/actions)
[![NPM version](https://badge.fury.io/js/engine.io-client.svg)](http://badge.fury.io/js/engine.io-client)
This is the client for [Engine.IO](http://github.com/socketio/engine.io),
the implementation of transport-based cross-browser/cross-device
bi-directional communication layer for [Socket.IO](http://github.com/socketio/socket.io).
## How to use
### Standalone
You can find an `engine.io.js` file in this repository, which is a
standalone build you can use as follows:
```html
<script src="/path/to/engine.io.js"></script>
<script>
// eio = Socket
const socket = eio('ws://localhost');
socket.on('open', () => {
socket.on('message', (data) => {});
socket.on('close', () => {});
});
</script>
```
### With browserify
Engine.IO is a commonjs module, which means you can include it by using
`require` on the browser and package using [browserify](http://browserify.org/):
1. install the client package
```bash
$ npm install engine.io-client
```
1. write your app code
```js
const { Socket } = require('engine.io-client');
const socket = new Socket('ws://localhost');
socket.on('open', () => {
socket.on('message', (data) => {});
socket.on('close', () => {});
});
```
1. build your app bundle
```bash
$ browserify app.js > bundle.js
```
1. include on your page
```html
<script src="/path/to/bundle.js"></script>
```
### Sending and receiving binary
```html
<script src="/path/to/engine.io.js"></script>
<script>
const socket = eio('ws://localhost/');
socket.binaryType = 'blob';
socket.on('open', () => {
socket.send(new Int8Array(5));
socket.on('message', (blob) => {});
socket.on('close', () => {});
});
</script>
```
### Node.JS
Add `engine.io-client` to your `package.json` and then:
```js
const { Socket } = require('engine.io-client');
const socket = new Socket('ws://localhost');
socket.on('open', () => {
socket.on('message', (data) => {});
socket.on('close', () => {});
});
```
### Node.js with certificates
```js
const opts = {
key: fs.readFileSync('test/fixtures/client.key'),
cert: fs.readFileSync('test/fixtures/client.crt'),
ca: fs.readFileSync('test/fixtures/ca.crt')
};
const { Socket } = require('engine.io-client');
const socket = new Socket('ws://localhost', opts);
socket.on('open', () => {
socket.on('message', (data) => {});
socket.on('close', () => {});
});
```
### Node.js with extraHeaders
```js
const opts = {
extraHeaders: {
'X-Custom-Header-For-My-Project': 'my-secret-access-token',
'Cookie': 'user_session=NI2JlCKF90aE0sJZD9ZzujtdsUqNYSBYxzlTsvdSUe35ZzdtVRGqYFr0kdGxbfc5gUOkR9RGp20GVKza; path=/; expires=Tue, 07-Apr-2015 18:18:08 GMT; secure; HttpOnly'
}
};
const { Socket } = require('engine.io-client');
const socket = new Socket('ws://localhost', opts);
socket.on('open', () => {
socket.on('message', (data) => {});
socket.on('close', () => {});
});
```
In the browser, the [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) object does not support additional headers.
In case you want to add some headers as part of some authentication mechanism, you can use the `transportOptions` attribute.
Please note that in this case the headers won't be sent in the WebSocket upgrade request.
```js
// WILL NOT WORK in the browser
const socket = new Socket('http://localhost', {
extraHeaders: {
'X-Custom-Header-For-My-Project': 'will not be sent'
}
});
// WILL NOT WORK
const socket = new Socket('http://localhost', {
transports: ['websocket'], // polling is disabled
transportOptions: {
polling: {
extraHeaders: {
'X-Custom-Header-For-My-Project': 'will not be sent'
}
}
}
});
// WILL WORK
const socket = new Socket('http://localhost', {
transports: ['polling', 'websocket'],
transportOptions: {
polling: {
extraHeaders: {
'X-Custom-Header-For-My-Project': 'will be used'
}
}
}
});
```
## Features
- Lightweight
- Runs on browser and node.js seamlessly
- Transports are independent of `Engine`
- Easy to debug
- Easy to unit test
- Runs inside HTML5 WebWorker
- Can send and receive binary data
- Receives as ArrayBuffer or Blob when in browser, and Buffer or ArrayBuffer
in Node
- When XHR2 or WebSockets are used, binary is emitted directly. Otherwise
binary is encoded into base64 strings, and decoded when binary types are
supported.
- With browsers that don't support ArrayBuffer, an object { base64: true,
data: dataAsBase64String } is emitted on the `message` event.
## API
### Socket
The client class. Mixes in [Emitter](http://github.com/component/emitter).
Exposed as `eio` in the browser standalone build.
#### Properties
- `protocol` _(Number)_: protocol revision number
- `binaryType` _(String)_ : can be set to 'arraybuffer' or 'blob' in browsers,
and `buffer` or `arraybuffer` in Node. Blob is only used in browser if it's
supported.
#### Events
- `open`
- Fired upon successful connection.
- `message`
- Fired when data is received from the server.
- **Arguments**
- `String` | `ArrayBuffer`: utf-8 encoded data or ArrayBuffer containing
binary data
- `close`
- Fired upon disconnection. In compliance with the WebSocket API spec, this event may be
fired even if the `open` event does not occur (i.e. due to connection error or `close()`).
- `error`
- Fired when an error occurs.
- `flush`
- Fired upon completing a buffer flush
- `drain`
- Fired after `drain` event of transport if writeBuffer is empty
- `upgradeError`
- Fired if an error occurs with a transport we're trying to upgrade to.
- `upgrade`
- Fired upon upgrade success, after the new transport is set
- `ping`
- Fired upon receiving a ping packet.
- `pong`
- Fired upon _flushing_ a pong packet (ie: actual packet write out)
#### Methods
- **constructor**
- Initializes the client
- **Parameters**
- `String` uri
- `Object`: optional, options object
- **Options**
- `agent` (`http.Agent`): `http.Agent` to use, defaults to `false` (NodeJS only)
- `upgrade` (`Boolean`): defaults to true, whether the client should try
to upgrade the transport from long-polling to something better.
- `forceBase64` (`Boolean`): forces base 64 encoding for polling transport even when XHR2 responseType is available and WebSocket even if the used standard supports binary.
- `withCredentials` (`Boolean`): defaults to `false`, whether to include credentials (cookies, authorization headers, TLS client certificates, etc.) with cross-origin XHR polling requests.
- `timestampRequests` (`Boolean`): whether to add the timestamp with each
transport request. Note: polling requests are always stamped unless this
option is explicitly set to `false` (`false`)
- `timestampParam` (`String`): timestamp parameter (`t`)
- `path` (`String`): path to connect to, default is `/engine.io`
- `transports` (`Array`): a list of transports to try (in order).
Defaults to `['polling', 'websocket', 'webtransport']`. `Engine`
always attempts to connect directly with the first one, provided the
feature detection test for it passes.
- `transportOptions` (`Object`): hash of options, indexed by transport name, overriding the common options for the given transport
- `rememberUpgrade` (`Boolean`): defaults to false.
If true and if the previous websocket connection to the server succeeded,
the connection attempt will bypass the normal upgrade process and will initially
try websocket. A connection attempt following a transport error will use the
normal upgrade process. It is recommended you turn this on only when using
SSL/TLS connections, or if you know that your network does not block websockets.
- `pfx` (`String`|`Buffer`): Certificate, Private key and CA certificates to use for SSL. Can be used in Node.js client environment to manually specify certificate information.
- `key` (`String`): Private key to use for SSL. Can be used in Node.js client environment to manually specify certificate information.
- `passphrase` (`String`): A string of passphrase for the private key or pfx. Can be used in Node.js client environment to manually specify certificate information.
- `cert` (`String`): Public x509 certificate to use. Can be used in Node.js client environment to manually specify certificate information.
- `ca` (`String`|`Array`): An authority certificate or array of authority certificates to check the remote host against.. Can be used in Node.js client environment to manually specify certificate information.
- `ciphers` (`String`): A string describing the ciphers to use or exclude. Consult the [cipher format list](http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT) for details on the format. Can be used in Node.js client environment to manually specify certificate information.
- `rejectUnauthorized` (`Boolean`): If true, the server certificate is verified against the list of supplied CAs. An 'error' event is emitted if verification fails. Verification happens at the connection level, before the HTTP request is sent. Can be used in Node.js client environment to manually specify certificate information.
- `perMessageDeflate` (`Object|Boolean`): parameters of the WebSocket permessage-deflate extension
(see [ws module](https://github.com/einaros/ws) api docs). Set to `false` to disable. (`true`)
- `threshold` (`Number`): data is compressed only if the byte size is above this value. This option is ignored on the browser. (`1024`)
- `extraHeaders` (`Object`): Headers that will be passed for each request to the server (via xhr-polling and via websockets). These values then can be used during handshake or for special proxies. Can only be used in Node.js client environment.
- `onlyBinaryUpgrades` (`Boolean`): whether transport upgrades should be restricted to transports supporting binary data (`false`)
- `forceNode` (`Boolean`): Uses NodeJS implementation for websockets - even if there is a native Browser-Websocket available, which is preferred by default over the NodeJS implementation. (This is useful when using hybrid platforms like nw.js or electron) (`false`, NodeJS only)
- `localAddress` (`String`): the local IP address to connect to
- `autoUnref` (`Boolean`): whether the transport should be `unref`'d upon creation. This calls `unref` on the underlying timers and sockets so that the program is allowed to exit if they are the only timers/sockets in the event system (Node.js only)
- `useNativeTimers` (`Boolean`): Whether to always use the native timeouts. This allows the client to reconnect when the native timeout functions are overridden, such as when mock clocks are installed with [`@sinonjs/fake-timers`](https://github.com/sinonjs/fake-timers).
- **Polling-only options**
- `requestTimeout` (`Number`): Timeout for xhr-polling requests in milliseconds (`0`)
- **Websocket-only options**
- `protocols` (`Array`): a list of subprotocols (see [MDN reference](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#Subprotocols))
- `closeOnBeforeunload` (`Boolean`): whether to silently close the connection when the [`beforeunload`](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event) event is emitted in the browser (defaults to `false`)
- `send`
- Sends a message to the server
- **Parameters**
- `String` | `ArrayBuffer` | `ArrayBufferView` | `Blob`: data to send
- `Object`: optional, options object
- `Function`: optional, callback upon `drain`
- **Options**
- `compress` (`Boolean`): whether to compress sending data. This option is ignored and forced to be `true` on the browser. (`true`)
- `close`
- Disconnects the client.
### Transport
The transport class. Private. _Inherits from EventEmitter_.
#### Events
- `poll`: emitted by polling transports upon starting a new request
- `pollComplete`: emitted by polling transports upon completing a request
- `drain`: emitted by polling transports upon a buffer drain
## Tests
`engine.io-client` is used to test
[engine](http://github.com/socketio/engine.io). Running the `engine.io`
test suite ensures the client works and vice-versa.
Browser tests are run using [zuul](https://github.com/defunctzombie/zuul). You can
run the tests locally using the following command.
```
./node_modules/.bin/zuul --local 8080 -- test/index.js
```
Additionally, `engine.io-client` has a standalone test suite you can run
with `make test` which will run node.js and browser tests. You must have zuul setup with
a saucelabs account.
## Support
The support channels for `engine.io-client` are the same as `socket.io`:
- irc.freenode.net **#socket.io**
- [Google Groups](http://groups.google.com/group/socket_io)
- [Website](http://socket.io)
## Development
To contribute patches, run tests or benchmarks, make sure to clone the
repository:
```bash
git clone git://github.com/socketio/engine.io-client.git
```
Then:
```bash
cd engine.io-client
npm install
```
See the `Tests` section above for how to run tests before submitting any patches.
## License
MIT - Copyright (c) 2014 Automattic, Inc.

View File

@@ -0,0 +1,3 @@
import { Socket } from "./socket.js";
declare const _default: (uri: any, opts: any) => Socket;
export default _default;

View File

@@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const socket_js_1 = require("./socket.js");
exports.default = (uri, opts) => new socket_js_1.Socket(uri, opts);

View File

@@ -0,0 +1 @@
export declare const hasCORS: boolean;

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hasCORS = void 0;
// imported from https://github.com/component/has-cors
let value = false;
try {
value = typeof XMLHttpRequest !== 'undefined' &&
'withCredentials' in new XMLHttpRequest();
}
catch (err) {
// if XMLHttp support is disabled in IE then it will throw
// when trying to create
}
exports.hasCORS = value;

View File

@@ -0,0 +1,15 @@
/**
* Compiles a querystring
* Returns string representation of the object
*
* @param {Object}
* @api private
*/
export declare function encode(obj: any): string;
/**
* Parses a simple querystring into an object
*
* @param {String} qs
* @api private
*/
export declare function decode(qs: any): {};

View File

@@ -0,0 +1,39 @@
"use strict";
// imported from https://github.com/galkn/querystring
/**
* Compiles a querystring
* Returns string representation of the object
*
* @param {Object}
* @api private
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.decode = exports.encode = void 0;
function encode(obj) {
let str = '';
for (let i in obj) {
if (obj.hasOwnProperty(i)) {
if (str.length)
str += '&';
str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
}
}
return str;
}
exports.encode = encode;
/**
* Parses a simple querystring into an object
*
* @param {String} qs
* @api private
*/
function decode(qs) {
let qry = {};
let pairs = qs.split('&');
for (let i = 0, l = pairs.length; i < l; i++) {
let pair = pairs[i].split('=');
qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return qry;
}
exports.decode = decode;

View File

@@ -0,0 +1 @@
export declare function parse(str: string): any;

View File

@@ -0,0 +1,68 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = void 0;
// imported from https://github.com/galkn/parseuri
/**
* Parses a URI
*
* Note: we could also have used the built-in URL object, but it isn't supported on all platforms.
*
* See:
* - https://developer.mozilla.org/en-US/docs/Web/API/URL
* - https://caniuse.com/url
* - https://www.rfc-editor.org/rfc/rfc3986#appendix-B
*
* History of the parse() method:
* - first commit: https://github.com/socketio/socket.io-client/commit/4ee1d5d94b3906a9c052b459f1a818b15f38f91c
* - export into its own module: https://github.com/socketio/engine.io-client/commit/de2c561e4564efeb78f1bdb1ba39ef81b2822cb3
* - reimport: https://github.com/socketio/engine.io-client/commit/df32277c3f6d622eec5ed09f493cae3f3391d242
*
* @author Steven Levithan <stevenlevithan.com> (MIT license)
* @api private
*/
const re = /^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
const parts = [
'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
];
function parse(str) {
if (str.length > 2000) {
throw "URI too long";
}
const src = str, b = str.indexOf('['), e = str.indexOf(']');
if (b != -1 && e != -1) {
str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
}
let m = re.exec(str || ''), uri = {}, i = 14;
while (i--) {
uri[parts[i]] = m[i] || '';
}
if (b != -1 && e != -1) {
uri.source = src;
uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
uri.ipv6uri = true;
}
uri.pathNames = pathNames(uri, uri['path']);
uri.queryKey = queryKey(uri, uri['query']);
return uri;
}
exports.parse = parse;
function pathNames(obj, path) {
const regx = /\/{2,9}/g, names = path.replace(regx, "/").split("/");
if (path.slice(0, 1) == '/' || path.length === 0) {
names.splice(0, 1);
}
if (path.slice(-1) == '/') {
names.splice(names.length - 1, 1);
}
return names;
}
function queryKey(uri, query) {
const data = {};
query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) {
if ($1) {
data[$1] = $2;
}
});
return data;
}

View File

@@ -0,0 +1,23 @@
/**
* Return a string representing the specified number.
*
* @param {Number} num The number to convert.
* @returns {String} The string representation of the number.
* @api public
*/
export declare function encode(num: any): string;
/**
* Return the integer value specified by the given string.
*
* @param {String} str The string to convert.
* @returns {Number} The integer value represented by the string.
* @api public
*/
export declare function decode(str: any): number;
/**
* Yeast: A tiny growing id generator.
*
* @returns {String} A unique id.
* @api public
*/
export declare function yeast(): string;

View File

@@ -0,0 +1,55 @@
// imported from https://github.com/unshiftio/yeast
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.yeast = exports.decode = exports.encode = void 0;
const alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split(''), length = 64, map = {};
let seed = 0, i = 0, prev;
/**
* Return a string representing the specified number.
*
* @param {Number} num The number to convert.
* @returns {String} The string representation of the number.
* @api public
*/
function encode(num) {
let encoded = '';
do {
encoded = alphabet[num % length] + encoded;
num = Math.floor(num / length);
} while (num > 0);
return encoded;
}
exports.encode = encode;
/**
* Return the integer value specified by the given string.
*
* @param {String} str The string to convert.
* @returns {Number} The integer value represented by the string.
* @api public
*/
function decode(str) {
let decoded = 0;
for (i = 0; i < str.length; i++) {
decoded = decoded * length + map[str.charAt(i)];
}
return decoded;
}
exports.decode = decode;
/**
* Yeast: A tiny growing id generator.
*
* @returns {String} A unique id.
* @api public
*/
function yeast() {
const now = encode(+new Date());
if (now !== prev)
return seed = 0, prev = now;
return now + '.' + encode(seed++);
}
exports.yeast = yeast;
//
// Map each character to its index.
//
for (; i < length; i++)
map[alphabet[i]] = i;

View File

@@ -0,0 +1 @@
export declare const globalThisShim: any;

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.globalThisShim = void 0;
exports.globalThisShim = (() => {
if (typeof self !== "undefined") {
return self;
}
else if (typeof window !== "undefined") {
return window;
}
else {
return Function("return this")();
}
})();

View File

@@ -0,0 +1 @@
export declare const globalThisShim: typeof globalThis;

View File

@@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.globalThisShim = void 0;
exports.globalThisShim = global;

9
node_modules/engine.io-client/build/cjs/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
import { Socket } from "./socket.js";
export { Socket };
export { SocketOptions } from "./socket.js";
export declare const protocol: number;
export { Transport, TransportError } from "./transport.js";
export { transports } from "./transports/index.js";
export { installTimerFunctions } from "./util.js";
export { parse } from "./contrib/parseuri.js";
export { nextTick } from "./transports/websocket-constructor.js";

17
node_modules/engine.io-client/build/cjs/index.js generated vendored Normal file
View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.nextTick = exports.parse = exports.installTimerFunctions = exports.transports = exports.TransportError = exports.Transport = exports.protocol = exports.Socket = void 0;
const socket_js_1 = require("./socket.js");
Object.defineProperty(exports, "Socket", { enumerable: true, get: function () { return socket_js_1.Socket; } });
exports.protocol = socket_js_1.Socket.protocol;
var transport_js_1 = require("./transport.js");
Object.defineProperty(exports, "Transport", { enumerable: true, get: function () { return transport_js_1.Transport; } });
Object.defineProperty(exports, "TransportError", { enumerable: true, get: function () { return transport_js_1.TransportError; } });
var index_js_1 = require("./transports/index.js");
Object.defineProperty(exports, "transports", { enumerable: true, get: function () { return index_js_1.transports; } });
var util_js_1 = require("./util.js");
Object.defineProperty(exports, "installTimerFunctions", { enumerable: true, get: function () { return util_js_1.installTimerFunctions; } });
var parseuri_js_1 = require("./contrib/parseuri.js");
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parseuri_js_1.parse; } });
var websocket_constructor_js_1 = require("./transports/websocket-constructor.js");
Object.defineProperty(exports, "nextTick", { enumerable: true, get: function () { return websocket_constructor_js_1.nextTick; } });

10
node_modules/engine.io-client/build/cjs/package.json generated vendored Normal file
View File

@@ -0,0 +1,10 @@
{
"name": "engine.io-client",
"type": "commonjs",
"browser": {
"ws": false,
"./transports/xmlhttprequest.js": "./transports/xmlhttprequest.browser.js",
"./transports/websocket-constructor.js": "./transports/websocket-constructor.browser.js",
"./globalThis.js": "./globalThis.browser.js"
}
}

362
node_modules/engine.io-client/build/cjs/socket.d.ts generated vendored Normal file
View File

@@ -0,0 +1,362 @@
import { Emitter } from "@socket.io/component-emitter";
import type { Packet, BinaryType, RawData } from "engine.io-parser";
import { CloseDetails, Transport } from "./transport.js";
export interface SocketOptions {
/**
* The host that we're connecting to. Set from the URI passed when connecting
*/
host: string;
/**
* The hostname for our connection. Set from the URI passed when connecting
*/
hostname: string;
/**
* If this is a secure connection. Set from the URI passed when connecting
*/
secure: boolean;
/**
* The port for our connection. Set from the URI passed when connecting
*/
port: string | number;
/**
* Any query parameters in our uri. Set from the URI passed when connecting
*/
query: {
[key: string]: any;
};
/**
* `http.Agent` to use, defaults to `false` (NodeJS only)
*
* Note: the type should be "undefined | http.Agent | https.Agent | false", but this would break browser-only clients.
*
* @see https://nodejs.org/api/http.html#httprequestoptions-callback
*/
agent: string | boolean;
/**
* Whether the client should try to upgrade the transport from
* long-polling to something better.
* @default true
*/
upgrade: boolean;
/**
* Forces base 64 encoding for polling transport even when XHR2
* responseType is available and WebSocket even if the used standard
* supports binary.
*/
forceBase64: boolean;
/**
* The param name to use as our timestamp key
* @default 't'
*/
timestampParam: string;
/**
* Whether to add the timestamp with each transport request. Note: this
* is ignored if the browser is IE or Android, in which case requests
* are always stamped
* @default false
*/
timestampRequests: boolean;
/**
* A list of transports to try (in order). Engine.io always attempts to
* connect directly with the first one, provided the feature detection test
* for it passes.
*
* @default ['polling','websocket', 'webtransport']
*/
transports: string[];
/**
* If true and if the previous websocket connection to the server succeeded,
* the connection attempt will bypass the normal upgrade process and will
* initially try websocket. A connection attempt following a transport error
* will use the normal upgrade process. It is recommended you turn this on
* only when using SSL/TLS connections, or if you know that your network does
* not block websockets.
* @default false
*/
rememberUpgrade: boolean;
/**
* Are we only interested in transports that support binary?
*/
onlyBinaryUpgrades: boolean;
/**
* Timeout for xhr-polling requests in milliseconds (0) (only for polling transport)
*/
requestTimeout: number;
/**
* Transport options for Node.js client (headers etc)
*/
transportOptions: Object;
/**
* (SSL) Certificate, Private key and CA certificates to use for SSL.
* Can be used in Node.js client environment to manually specify
* certificate information.
*/
pfx: string;
/**
* (SSL) Private key to use for SSL. Can be used in Node.js client
* environment to manually specify certificate information.
*/
key: string;
/**
* (SSL) A string or passphrase for the private key or pfx. Can be
* used in Node.js client environment to manually specify certificate
* information.
*/
passphrase: string;
/**
* (SSL) Public x509 certificate to use. Can be used in Node.js client
* environment to manually specify certificate information.
*/
cert: string;
/**
* (SSL) An authority certificate or array of authority certificates to
* check the remote host against.. Can be used in Node.js client
* environment to manually specify certificate information.
*/
ca: string | string[];
/**
* (SSL) A string describing the ciphers to use or exclude. Consult the
* [cipher format list]
* (http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT) for
* details on the format.. Can be used in Node.js client environment to
* manually specify certificate information.
*/
ciphers: string;
/**
* (SSL) If true, the server certificate is verified against the list of
* supplied CAs. An 'error' event is emitted if verification fails.
* Verification happens at the connection level, before the HTTP request
* is sent. Can be used in Node.js client environment to manually specify
* certificate information.
*/
rejectUnauthorized: boolean;
/**
* Headers that will be passed for each request to the server (via xhr-polling and via websockets).
* These values then can be used during handshake or for special proxies.
*/
extraHeaders?: {
[header: string]: string;
};
/**
* Whether to include credentials (cookies, authorization headers, TLS
* client certificates, etc.) with cross-origin XHR polling requests
* @default false
*/
withCredentials: boolean;
/**
* Whether to automatically close the connection whenever the beforeunload event is received.
* @default false
*/
closeOnBeforeunload: boolean;
/**
* Whether to always use the native timeouts. This allows the client to
* reconnect when the native timeout functions are overridden, such as when
* mock clocks are installed.
* @default false
*/
useNativeTimers: boolean;
/**
* weather we should unref the reconnect timer when it is
* create automatically
* @default false
*/
autoUnref: boolean;
/**
* parameters of the WebSocket permessage-deflate extension (see ws module api docs). Set to false to disable.
* @default false
*/
perMessageDeflate: {
threshold: number;
};
/**
* The path to get our client file from, in the case of the server
* serving it
* @default '/engine.io'
*/
path: string;
/**
* Whether we should add a trailing slash to the request path.
* @default true
*/
addTrailingSlash: boolean;
/**
* Either a single protocol string or an array of protocol strings. These strings are used to indicate sub-protocols,
* so that a single server can implement multiple WebSocket sub-protocols (for example, you might want one server to
* be able to handle different types of interactions depending on the specified protocol)
* @default []
*/
protocols: string | string[];
}
interface HandshakeData {
sid: string;
upgrades: string[];
pingInterval: number;
pingTimeout: number;
maxPayload: number;
}
interface SocketReservedEvents {
open: () => void;
handshake: (data: HandshakeData) => void;
packet: (packet: Packet) => void;
packetCreate: (packet: Packet) => void;
data: (data: any) => void;
message: (data: any) => void;
drain: () => void;
flush: () => void;
heartbeat: () => void;
ping: () => void;
pong: () => void;
error: (err: string | Error) => void;
upgrading: (transport: any) => void;
upgrade: (transport: any) => void;
upgradeError: (err: Error) => void;
close: (reason: string, description?: CloseDetails | Error) => void;
}
type SocketState = "opening" | "open" | "closing" | "closed";
export declare class Socket extends Emitter<Record<never, never>, Record<never, never>, SocketReservedEvents> {
id: string;
transport: Transport;
binaryType: BinaryType;
readyState: SocketState;
writeBuffer: Packet[];
private prevBufferLen;
private upgrades;
private pingInterval;
private pingTimeout;
private pingTimeoutTimer;
private setTimeoutFn;
private clearTimeoutFn;
private readonly beforeunloadEventListener;
private readonly offlineEventListener;
private upgrading;
private maxPayload?;
private readonly opts;
private readonly secure;
private readonly hostname;
private readonly port;
private readonly transports;
static priorWebsocketSuccess: boolean;
static protocol: number;
/**
* Socket constructor.
*
* @param {String|Object} uri - uri or options
* @param {Object} opts - options
*/
constructor(uri: any, opts?: Partial<SocketOptions>);
/**
* Creates transport of the given type.
*
* @param {String} name - transport name
* @return {Transport}
* @private
*/
private createTransport;
/**
* Initializes transport to use and starts probe.
*
* @private
*/
private open;
/**
* Sets the current transport. Disables the existing one (if any).
*
* @private
*/
private setTransport;
/**
* Probes a transport.
*
* @param {String} name - transport name
* @private
*/
private probe;
/**
* Called when connection is deemed open.
*
* @private
*/
private onOpen;
/**
* Handles a packet.
*
* @private
*/
private onPacket;
/**
* Called upon handshake completion.
*
* @param {Object} data - handshake obj
* @private
*/
private onHandshake;
/**
* Sets and resets ping timeout timer based on server pings.
*
* @private
*/
private resetPingTimeout;
/**
* Called on `drain` event
*
* @private
*/
private onDrain;
/**
* Flush write buffers.
*
* @private
*/
private flush;
/**
* Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP
* long-polling)
*
* @private
*/
private getWritablePackets;
/**
* Sends a message.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} callback function.
* @return {Socket} for chaining.
*/
write(msg: RawData, options?: any, fn?: any): this;
send(msg: RawData, options?: any, fn?: any): this;
/**
* Sends a packet.
*
* @param {String} type: packet type.
* @param {String} data.
* @param {Object} options.
* @param {Function} fn - callback function.
* @private
*/
private sendPacket;
/**
* Closes the connection.
*/
close(): this;
/**
* Called upon transport error
*
* @private
*/
private onError;
/**
* Called upon transport close.
*
* @private
*/
private onClose;
/**
* Filters upgrades, returning only those matching client transports.
*
* @param {Array} upgrades - server upgrades
* @private
*/
private filterUpgrades;
}
export {};

626
node_modules/engine.io-client/build/cjs/socket.js generated vendored Normal file
View File

@@ -0,0 +1,626 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Socket = void 0;
const index_js_1 = require("./transports/index.js");
const util_js_1 = require("./util.js");
const parseqs_js_1 = require("./contrib/parseqs.js");
const parseuri_js_1 = require("./contrib/parseuri.js");
const debug_1 = __importDefault(require("debug")); // debug()
const component_emitter_1 = require("@socket.io/component-emitter");
const engine_io_parser_1 = require("engine.io-parser");
const websocket_constructor_js_1 = require("./transports/websocket-constructor.js");
const debug = (0, debug_1.default)("engine.io-client:socket"); // debug()
class Socket extends component_emitter_1.Emitter {
/**
* Socket constructor.
*
* @param {String|Object} uri - uri or options
* @param {Object} opts - options
*/
constructor(uri, opts = {}) {
super();
this.binaryType = websocket_constructor_js_1.defaultBinaryType;
this.writeBuffer = [];
if (uri && "object" === typeof uri) {
opts = uri;
uri = null;
}
if (uri) {
uri = (0, parseuri_js_1.parse)(uri);
opts.hostname = uri.host;
opts.secure = uri.protocol === "https" || uri.protocol === "wss";
opts.port = uri.port;
if (uri.query)
opts.query = uri.query;
}
else if (opts.host) {
opts.hostname = (0, parseuri_js_1.parse)(opts.host).host;
}
(0, util_js_1.installTimerFunctions)(this, opts);
this.secure =
null != opts.secure
? opts.secure
: typeof location !== "undefined" && "https:" === location.protocol;
if (opts.hostname && !opts.port) {
// if no port is specified manually, use the protocol default
opts.port = this.secure ? "443" : "80";
}
this.hostname =
opts.hostname ||
(typeof location !== "undefined" ? location.hostname : "localhost");
this.port =
opts.port ||
(typeof location !== "undefined" && location.port
? location.port
: this.secure
? "443"
: "80");
this.transports = opts.transports || [
"polling",
"websocket",
"webtransport",
];
this.writeBuffer = [];
this.prevBufferLen = 0;
this.opts = Object.assign({
path: "/engine.io",
agent: false,
withCredentials: false,
upgrade: true,
timestampParam: "t",
rememberUpgrade: false,
addTrailingSlash: true,
rejectUnauthorized: true,
perMessageDeflate: {
threshold: 1024,
},
transportOptions: {},
closeOnBeforeunload: false,
}, opts);
this.opts.path =
this.opts.path.replace(/\/$/, "") +
(this.opts.addTrailingSlash ? "/" : "");
if (typeof this.opts.query === "string") {
this.opts.query = (0, parseqs_js_1.decode)(this.opts.query);
}
// set on handshake
this.id = null;
this.upgrades = null;
this.pingInterval = null;
this.pingTimeout = null;
// set on heartbeat
this.pingTimeoutTimer = null;
if (typeof addEventListener === "function") {
if (this.opts.closeOnBeforeunload) {
// Firefox closes the connection when the "beforeunload" event is emitted but not Chrome. This event listener
// ensures every browser behaves the same (no "disconnect" event at the Socket.IO level when the page is
// closed/reloaded)
this.beforeunloadEventListener = () => {
if (this.transport) {
// silently close the transport
this.transport.removeAllListeners();
this.transport.close();
}
};
addEventListener("beforeunload", this.beforeunloadEventListener, false);
}
if (this.hostname !== "localhost") {
this.offlineEventListener = () => {
this.onClose("transport close", {
description: "network connection lost",
});
};
addEventListener("offline", this.offlineEventListener, false);
}
}
this.open();
}
/**
* Creates transport of the given type.
*
* @param {String} name - transport name
* @return {Transport}
* @private
*/
createTransport(name) {
debug('creating transport "%s"', name);
const query = Object.assign({}, this.opts.query);
// append engine.io protocol identifier
query.EIO = engine_io_parser_1.protocol;
// transport name
query.transport = name;
// session id if we already have one
if (this.id)
query.sid = this.id;
const opts = Object.assign({}, this.opts, {
query,
socket: this,
hostname: this.hostname,
secure: this.secure,
port: this.port,
}, this.opts.transportOptions[name]);
debug("options: %j", opts);
return new index_js_1.transports[name](opts);
}
/**
* Initializes transport to use and starts probe.
*
* @private
*/
open() {
let transport;
if (this.opts.rememberUpgrade &&
Socket.priorWebsocketSuccess &&
this.transports.indexOf("websocket") !== -1) {
transport = "websocket";
}
else if (0 === this.transports.length) {
// Emit error on next tick so it can be listened to
this.setTimeoutFn(() => {
this.emitReserved("error", "No transports available");
}, 0);
return;
}
else {
transport = this.transports[0];
}
this.readyState = "opening";
// Retry with the next transport if the transport is disabled (jsonp: false)
try {
transport = this.createTransport(transport);
}
catch (e) {
debug("error while creating transport: %s", e);
this.transports.shift();
this.open();
return;
}
transport.open();
this.setTransport(transport);
}
/**
* Sets the current transport. Disables the existing one (if any).
*
* @private
*/
setTransport(transport) {
debug("setting transport %s", transport.name);
if (this.transport) {
debug("clearing existing transport %s", this.transport.name);
this.transport.removeAllListeners();
}
// set up transport
this.transport = transport;
// set up transport listeners
transport
.on("drain", this.onDrain.bind(this))
.on("packet", this.onPacket.bind(this))
.on("error", this.onError.bind(this))
.on("close", (reason) => this.onClose("transport close", reason));
}
/**
* Probes a transport.
*
* @param {String} name - transport name
* @private
*/
probe(name) {
debug('probing transport "%s"', name);
let transport = this.createTransport(name);
let failed = false;
Socket.priorWebsocketSuccess = false;
const onTransportOpen = () => {
if (failed)
return;
debug('probe transport "%s" opened', name);
transport.send([{ type: "ping", data: "probe" }]);
transport.once("packet", (msg) => {
if (failed)
return;
if ("pong" === msg.type && "probe" === msg.data) {
debug('probe transport "%s" pong', name);
this.upgrading = true;
this.emitReserved("upgrading", transport);
if (!transport)
return;
Socket.priorWebsocketSuccess = "websocket" === transport.name;
debug('pausing current transport "%s"', this.transport.name);
this.transport.pause(() => {
if (failed)
return;
if ("closed" === this.readyState)
return;
debug("changing transport and sending upgrade packet");
cleanup();
this.setTransport(transport);
transport.send([{ type: "upgrade" }]);
this.emitReserved("upgrade", transport);
transport = null;
this.upgrading = false;
this.flush();
});
}
else {
debug('probe transport "%s" failed', name);
const err = new Error("probe error");
// @ts-ignore
err.transport = transport.name;
this.emitReserved("upgradeError", err);
}
});
};
function freezeTransport() {
if (failed)
return;
// Any callback called by transport should be ignored since now
failed = true;
cleanup();
transport.close();
transport = null;
}
// Handle any error that happens while probing
const onerror = (err) => {
const error = new Error("probe error: " + err);
// @ts-ignore
error.transport = transport.name;
freezeTransport();
debug('probe transport "%s" failed because of error: %s', name, err);
this.emitReserved("upgradeError", error);
};
function onTransportClose() {
onerror("transport closed");
}
// When the socket is closed while we're probing
function onclose() {
onerror("socket closed");
}
// When the socket is upgraded while we're probing
function onupgrade(to) {
if (transport && to.name !== transport.name) {
debug('"%s" works - aborting "%s"', to.name, transport.name);
freezeTransport();
}
}
// Remove all listeners on the transport and on self
const cleanup = () => {
transport.removeListener("open", onTransportOpen);
transport.removeListener("error", onerror);
transport.removeListener("close", onTransportClose);
this.off("close", onclose);
this.off("upgrading", onupgrade);
};
transport.once("open", onTransportOpen);
transport.once("error", onerror);
transport.once("close", onTransportClose);
this.once("close", onclose);
this.once("upgrading", onupgrade);
if (this.upgrades.indexOf("webtransport") !== -1 &&
name !== "webtransport") {
// favor WebTransport
this.setTimeoutFn(() => {
if (!failed) {
transport.open();
}
}, 200);
}
else {
transport.open();
}
}
/**
* Called when connection is deemed open.
*
* @private
*/
onOpen() {
debug("socket open");
this.readyState = "open";
Socket.priorWebsocketSuccess = "websocket" === this.transport.name;
this.emitReserved("open");
this.flush();
// we check for `readyState` in case an `open`
// listener already closed the socket
if ("open" === this.readyState && this.opts.upgrade) {
debug("starting upgrade probes");
let i = 0;
const l = this.upgrades.length;
for (; i < l; i++) {
this.probe(this.upgrades[i]);
}
}
}
/**
* Handles a packet.
*
* @private
*/
onPacket(packet) {
if ("opening" === this.readyState ||
"open" === this.readyState ||
"closing" === this.readyState) {
debug('socket receive: type "%s", data "%s"', packet.type, packet.data);
this.emitReserved("packet", packet);
// Socket is live - any packet counts
this.emitReserved("heartbeat");
this.resetPingTimeout();
switch (packet.type) {
case "open":
this.onHandshake(JSON.parse(packet.data));
break;
case "ping":
this.sendPacket("pong");
this.emitReserved("ping");
this.emitReserved("pong");
break;
case "error":
const err = new Error("server error");
// @ts-ignore
err.code = packet.data;
this.onError(err);
break;
case "message":
this.emitReserved("data", packet.data);
this.emitReserved("message", packet.data);
break;
}
}
else {
debug('packet received with socket readyState "%s"', this.readyState);
}
}
/**
* Called upon handshake completion.
*
* @param {Object} data - handshake obj
* @private
*/
onHandshake(data) {
this.emitReserved("handshake", data);
this.id = data.sid;
this.transport.query.sid = data.sid;
this.upgrades = this.filterUpgrades(data.upgrades);
this.pingInterval = data.pingInterval;
this.pingTimeout = data.pingTimeout;
this.maxPayload = data.maxPayload;
this.onOpen();
// In case open handler closes socket
if ("closed" === this.readyState)
return;
this.resetPingTimeout();
}
/**
* Sets and resets ping timeout timer based on server pings.
*
* @private
*/
resetPingTimeout() {
this.clearTimeoutFn(this.pingTimeoutTimer);
this.pingTimeoutTimer = this.setTimeoutFn(() => {
this.onClose("ping timeout");
}, this.pingInterval + this.pingTimeout);
if (this.opts.autoUnref) {
this.pingTimeoutTimer.unref();
}
}
/**
* Called on `drain` event
*
* @private
*/
onDrain() {
this.writeBuffer.splice(0, this.prevBufferLen);
// setting prevBufferLen = 0 is very important
// for example, when upgrading, upgrade packet is sent over,
// and a nonzero prevBufferLen could cause problems on `drain`
this.prevBufferLen = 0;
if (0 === this.writeBuffer.length) {
this.emitReserved("drain");
}
else {
this.flush();
}
}
/**
* Flush write buffers.
*
* @private
*/
flush() {
if ("closed" !== this.readyState &&
this.transport.writable &&
!this.upgrading &&
this.writeBuffer.length) {
const packets = this.getWritablePackets();
debug("flushing %d packets in socket", packets.length);
this.transport.send(packets);
// keep track of current length of writeBuffer
// splice writeBuffer and callbackBuffer on `drain`
this.prevBufferLen = packets.length;
this.emitReserved("flush");
}
}
/**
* Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP
* long-polling)
*
* @private
*/
getWritablePackets() {
const shouldCheckPayloadSize = this.maxPayload &&
this.transport.name === "polling" &&
this.writeBuffer.length > 1;
if (!shouldCheckPayloadSize) {
return this.writeBuffer;
}
let payloadSize = 1; // first packet type
for (let i = 0; i < this.writeBuffer.length; i++) {
const data = this.writeBuffer[i].data;
if (data) {
payloadSize += (0, util_js_1.byteLength)(data);
}
if (i > 0 && payloadSize > this.maxPayload) {
debug("only send %d out of %d packets", i, this.writeBuffer.length);
return this.writeBuffer.slice(0, i);
}
payloadSize += 2; // separator + packet type
}
debug("payload size is %d (max: %d)", payloadSize, this.maxPayload);
return this.writeBuffer;
}
/**
* Sends a message.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} callback function.
* @return {Socket} for chaining.
*/
write(msg, options, fn) {
this.sendPacket("message", msg, options, fn);
return this;
}
send(msg, options, fn) {
this.sendPacket("message", msg, options, fn);
return this;
}
/**
* Sends a packet.
*
* @param {String} type: packet type.
* @param {String} data.
* @param {Object} options.
* @param {Function} fn - callback function.
* @private
*/
sendPacket(type, data, options, fn) {
if ("function" === typeof data) {
fn = data;
data = undefined;
}
if ("function" === typeof options) {
fn = options;
options = null;
}
if ("closing" === this.readyState || "closed" === this.readyState) {
return;
}
options = options || {};
options.compress = false !== options.compress;
const packet = {
type: type,
data: data,
options: options,
};
this.emitReserved("packetCreate", packet);
this.writeBuffer.push(packet);
if (fn)
this.once("flush", fn);
this.flush();
}
/**
* Closes the connection.
*/
close() {
const close = () => {
this.onClose("forced close");
debug("socket closing - telling transport to close");
this.transport.close();
};
const cleanupAndClose = () => {
this.off("upgrade", cleanupAndClose);
this.off("upgradeError", cleanupAndClose);
close();
};
const waitForUpgrade = () => {
// wait for upgrade to finish since we can't send packets while pausing a transport
this.once("upgrade", cleanupAndClose);
this.once("upgradeError", cleanupAndClose);
};
if ("opening" === this.readyState || "open" === this.readyState) {
this.readyState = "closing";
if (this.writeBuffer.length) {
this.once("drain", () => {
if (this.upgrading) {
waitForUpgrade();
}
else {
close();
}
});
}
else if (this.upgrading) {
waitForUpgrade();
}
else {
close();
}
}
return this;
}
/**
* Called upon transport error
*
* @private
*/
onError(err) {
debug("socket error %j", err);
Socket.priorWebsocketSuccess = false;
this.emitReserved("error", err);
this.onClose("transport error", err);
}
/**
* Called upon transport close.
*
* @private
*/
onClose(reason, description) {
if ("opening" === this.readyState ||
"open" === this.readyState ||
"closing" === this.readyState) {
debug('socket close with reason: "%s"', reason);
// clear timers
this.clearTimeoutFn(this.pingTimeoutTimer);
// stop event from firing again for transport
this.transport.removeAllListeners("close");
// ensure transport won't stay open
this.transport.close();
// ignore further transport communication
this.transport.removeAllListeners();
if (typeof removeEventListener === "function") {
removeEventListener("beforeunload", this.beforeunloadEventListener, false);
removeEventListener("offline", this.offlineEventListener, false);
}
// set ready state
this.readyState = "closed";
// clear session id
this.id = null;
// emit close event
this.emitReserved("close", reason, description);
// clean buffers after, so users can still
// grab the buffers on `close` event
this.writeBuffer = [];
this.prevBufferLen = 0;
}
}
/**
* Filters upgrades, returning only those matching client transports.
*
* @param {Array} upgrades - server upgrades
* @private
*/
filterUpgrades(upgrades) {
const filteredUpgrades = [];
let i = 0;
const j = upgrades.length;
for (; i < j; i++) {
if (~this.transports.indexOf(upgrades[i]))
filteredUpgrades.push(upgrades[i]);
}
return filteredUpgrades;
}
}
exports.Socket = Socket;
Socket.protocol = engine_io_parser_1.protocol;

106
node_modules/engine.io-client/build/cjs/transport.d.ts generated vendored Normal file
View File

@@ -0,0 +1,106 @@
import type { Packet, RawData } from "engine.io-parser";
import { Emitter } from "@socket.io/component-emitter";
import { SocketOptions } from "./socket.js";
export declare class TransportError extends Error {
readonly description: any;
readonly context: any;
readonly type = "TransportError";
constructor(reason: string, description: any, context: any);
}
export interface CloseDetails {
description: string;
context?: unknown;
}
interface TransportReservedEvents {
open: () => void;
error: (err: TransportError) => void;
packet: (packet: Packet) => void;
close: (details?: CloseDetails) => void;
poll: () => void;
pollComplete: () => void;
drain: () => void;
}
type TransportState = "opening" | "open" | "closed" | "pausing" | "paused";
export declare abstract class Transport extends Emitter<Record<never, never>, Record<never, never>, TransportReservedEvents> {
query: Record<string, string>;
writable: boolean;
protected opts: SocketOptions;
protected supportsBinary: boolean;
protected readyState: TransportState;
protected socket: any;
protected setTimeoutFn: typeof setTimeout;
/**
* Transport abstract constructor.
*
* @param {Object} opts - options
* @protected
*/
constructor(opts: any);
/**
* Emits an error.
*
* @param {String} reason
* @param description
* @param context - the error context
* @return {Transport} for chaining
* @protected
*/
protected onError(reason: string, description: any, context?: any): this;
/**
* Opens the transport.
*/
open(): this;
/**
* Closes the transport.
*/
close(): this;
/**
* Sends multiple packets.
*
* @param {Array} packets
*/
send(packets: any): void;
/**
* Called upon open
*
* @protected
*/
protected onOpen(): void;
/**
* Called with data.
*
* @param {String} data
* @protected
*/
protected onData(data: RawData): void;
/**
* Called with a decoded packet.
*
* @protected
*/
protected onPacket(packet: Packet): void;
/**
* Called upon close.
*
* @protected
*/
protected onClose(details?: CloseDetails): void;
/**
* The name of the transport
*/
abstract get name(): string;
/**
* Pauses the transport, in order not to lose packets during an upgrade.
*
* @param onPause
*/
pause(onPause: () => void): void;
protected createUri(schema: string, query?: Record<string, unknown>): string;
private _hostname;
private _port;
private _query;
protected abstract doOpen(): any;
protected abstract doClose(): any;
protected abstract write(packets: Packet[]): any;
}
export {};

152
node_modules/engine.io-client/build/cjs/transport.js generated vendored Normal file
View File

@@ -0,0 +1,152 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Transport = exports.TransportError = void 0;
const engine_io_parser_1 = require("engine.io-parser");
const component_emitter_1 = require("@socket.io/component-emitter");
const util_js_1 = require("./util.js");
const debug_1 = __importDefault(require("debug")); // debug()
const parseqs_js_1 = require("./contrib/parseqs.js");
const debug = (0, debug_1.default)("engine.io-client:transport"); // debug()
class TransportError extends Error {
constructor(reason, description, context) {
super(reason);
this.description = description;
this.context = context;
this.type = "TransportError";
}
}
exports.TransportError = TransportError;
class Transport extends component_emitter_1.Emitter {
/**
* Transport abstract constructor.
*
* @param {Object} opts - options
* @protected
*/
constructor(opts) {
super();
this.writable = false;
(0, util_js_1.installTimerFunctions)(this, opts);
this.opts = opts;
this.query = opts.query;
this.socket = opts.socket;
}
/**
* Emits an error.
*
* @param {String} reason
* @param description
* @param context - the error context
* @return {Transport} for chaining
* @protected
*/
onError(reason, description, context) {
super.emitReserved("error", new TransportError(reason, description, context));
return this;
}
/**
* Opens the transport.
*/
open() {
this.readyState = "opening";
this.doOpen();
return this;
}
/**
* Closes the transport.
*/
close() {
if (this.readyState === "opening" || this.readyState === "open") {
this.doClose();
this.onClose();
}
return this;
}
/**
* Sends multiple packets.
*
* @param {Array} packets
*/
send(packets) {
if (this.readyState === "open") {
this.write(packets);
}
else {
// this might happen if the transport was silently closed in the beforeunload event handler
debug("transport is not open, discarding packets");
}
}
/**
* Called upon open
*
* @protected
*/
onOpen() {
this.readyState = "open";
this.writable = true;
super.emitReserved("open");
}
/**
* Called with data.
*
* @param {String} data
* @protected
*/
onData(data) {
const packet = (0, engine_io_parser_1.decodePacket)(data, this.socket.binaryType);
this.onPacket(packet);
}
/**
* Called with a decoded packet.
*
* @protected
*/
onPacket(packet) {
super.emitReserved("packet", packet);
}
/**
* Called upon close.
*
* @protected
*/
onClose(details) {
this.readyState = "closed";
super.emitReserved("close", details);
}
/**
* Pauses the transport, in order not to lose packets during an upgrade.
*
* @param onPause
*/
pause(onPause) { }
createUri(schema, query = {}) {
return (schema +
"://" +
this._hostname() +
this._port() +
this.opts.path +
this._query(query));
}
_hostname() {
const hostname = this.opts.hostname;
return hostname.indexOf(":") === -1 ? hostname : "[" + hostname + "]";
}
_port() {
if (this.opts.port &&
((this.opts.secure && Number(this.opts.port !== 443)) ||
(!this.opts.secure && Number(this.opts.port) !== 80))) {
return ":" + this.opts.port;
}
else {
return "";
}
}
_query(query) {
const encodedQuery = (0, parseqs_js_1.encode)(query);
return encodedQuery.length ? "?" + encodedQuery : "";
}
}
exports.Transport = Transport;

View File

@@ -0,0 +1,8 @@
import { Polling } from "./polling.js";
import { WS } from "./websocket.js";
import { WT } from "./webtransport.js";
export declare const transports: {
websocket: typeof WS;
webtransport: typeof WT;
polling: typeof Polling;
};

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transports = void 0;
const polling_js_1 = require("./polling.js");
const websocket_js_1 = require("./websocket.js");
const webtransport_js_1 = require("./webtransport.js");
exports.transports = {
websocket: websocket_js_1.WS,
webtransport: webtransport_js_1.WT,
polling: polling_js_1.Polling,
};

View File

@@ -0,0 +1,137 @@
import { Transport } from "../transport.js";
import { RawData } from "engine.io-parser";
import { Emitter } from "@socket.io/component-emitter";
export declare class Polling extends Transport {
private readonly xd;
private polling;
private pollXhr;
private cookieJar?;
/**
* XHR Polling constructor.
*
* @param {Object} opts
* @package
*/
constructor(opts: any);
get name(): string;
/**
* Opens the socket (triggers polling). We write a PING message to determine
* when the transport is open.
*
* @protected
*/
doOpen(): void;
/**
* Pauses polling.
*
* @param {Function} onPause - callback upon buffers are flushed and transport is paused
* @package
*/
pause(onPause: any): void;
/**
* Starts polling cycle.
*
* @private
*/
poll(): void;
/**
* Overloads onData to detect payloads.
*
* @protected
*/
onData(data: any): void;
/**
* For polling, send a close packet.
*
* @protected
*/
doClose(): void;
/**
* Writes a packets payload.
*
* @param {Array} packets - data packets
* @protected
*/
write(packets: any): void;
/**
* Generates uri for connection.
*
* @private
*/
private uri;
/**
* Creates a request.
*
* @param {String} method
* @private
*/
request(opts?: {}): Request;
/**
* Sends data.
*
* @param {String} data to send.
* @param {Function} called upon flush.
* @private
*/
private doWrite;
/**
* Starts a poll cycle.
*
* @private
*/
private doPoll;
}
interface RequestReservedEvents {
success: () => void;
data: (data: RawData) => void;
error: (err: number | Error, context: unknown) => void;
}
export declare class Request extends Emitter<{}, {}, RequestReservedEvents> {
private readonly opts;
private readonly method;
private readonly uri;
private readonly data;
private xhr;
private setTimeoutFn;
private index;
static requestsCount: number;
static requests: {};
/**
* Request constructor
*
* @param {Object} options
* @package
*/
constructor(uri: any, opts: any);
/**
* Creates the XHR object and sends the request.
*
* @private
*/
private create;
/**
* Called upon error.
*
* @private
*/
private onError;
/**
* Cleans up house.
*
* @private
*/
private cleanup;
/**
* Called upon load.
*
* @private
*/
private onLoad;
/**
* Aborts the request.
*
* @package
*/
abort(): void;
}
export {};

View File

@@ -0,0 +1,414 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Request = exports.Polling = void 0;
const transport_js_1 = require("../transport.js");
const debug_1 = __importDefault(require("debug")); // debug()
const yeast_js_1 = require("../contrib/yeast.js");
const engine_io_parser_1 = require("engine.io-parser");
const xmlhttprequest_js_1 = require("./xmlhttprequest.js");
const component_emitter_1 = require("@socket.io/component-emitter");
const util_js_1 = require("../util.js");
const globalThis_js_1 = require("../globalThis.js");
const debug = (0, debug_1.default)("engine.io-client:polling"); // debug()
function empty() { }
const hasXHR2 = (function () {
const xhr = new xmlhttprequest_js_1.XHR({
xdomain: false,
});
return null != xhr.responseType;
})();
class Polling extends transport_js_1.Transport {
/**
* XHR Polling constructor.
*
* @param {Object} opts
* @package
*/
constructor(opts) {
super(opts);
this.polling = false;
if (typeof location !== "undefined") {
const isSSL = "https:" === location.protocol;
let port = location.port;
// some user agents have empty `location.port`
if (!port) {
port = isSSL ? "443" : "80";
}
this.xd =
(typeof location !== "undefined" &&
opts.hostname !== location.hostname) ||
port !== opts.port;
}
/**
* XHR supports binary
*/
const forceBase64 = opts && opts.forceBase64;
this.supportsBinary = hasXHR2 && !forceBase64;
if (this.opts.withCredentials) {
this.cookieJar = (0, xmlhttprequest_js_1.createCookieJar)();
}
}
get name() {
return "polling";
}
/**
* Opens the socket (triggers polling). We write a PING message to determine
* when the transport is open.
*
* @protected
*/
doOpen() {
this.poll();
}
/**
* Pauses polling.
*
* @param {Function} onPause - callback upon buffers are flushed and transport is paused
* @package
*/
pause(onPause) {
this.readyState = "pausing";
const pause = () => {
debug("paused");
this.readyState = "paused";
onPause();
};
if (this.polling || !this.writable) {
let total = 0;
if (this.polling) {
debug("we are currently polling - waiting to pause");
total++;
this.once("pollComplete", function () {
debug("pre-pause polling complete");
--total || pause();
});
}
if (!this.writable) {
debug("we are currently writing - waiting to pause");
total++;
this.once("drain", function () {
debug("pre-pause writing complete");
--total || pause();
});
}
}
else {
pause();
}
}
/**
* Starts polling cycle.
*
* @private
*/
poll() {
debug("polling");
this.polling = true;
this.doPoll();
this.emitReserved("poll");
}
/**
* Overloads onData to detect payloads.
*
* @protected
*/
onData(data) {
debug("polling got data %s", data);
const callback = (packet) => {
// if its the first message we consider the transport open
if ("opening" === this.readyState && packet.type === "open") {
this.onOpen();
}
// if its a close packet, we close the ongoing requests
if ("close" === packet.type) {
this.onClose({ description: "transport closed by the server" });
return false;
}
// otherwise bypass onData and handle the message
this.onPacket(packet);
};
// decode payload
(0, engine_io_parser_1.decodePayload)(data, this.socket.binaryType).forEach(callback);
// if an event did not trigger closing
if ("closed" !== this.readyState) {
// if we got data we're not polling
this.polling = false;
this.emitReserved("pollComplete");
if ("open" === this.readyState) {
this.poll();
}
else {
debug('ignoring poll - transport state "%s"', this.readyState);
}
}
}
/**
* For polling, send a close packet.
*
* @protected
*/
doClose() {
const close = () => {
debug("writing close packet");
this.write([{ type: "close" }]);
};
if ("open" === this.readyState) {
debug("transport open - closing");
close();
}
else {
// in case we're trying to close while
// handshaking is in progress (GH-164)
debug("transport not open - deferring close");
this.once("open", close);
}
}
/**
* Writes a packets payload.
*
* @param {Array} packets - data packets
* @protected
*/
write(packets) {
this.writable = false;
(0, engine_io_parser_1.encodePayload)(packets, (data) => {
this.doWrite(data, () => {
this.writable = true;
this.emitReserved("drain");
});
});
}
/**
* Generates uri for connection.
*
* @private
*/
uri() {
const schema = this.opts.secure ? "https" : "http";
const query = this.query || {};
// cache busting is forced
if (false !== this.opts.timestampRequests) {
query[this.opts.timestampParam] = (0, yeast_js_1.yeast)();
}
if (!this.supportsBinary && !query.sid) {
query.b64 = 1;
}
return this.createUri(schema, query);
}
/**
* Creates a request.
*
* @param {String} method
* @private
*/
request(opts = {}) {
Object.assign(opts, { xd: this.xd, cookieJar: this.cookieJar }, this.opts);
return new Request(this.uri(), opts);
}
/**
* Sends data.
*
* @param {String} data to send.
* @param {Function} called upon flush.
* @private
*/
doWrite(data, fn) {
const req = this.request({
method: "POST",
data: data,
});
req.on("success", fn);
req.on("error", (xhrStatus, context) => {
this.onError("xhr post error", xhrStatus, context);
});
}
/**
* Starts a poll cycle.
*
* @private
*/
doPoll() {
debug("xhr poll");
const req = this.request();
req.on("data", this.onData.bind(this));
req.on("error", (xhrStatus, context) => {
this.onError("xhr poll error", xhrStatus, context);
});
this.pollXhr = req;
}
}
exports.Polling = Polling;
class Request extends component_emitter_1.Emitter {
/**
* Request constructor
*
* @param {Object} options
* @package
*/
constructor(uri, opts) {
super();
(0, util_js_1.installTimerFunctions)(this, opts);
this.opts = opts;
this.method = opts.method || "GET";
this.uri = uri;
this.data = undefined !== opts.data ? opts.data : null;
this.create();
}
/**
* Creates the XHR object and sends the request.
*
* @private
*/
create() {
var _a;
const opts = (0, util_js_1.pick)(this.opts, "agent", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "autoUnref");
opts.xdomain = !!this.opts.xd;
const xhr = (this.xhr = new xmlhttprequest_js_1.XHR(opts));
try {
debug("xhr open %s: %s", this.method, this.uri);
xhr.open(this.method, this.uri, true);
try {
if (this.opts.extraHeaders) {
xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true);
for (let i in this.opts.extraHeaders) {
if (this.opts.extraHeaders.hasOwnProperty(i)) {
xhr.setRequestHeader(i, this.opts.extraHeaders[i]);
}
}
}
}
catch (e) { }
if ("POST" === this.method) {
try {
xhr.setRequestHeader("Content-type", "text/plain;charset=UTF-8");
}
catch (e) { }
}
try {
xhr.setRequestHeader("Accept", "*/*");
}
catch (e) { }
(_a = this.opts.cookieJar) === null || _a === void 0 ? void 0 : _a.addCookies(xhr);
// ie6 check
if ("withCredentials" in xhr) {
xhr.withCredentials = this.opts.withCredentials;
}
if (this.opts.requestTimeout) {
xhr.timeout = this.opts.requestTimeout;
}
xhr.onreadystatechange = () => {
var _a;
if (xhr.readyState === 3) {
(_a = this.opts.cookieJar) === null || _a === void 0 ? void 0 : _a.parseCookies(xhr);
}
if (4 !== xhr.readyState)
return;
if (200 === xhr.status || 1223 === xhr.status) {
this.onLoad();
}
else {
// make sure the `error` event handler that's user-set
// does not throw in the same tick and gets caught here
this.setTimeoutFn(() => {
this.onError(typeof xhr.status === "number" ? xhr.status : 0);
}, 0);
}
};
debug("xhr data %s", this.data);
xhr.send(this.data);
}
catch (e) {
// Need to defer since .create() is called directly from the constructor
// and thus the 'error' event can only be only bound *after* this exception
// occurs. Therefore, also, we cannot throw here at all.
this.setTimeoutFn(() => {
this.onError(e);
}, 0);
return;
}
if (typeof document !== "undefined") {
this.index = Request.requestsCount++;
Request.requests[this.index] = this;
}
}
/**
* Called upon error.
*
* @private
*/
onError(err) {
this.emitReserved("error", err, this.xhr);
this.cleanup(true);
}
/**
* Cleans up house.
*
* @private
*/
cleanup(fromError) {
if ("undefined" === typeof this.xhr || null === this.xhr) {
return;
}
this.xhr.onreadystatechange = empty;
if (fromError) {
try {
this.xhr.abort();
}
catch (e) { }
}
if (typeof document !== "undefined") {
delete Request.requests[this.index];
}
this.xhr = null;
}
/**
* Called upon load.
*
* @private
*/
onLoad() {
const data = this.xhr.responseText;
if (data !== null) {
this.emitReserved("data", data);
this.emitReserved("success");
this.cleanup();
}
}
/**
* Aborts the request.
*
* @package
*/
abort() {
this.cleanup();
}
}
exports.Request = Request;
Request.requestsCount = 0;
Request.requests = {};
/**
* Aborts pending requests when unloading the window. This is needed to prevent
* memory leaks (e.g. when using IE) and to ensure that no spurious error is
* emitted.
*/
if (typeof document !== "undefined") {
// @ts-ignore
if (typeof attachEvent === "function") {
// @ts-ignore
attachEvent("onunload", unloadHandler);
}
else if (typeof addEventListener === "function") {
const terminationEvent = "onpagehide" in globalThis_js_1.globalThisShim ? "pagehide" : "unload";
addEventListener(terminationEvent, unloadHandler, false);
}
}
function unloadHandler() {
for (let i in Request.requests) {
if (Request.requests.hasOwnProperty(i)) {
Request.requests[i].abort();
}
}
}

View File

@@ -0,0 +1,4 @@
export declare const nextTick: (cb: any, setTimeoutFn: any) => any;
export declare const WebSocket: any;
export declare const usingBrowserWebSocket = true;
export declare const defaultBinaryType = "arraybuffer";

View File

@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultBinaryType = exports.usingBrowserWebSocket = exports.WebSocket = exports.nextTick = void 0;
const globalThis_js_1 = require("../globalThis.js");
exports.nextTick = (() => {
const isPromiseAvailable = typeof Promise === "function" && typeof Promise.resolve === "function";
if (isPromiseAvailable) {
return (cb) => Promise.resolve().then(cb);
}
else {
return (cb, setTimeoutFn) => setTimeoutFn(cb, 0);
}
})();
exports.WebSocket = globalThis_js_1.globalThisShim.WebSocket || globalThis_js_1.globalThisShim.MozWebSocket;
exports.usingBrowserWebSocket = true;
exports.defaultBinaryType = "arraybuffer";

View File

@@ -0,0 +1,4 @@
export declare const WebSocket: any;
export declare const usingBrowserWebSocket = false;
export declare const defaultBinaryType = "nodebuffer";
export declare const nextTick: (callback: Function, ...args: any[]) => void;

View File

@@ -0,0 +1,11 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.nextTick = exports.defaultBinaryType = exports.usingBrowserWebSocket = exports.WebSocket = void 0;
const ws_1 = __importDefault(require("ws"));
exports.WebSocket = ws_1.default;
exports.usingBrowserWebSocket = false;
exports.defaultBinaryType = "nodebuffer";
exports.nextTick = process.nextTick;

View File

@@ -0,0 +1,34 @@
import { Transport } from "../transport.js";
export declare class WS extends Transport {
private ws;
/**
* WebSocket transport constructor.
*
* @param {Object} opts - connection options
* @protected
*/
constructor(opts: any);
get name(): string;
doOpen(): this;
/**
* Adds event listeners to the socket
*
* @private
*/
private addEventListeners;
write(packets: any): void;
doClose(): void;
/**
* Generates uri for connection.
*
* @private
*/
private uri;
/**
* Feature detection for WebSocket.
*
* @return {Boolean} whether this transport is available.
* @private
*/
private check;
}

View File

@@ -0,0 +1,162 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WS = void 0;
const transport_js_1 = require("../transport.js");
const yeast_js_1 = require("../contrib/yeast.js");
const util_js_1 = require("../util.js");
const websocket_constructor_js_1 = require("./websocket-constructor.js");
const debug_1 = __importDefault(require("debug")); // debug()
const engine_io_parser_1 = require("engine.io-parser");
const debug = (0, debug_1.default)("engine.io-client:websocket"); // debug()
// detect ReactNative environment
const isReactNative = typeof navigator !== "undefined" &&
typeof navigator.product === "string" &&
navigator.product.toLowerCase() === "reactnative";
class WS extends transport_js_1.Transport {
/**
* WebSocket transport constructor.
*
* @param {Object} opts - connection options
* @protected
*/
constructor(opts) {
super(opts);
this.supportsBinary = !opts.forceBase64;
}
get name() {
return "websocket";
}
doOpen() {
if (!this.check()) {
// let probe timeout
return;
}
const uri = this.uri();
const protocols = this.opts.protocols;
// React Native only supports the 'headers' option, and will print a warning if anything else is passed
const opts = isReactNative
? {}
: (0, util_js_1.pick)(this.opts, "agent", "perMessageDeflate", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "localAddress", "protocolVersion", "origin", "maxPayload", "family", "checkServerIdentity");
if (this.opts.extraHeaders) {
opts.headers = this.opts.extraHeaders;
}
try {
this.ws =
websocket_constructor_js_1.usingBrowserWebSocket && !isReactNative
? protocols
? new websocket_constructor_js_1.WebSocket(uri, protocols)
: new websocket_constructor_js_1.WebSocket(uri)
: new websocket_constructor_js_1.WebSocket(uri, protocols, opts);
}
catch (err) {
return this.emitReserved("error", err);
}
this.ws.binaryType = this.socket.binaryType;
this.addEventListeners();
}
/**
* Adds event listeners to the socket
*
* @private
*/
addEventListeners() {
this.ws.onopen = () => {
if (this.opts.autoUnref) {
this.ws._socket.unref();
}
this.onOpen();
};
this.ws.onclose = (closeEvent) => this.onClose({
description: "websocket connection closed",
context: closeEvent,
});
this.ws.onmessage = (ev) => this.onData(ev.data);
this.ws.onerror = (e) => this.onError("websocket error", e);
}
write(packets) {
this.writable = false;
// encodePacket efficient as it uses WS framing
// no need for encodePayload
for (let i = 0; i < packets.length; i++) {
const packet = packets[i];
const lastPacket = i === packets.length - 1;
(0, engine_io_parser_1.encodePacket)(packet, this.supportsBinary, (data) => {
// always create a new object (GH-437)
const opts = {};
if (!websocket_constructor_js_1.usingBrowserWebSocket) {
if (packet.options) {
opts.compress = packet.options.compress;
}
if (this.opts.perMessageDeflate) {
const len =
// @ts-ignore
"string" === typeof data ? Buffer.byteLength(data) : data.length;
if (len < this.opts.perMessageDeflate.threshold) {
opts.compress = false;
}
}
}
// Sometimes the websocket has already been closed but the browser didn't
// have a chance of informing us about it yet, in that case send will
// throw an error
try {
if (websocket_constructor_js_1.usingBrowserWebSocket) {
// TypeError is thrown when passing the second argument on Safari
this.ws.send(data);
}
else {
this.ws.send(data, opts);
}
}
catch (e) {
debug("websocket closed before onclose event");
}
if (lastPacket) {
// fake drain
// defer to next tick to allow Socket to clear writeBuffer
(0, websocket_constructor_js_1.nextTick)(() => {
this.writable = true;
this.emitReserved("drain");
}, this.setTimeoutFn);
}
});
}
}
doClose() {
if (typeof this.ws !== "undefined") {
this.ws.close();
this.ws = null;
}
}
/**
* Generates uri for connection.
*
* @private
*/
uri() {
const schema = this.opts.secure ? "wss" : "ws";
const query = this.query || {};
// append timestamp to URI
if (this.opts.timestampRequests) {
query[this.opts.timestampParam] = (0, yeast_js_1.yeast)();
}
// communicate binary support capabilities
if (!this.supportsBinary) {
query.b64 = 1;
}
return this.createUri(schema, query);
}
/**
* Feature detection for WebSocket.
*
* @return {Boolean} whether this transport is available.
* @private
*/
check() {
return !!websocket_constructor_js_1.WebSocket;
}
}
exports.WS = WS;

View File

@@ -0,0 +1,10 @@
import { Transport } from "../transport.js";
import { Packet } from "engine.io-parser";
export declare class WT extends Transport {
private transport;
private writer;
get name(): string;
protected doOpen(): void;
protected write(packets: Packet[]): void;
protected doClose(): void;
}

View File

@@ -0,0 +1,85 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WT = void 0;
const transport_js_1 = require("../transport.js");
const websocket_constructor_js_1 = require("./websocket-constructor.js");
const engine_io_parser_1 = require("engine.io-parser");
const debug_1 = __importDefault(require("debug")); // debug()
const debug = (0, debug_1.default)("engine.io-client:webtransport"); // debug()
class WT extends transport_js_1.Transport {
get name() {
return "webtransport";
}
doOpen() {
// @ts-ignore
if (typeof WebTransport !== "function") {
return;
}
// @ts-ignore
this.transport = new WebTransport(this.createUri("https"), this.opts.transportOptions[this.name]);
this.transport.closed
.then(() => {
debug("transport closed gracefully");
this.onClose();
})
.catch((err) => {
debug("transport closed due to %s", err);
this.onError("webtransport error", err);
});
// note: we could have used async/await, but that would require some additional polyfills
this.transport.ready.then(() => {
this.transport.createBidirectionalStream().then((stream) => {
const decoderStream = (0, engine_io_parser_1.createPacketDecoderStream)(Number.MAX_SAFE_INTEGER, this.socket.binaryType);
const reader = stream.readable.pipeThrough(decoderStream).getReader();
const encoderStream = (0, engine_io_parser_1.createPacketEncoderStream)();
encoderStream.readable.pipeTo(stream.writable);
this.writer = encoderStream.writable.getWriter();
const read = () => {
reader
.read()
.then(({ done, value }) => {
if (done) {
debug("session is closed");
return;
}
debug("received chunk: %o", value);
this.onPacket(value);
read();
})
.catch((err) => {
debug("an error occurred while reading: %s", err);
});
};
read();
const packet = { type: "open" };
if (this.query.sid) {
packet.data = `{"sid":"${this.query.sid}"}`;
}
this.writer.write(packet).then(() => this.onOpen());
});
});
}
write(packets) {
this.writable = false;
for (let i = 0; i < packets.length; i++) {
const packet = packets[i];
const lastPacket = i === packets.length - 1;
this.writer.write(packet).then(() => {
if (lastPacket) {
(0, websocket_constructor_js_1.nextTick)(() => {
this.writable = true;
this.emitReserved("drain");
}, this.setTimeoutFn);
}
});
}
}
doClose() {
var _a;
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.close();
}
}
exports.WT = WT;

View File

@@ -0,0 +1,2 @@
export declare function XHR(opts: any): any;
export declare function createCookieJar(): void;

View File

@@ -0,0 +1,25 @@
"use strict";
// browser shim for xmlhttprequest module
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCookieJar = exports.XHR = void 0;
const has_cors_js_1 = require("../contrib/has-cors.js");
const globalThis_js_1 = require("../globalThis.js");
function XHR(opts) {
const xdomain = opts.xdomain;
// XMLHttpRequest can be disabled on IE
try {
if ("undefined" !== typeof XMLHttpRequest && (!xdomain || has_cors_js_1.hasCORS)) {
return new XMLHttpRequest();
}
}
catch (e) { }
if (!xdomain) {
try {
return new globalThis_js_1.globalThisShim[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP");
}
catch (e) { }
}
}
exports.XHR = XHR;
function createCookieJar() { }
exports.createCookieJar = createCookieJar;

View File

@@ -0,0 +1,17 @@
export declare const XHR: any;
export declare function createCookieJar(): CookieJar;
interface Cookie {
name: string;
value: string;
expires?: Date;
}
/**
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
*/
export declare function parse(setCookieString: string): Cookie;
export declare class CookieJar {
private cookies;
parseCookies(xhr: any): void;
addCookies(xhr: any): void;
}
export {};

View File

@@ -0,0 +1,111 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CookieJar = exports.parse = exports.createCookieJar = exports.XHR = void 0;
const XMLHttpRequestModule = __importStar(require("xmlhttprequest-ssl"));
exports.XHR = XMLHttpRequestModule.default || XMLHttpRequestModule;
function createCookieJar() {
return new CookieJar();
}
exports.createCookieJar = createCookieJar;
/**
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
*/
function parse(setCookieString) {
const parts = setCookieString.split("; ");
const i = parts[0].indexOf("=");
if (i === -1) {
return;
}
const name = parts[0].substring(0, i).trim();
if (!name.length) {
return;
}
let value = parts[0].substring(i + 1).trim();
if (value.charCodeAt(0) === 0x22) {
// remove double quotes
value = value.slice(1, -1);
}
const cookie = {
name,
value,
};
for (let j = 1; j < parts.length; j++) {
const subParts = parts[j].split("=");
if (subParts.length !== 2) {
continue;
}
const key = subParts[0].trim();
const value = subParts[1].trim();
switch (key) {
case "Expires":
cookie.expires = new Date(value);
break;
case "Max-Age":
const expiration = new Date();
expiration.setUTCSeconds(expiration.getUTCSeconds() + parseInt(value, 10));
cookie.expires = expiration;
break;
default:
// ignore other keys
}
}
return cookie;
}
exports.parse = parse;
class CookieJar {
constructor() {
this.cookies = new Map();
}
parseCookies(xhr) {
const values = xhr.getResponseHeader("set-cookie");
if (!values) {
return;
}
values.forEach((value) => {
const parsed = parse(value);
if (parsed) {
this.cookies.set(parsed.name, parsed);
}
});
}
addCookies(xhr) {
const cookies = [];
this.cookies.forEach((cookie, name) => {
var _a;
if (((_a = cookie.expires) === null || _a === void 0 ? void 0 : _a.getTime()) < Date.now()) {
this.cookies.delete(name);
}
else {
cookies.push(`${name}=${cookie.value}`);
}
});
if (cookies.length) {
xhr.setDisableHeaderCheck(true);
xhr.setRequestHeader("cookie", cookies.join("; "));
}
}
}
exports.CookieJar = CookieJar;

3
node_modules/engine.io-client/build/cjs/util.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
export declare function pick(obj: any, ...attr: any[]): any;
export declare function installTimerFunctions(obj: any, opts: any): void;
export declare function byteLength(obj: any): number;

58
node_modules/engine.io-client/build/cjs/util.js generated vendored Normal file
View File

@@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.byteLength = exports.installTimerFunctions = exports.pick = void 0;
const globalThis_js_1 = require("./globalThis.js");
function pick(obj, ...attr) {
return attr.reduce((acc, k) => {
if (obj.hasOwnProperty(k)) {
acc[k] = obj[k];
}
return acc;
}, {});
}
exports.pick = pick;
// Keep a reference to the real timeout functions so they can be used when overridden
const NATIVE_SET_TIMEOUT = globalThis_js_1.globalThisShim.setTimeout;
const NATIVE_CLEAR_TIMEOUT = globalThis_js_1.globalThisShim.clearTimeout;
function installTimerFunctions(obj, opts) {
if (opts.useNativeTimers) {
obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(globalThis_js_1.globalThisShim);
obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(globalThis_js_1.globalThisShim);
}
else {
obj.setTimeoutFn = globalThis_js_1.globalThisShim.setTimeout.bind(globalThis_js_1.globalThisShim);
obj.clearTimeoutFn = globalThis_js_1.globalThisShim.clearTimeout.bind(globalThis_js_1.globalThisShim);
}
}
exports.installTimerFunctions = installTimerFunctions;
// base64 encoded buffers are about 33% bigger (https://en.wikipedia.org/wiki/Base64)
const BASE64_OVERHEAD = 1.33;
// we could also have used `new Blob([obj]).size`, but it isn't supported in IE9
function byteLength(obj) {
if (typeof obj === "string") {
return utf8Length(obj);
}
// arraybuffer or blob
return Math.ceil((obj.byteLength || obj.size) * BASE64_OVERHEAD);
}
exports.byteLength = byteLength;
function utf8Length(str) {
let c = 0, length = 0;
for (let i = 0, l = str.length; i < l; i++) {
c = str.charCodeAt(i);
if (c < 0x80) {
length += 1;
}
else if (c < 0x800) {
length += 2;
}
else if (c < 0xd800 || c >= 0xe000) {
length += 3;
}
else {
i++;
length += 4;
}
}
return length;
}

View File

@@ -0,0 +1,3 @@
import { Socket } from "./socket.js";
declare const _default: (uri: any, opts: any) => Socket;
export default _default;

View File

@@ -0,0 +1,2 @@
import { Socket } from "./socket.js";
export default (uri, opts) => new Socket(uri, opts);

View File

@@ -0,0 +1 @@
export declare const hasCORS: boolean;

View File

@@ -0,0 +1,11 @@
// imported from https://github.com/component/has-cors
let value = false;
try {
value = typeof XMLHttpRequest !== 'undefined' &&
'withCredentials' in new XMLHttpRequest();
}
catch (err) {
// if XMLHttp support is disabled in IE then it will throw
// when trying to create
}
export const hasCORS = value;

View File

@@ -0,0 +1,15 @@
/**
* Compiles a querystring
* Returns string representation of the object
*
* @param {Object}
* @api private
*/
export declare function encode(obj: any): string;
/**
* Parses a simple querystring into an object
*
* @param {String} qs
* @api private
*/
export declare function decode(qs: any): {};

View File

@@ -0,0 +1,34 @@
// imported from https://github.com/galkn/querystring
/**
* Compiles a querystring
* Returns string representation of the object
*
* @param {Object}
* @api private
*/
export function encode(obj) {
let str = '';
for (let i in obj) {
if (obj.hasOwnProperty(i)) {
if (str.length)
str += '&';
str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
}
}
return str;
}
/**
* Parses a simple querystring into an object
*
* @param {String} qs
* @api private
*/
export function decode(qs) {
let qry = {};
let pairs = qs.split('&');
for (let i = 0, l = pairs.length; i < l; i++) {
let pair = pairs[i].split('=');
qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return qry;
}

View File

@@ -0,0 +1 @@
export declare function parse(str: string): any;

View File

@@ -0,0 +1,64 @@
// imported from https://github.com/galkn/parseuri
/**
* Parses a URI
*
* Note: we could also have used the built-in URL object, but it isn't supported on all platforms.
*
* See:
* - https://developer.mozilla.org/en-US/docs/Web/API/URL
* - https://caniuse.com/url
* - https://www.rfc-editor.org/rfc/rfc3986#appendix-B
*
* History of the parse() method:
* - first commit: https://github.com/socketio/socket.io-client/commit/4ee1d5d94b3906a9c052b459f1a818b15f38f91c
* - export into its own module: https://github.com/socketio/engine.io-client/commit/de2c561e4564efeb78f1bdb1ba39ef81b2822cb3
* - reimport: https://github.com/socketio/engine.io-client/commit/df32277c3f6d622eec5ed09f493cae3f3391d242
*
* @author Steven Levithan <stevenlevithan.com> (MIT license)
* @api private
*/
const re = /^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
const parts = [
'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
];
export function parse(str) {
if (str.length > 2000) {
throw "URI too long";
}
const src = str, b = str.indexOf('['), e = str.indexOf(']');
if (b != -1 && e != -1) {
str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
}
let m = re.exec(str || ''), uri = {}, i = 14;
while (i--) {
uri[parts[i]] = m[i] || '';
}
if (b != -1 && e != -1) {
uri.source = src;
uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
uri.ipv6uri = true;
}
uri.pathNames = pathNames(uri, uri['path']);
uri.queryKey = queryKey(uri, uri['query']);
return uri;
}
function pathNames(obj, path) {
const regx = /\/{2,9}/g, names = path.replace(regx, "/").split("/");
if (path.slice(0, 1) == '/' || path.length === 0) {
names.splice(0, 1);
}
if (path.slice(-1) == '/') {
names.splice(names.length - 1, 1);
}
return names;
}
function queryKey(uri, query) {
const data = {};
query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) {
if ($1) {
data[$1] = $2;
}
});
return data;
}

View File

@@ -0,0 +1,23 @@
/**
* Return a string representing the specified number.
*
* @param {Number} num The number to convert.
* @returns {String} The string representation of the number.
* @api public
*/
export declare function encode(num: any): string;
/**
* Return the integer value specified by the given string.
*
* @param {String} str The string to convert.
* @returns {Number} The integer value represented by the string.
* @api public
*/
export declare function decode(str: any): number;
/**
* Yeast: A tiny growing id generator.
*
* @returns {String} A unique id.
* @api public
*/
export declare function yeast(): string;

View File

@@ -0,0 +1,50 @@
// imported from https://github.com/unshiftio/yeast
'use strict';
const alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split(''), length = 64, map = {};
let seed = 0, i = 0, prev;
/**
* Return a string representing the specified number.
*
* @param {Number} num The number to convert.
* @returns {String} The string representation of the number.
* @api public
*/
export function encode(num) {
let encoded = '';
do {
encoded = alphabet[num % length] + encoded;
num = Math.floor(num / length);
} while (num > 0);
return encoded;
}
/**
* Return the integer value specified by the given string.
*
* @param {String} str The string to convert.
* @returns {Number} The integer value represented by the string.
* @api public
*/
export function decode(str) {
let decoded = 0;
for (i = 0; i < str.length; i++) {
decoded = decoded * length + map[str.charAt(i)];
}
return decoded;
}
/**
* Yeast: A tiny growing id generator.
*
* @returns {String} A unique id.
* @api public
*/
export function yeast() {
const now = encode(+new Date());
if (now !== prev)
return seed = 0, prev = now;
return now + '.' + encode(seed++);
}
//
// Map each character to its index.
//
for (; i < length; i++)
map[alphabet[i]] = i;

View File

@@ -0,0 +1 @@
export declare const globalThisShim: any;

View File

@@ -0,0 +1,11 @@
export const globalThisShim = (() => {
if (typeof self !== "undefined") {
return self;
}
else if (typeof window !== "undefined") {
return window;
}
else {
return Function("return this")();
}
})();

View File

@@ -0,0 +1 @@
export declare const globalThisShim: typeof globalThis;

View File

@@ -0,0 +1 @@
export const globalThisShim = global;

View File

@@ -0,0 +1,9 @@
import { Socket } from "./socket.js";
export { Socket };
export { SocketOptions } from "./socket.js";
export declare const protocol: number;
export { Transport, TransportError } from "./transport.js";
export { transports } from "./transports/index.js";
export { installTimerFunctions } from "./util.js";
export { parse } from "./contrib/parseuri.js";
export { nextTick } from "./transports/websocket-constructor.js";

View File

@@ -0,0 +1,8 @@
import { Socket } from "./socket.js";
export { Socket };
export const protocol = Socket.protocol;
export { Transport, TransportError } from "./transport.js";
export { transports } from "./transports/index.js";
export { installTimerFunctions } from "./util.js";
export { parse } from "./contrib/parseuri.js";
export { nextTick } from "./transports/websocket-constructor.js";

View File

@@ -0,0 +1,10 @@
{
"name": "engine.io-client",
"type": "module",
"browser": {
"ws": false,
"./transports/xmlhttprequest.js": "./transports/xmlhttprequest.browser.js",
"./transports/websocket-constructor.js": "./transports/websocket-constructor.browser.js",
"./globalThis.js": "./globalThis.browser.js"
}
}

View File

@@ -0,0 +1,362 @@
import { Emitter } from "@socket.io/component-emitter";
import type { Packet, BinaryType, RawData } from "engine.io-parser";
import { CloseDetails, Transport } from "./transport.js";
export interface SocketOptions {
/**
* The host that we're connecting to. Set from the URI passed when connecting
*/
host: string;
/**
* The hostname for our connection. Set from the URI passed when connecting
*/
hostname: string;
/**
* If this is a secure connection. Set from the URI passed when connecting
*/
secure: boolean;
/**
* The port for our connection. Set from the URI passed when connecting
*/
port: string | number;
/**
* Any query parameters in our uri. Set from the URI passed when connecting
*/
query: {
[key: string]: any;
};
/**
* `http.Agent` to use, defaults to `false` (NodeJS only)
*
* Note: the type should be "undefined | http.Agent | https.Agent | false", but this would break browser-only clients.
*
* @see https://nodejs.org/api/http.html#httprequestoptions-callback
*/
agent: string | boolean;
/**
* Whether the client should try to upgrade the transport from
* long-polling to something better.
* @default true
*/
upgrade: boolean;
/**
* Forces base 64 encoding for polling transport even when XHR2
* responseType is available and WebSocket even if the used standard
* supports binary.
*/
forceBase64: boolean;
/**
* The param name to use as our timestamp key
* @default 't'
*/
timestampParam: string;
/**
* Whether to add the timestamp with each transport request. Note: this
* is ignored if the browser is IE or Android, in which case requests
* are always stamped
* @default false
*/
timestampRequests: boolean;
/**
* A list of transports to try (in order). Engine.io always attempts to
* connect directly with the first one, provided the feature detection test
* for it passes.
*
* @default ['polling','websocket', 'webtransport']
*/
transports: string[];
/**
* If true and if the previous websocket connection to the server succeeded,
* the connection attempt will bypass the normal upgrade process and will
* initially try websocket. A connection attempt following a transport error
* will use the normal upgrade process. It is recommended you turn this on
* only when using SSL/TLS connections, or if you know that your network does
* not block websockets.
* @default false
*/
rememberUpgrade: boolean;
/**
* Are we only interested in transports that support binary?
*/
onlyBinaryUpgrades: boolean;
/**
* Timeout for xhr-polling requests in milliseconds (0) (only for polling transport)
*/
requestTimeout: number;
/**
* Transport options for Node.js client (headers etc)
*/
transportOptions: Object;
/**
* (SSL) Certificate, Private key and CA certificates to use for SSL.
* Can be used in Node.js client environment to manually specify
* certificate information.
*/
pfx: string;
/**
* (SSL) Private key to use for SSL. Can be used in Node.js client
* environment to manually specify certificate information.
*/
key: string;
/**
* (SSL) A string or passphrase for the private key or pfx. Can be
* used in Node.js client environment to manually specify certificate
* information.
*/
passphrase: string;
/**
* (SSL) Public x509 certificate to use. Can be used in Node.js client
* environment to manually specify certificate information.
*/
cert: string;
/**
* (SSL) An authority certificate or array of authority certificates to
* check the remote host against.. Can be used in Node.js client
* environment to manually specify certificate information.
*/
ca: string | string[];
/**
* (SSL) A string describing the ciphers to use or exclude. Consult the
* [cipher format list]
* (http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT) for
* details on the format.. Can be used in Node.js client environment to
* manually specify certificate information.
*/
ciphers: string;
/**
* (SSL) If true, the server certificate is verified against the list of
* supplied CAs. An 'error' event is emitted if verification fails.
* Verification happens at the connection level, before the HTTP request
* is sent. Can be used in Node.js client environment to manually specify
* certificate information.
*/
rejectUnauthorized: boolean;
/**
* Headers that will be passed for each request to the server (via xhr-polling and via websockets).
* These values then can be used during handshake or for special proxies.
*/
extraHeaders?: {
[header: string]: string;
};
/**
* Whether to include credentials (cookies, authorization headers, TLS
* client certificates, etc.) with cross-origin XHR polling requests
* @default false
*/
withCredentials: boolean;
/**
* Whether to automatically close the connection whenever the beforeunload event is received.
* @default false
*/
closeOnBeforeunload: boolean;
/**
* Whether to always use the native timeouts. This allows the client to
* reconnect when the native timeout functions are overridden, such as when
* mock clocks are installed.
* @default false
*/
useNativeTimers: boolean;
/**
* weather we should unref the reconnect timer when it is
* create automatically
* @default false
*/
autoUnref: boolean;
/**
* parameters of the WebSocket permessage-deflate extension (see ws module api docs). Set to false to disable.
* @default false
*/
perMessageDeflate: {
threshold: number;
};
/**
* The path to get our client file from, in the case of the server
* serving it
* @default '/engine.io'
*/
path: string;
/**
* Whether we should add a trailing slash to the request path.
* @default true
*/
addTrailingSlash: boolean;
/**
* Either a single protocol string or an array of protocol strings. These strings are used to indicate sub-protocols,
* so that a single server can implement multiple WebSocket sub-protocols (for example, you might want one server to
* be able to handle different types of interactions depending on the specified protocol)
* @default []
*/
protocols: string | string[];
}
interface HandshakeData {
sid: string;
upgrades: string[];
pingInterval: number;
pingTimeout: number;
maxPayload: number;
}
interface SocketReservedEvents {
open: () => void;
handshake: (data: HandshakeData) => void;
packet: (packet: Packet) => void;
packetCreate: (packet: Packet) => void;
data: (data: any) => void;
message: (data: any) => void;
drain: () => void;
flush: () => void;
heartbeat: () => void;
ping: () => void;
pong: () => void;
error: (err: string | Error) => void;
upgrading: (transport: any) => void;
upgrade: (transport: any) => void;
upgradeError: (err: Error) => void;
close: (reason: string, description?: CloseDetails | Error) => void;
}
type SocketState = "opening" | "open" | "closing" | "closed";
export declare class Socket extends Emitter<Record<never, never>, Record<never, never>, SocketReservedEvents> {
id: string;
transport: Transport;
binaryType: BinaryType;
readyState: SocketState;
writeBuffer: Packet[];
private prevBufferLen;
private upgrades;
private pingInterval;
private pingTimeout;
private pingTimeoutTimer;
private setTimeoutFn;
private clearTimeoutFn;
private readonly beforeunloadEventListener;
private readonly offlineEventListener;
private upgrading;
private maxPayload?;
private readonly opts;
private readonly secure;
private readonly hostname;
private readonly port;
private readonly transports;
static priorWebsocketSuccess: boolean;
static protocol: number;
/**
* Socket constructor.
*
* @param {String|Object} uri - uri or options
* @param {Object} opts - options
*/
constructor(uri: any, opts?: Partial<SocketOptions>);
/**
* Creates transport of the given type.
*
* @param {String} name - transport name
* @return {Transport}
* @private
*/
private createTransport;
/**
* Initializes transport to use and starts probe.
*
* @private
*/
private open;
/**
* Sets the current transport. Disables the existing one (if any).
*
* @private
*/
private setTransport;
/**
* Probes a transport.
*
* @param {String} name - transport name
* @private
*/
private probe;
/**
* Called when connection is deemed open.
*
* @private
*/
private onOpen;
/**
* Handles a packet.
*
* @private
*/
private onPacket;
/**
* Called upon handshake completion.
*
* @param {Object} data - handshake obj
* @private
*/
private onHandshake;
/**
* Sets and resets ping timeout timer based on server pings.
*
* @private
*/
private resetPingTimeout;
/**
* Called on `drain` event
*
* @private
*/
private onDrain;
/**
* Flush write buffers.
*
* @private
*/
private flush;
/**
* Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP
* long-polling)
*
* @private
*/
private getWritablePackets;
/**
* Sends a message.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} callback function.
* @return {Socket} for chaining.
*/
write(msg: RawData, options?: any, fn?: any): this;
send(msg: RawData, options?: any, fn?: any): this;
/**
* Sends a packet.
*
* @param {String} type: packet type.
* @param {String} data.
* @param {Object} options.
* @param {Function} fn - callback function.
* @private
*/
private sendPacket;
/**
* Closes the connection.
*/
close(): this;
/**
* Called upon transport error
*
* @private
*/
private onError;
/**
* Called upon transport close.
*
* @private
*/
private onClose;
/**
* Filters upgrades, returning only those matching client transports.
*
* @param {Array} upgrades - server upgrades
* @private
*/
private filterUpgrades;
}
export {};

619
node_modules/engine.io-client/build/esm-debug/socket.js generated vendored Normal file
View File

@@ -0,0 +1,619 @@
import { transports } from "./transports/index.js";
import { installTimerFunctions, byteLength } from "./util.js";
import { decode } from "./contrib/parseqs.js";
import { parse } from "./contrib/parseuri.js";
import debugModule from "debug"; // debug()
import { Emitter } from "@socket.io/component-emitter";
import { protocol } from "engine.io-parser";
import { defaultBinaryType } from "./transports/websocket-constructor.js";
const debug = debugModule("engine.io-client:socket"); // debug()
export class Socket extends Emitter {
/**
* Socket constructor.
*
* @param {String|Object} uri - uri or options
* @param {Object} opts - options
*/
constructor(uri, opts = {}) {
super();
this.binaryType = defaultBinaryType;
this.writeBuffer = [];
if (uri && "object" === typeof uri) {
opts = uri;
uri = null;
}
if (uri) {
uri = parse(uri);
opts.hostname = uri.host;
opts.secure = uri.protocol === "https" || uri.protocol === "wss";
opts.port = uri.port;
if (uri.query)
opts.query = uri.query;
}
else if (opts.host) {
opts.hostname = parse(opts.host).host;
}
installTimerFunctions(this, opts);
this.secure =
null != opts.secure
? opts.secure
: typeof location !== "undefined" && "https:" === location.protocol;
if (opts.hostname && !opts.port) {
// if no port is specified manually, use the protocol default
opts.port = this.secure ? "443" : "80";
}
this.hostname =
opts.hostname ||
(typeof location !== "undefined" ? location.hostname : "localhost");
this.port =
opts.port ||
(typeof location !== "undefined" && location.port
? location.port
: this.secure
? "443"
: "80");
this.transports = opts.transports || [
"polling",
"websocket",
"webtransport",
];
this.writeBuffer = [];
this.prevBufferLen = 0;
this.opts = Object.assign({
path: "/engine.io",
agent: false,
withCredentials: false,
upgrade: true,
timestampParam: "t",
rememberUpgrade: false,
addTrailingSlash: true,
rejectUnauthorized: true,
perMessageDeflate: {
threshold: 1024,
},
transportOptions: {},
closeOnBeforeunload: false,
}, opts);
this.opts.path =
this.opts.path.replace(/\/$/, "") +
(this.opts.addTrailingSlash ? "/" : "");
if (typeof this.opts.query === "string") {
this.opts.query = decode(this.opts.query);
}
// set on handshake
this.id = null;
this.upgrades = null;
this.pingInterval = null;
this.pingTimeout = null;
// set on heartbeat
this.pingTimeoutTimer = null;
if (typeof addEventListener === "function") {
if (this.opts.closeOnBeforeunload) {
// Firefox closes the connection when the "beforeunload" event is emitted but not Chrome. This event listener
// ensures every browser behaves the same (no "disconnect" event at the Socket.IO level when the page is
// closed/reloaded)
this.beforeunloadEventListener = () => {
if (this.transport) {
// silently close the transport
this.transport.removeAllListeners();
this.transport.close();
}
};
addEventListener("beforeunload", this.beforeunloadEventListener, false);
}
if (this.hostname !== "localhost") {
this.offlineEventListener = () => {
this.onClose("transport close", {
description: "network connection lost",
});
};
addEventListener("offline", this.offlineEventListener, false);
}
}
this.open();
}
/**
* Creates transport of the given type.
*
* @param {String} name - transport name
* @return {Transport}
* @private
*/
createTransport(name) {
debug('creating transport "%s"', name);
const query = Object.assign({}, this.opts.query);
// append engine.io protocol identifier
query.EIO = protocol;
// transport name
query.transport = name;
// session id if we already have one
if (this.id)
query.sid = this.id;
const opts = Object.assign({}, this.opts, {
query,
socket: this,
hostname: this.hostname,
secure: this.secure,
port: this.port,
}, this.opts.transportOptions[name]);
debug("options: %j", opts);
return new transports[name](opts);
}
/**
* Initializes transport to use and starts probe.
*
* @private
*/
open() {
let transport;
if (this.opts.rememberUpgrade &&
Socket.priorWebsocketSuccess &&
this.transports.indexOf("websocket") !== -1) {
transport = "websocket";
}
else if (0 === this.transports.length) {
// Emit error on next tick so it can be listened to
this.setTimeoutFn(() => {
this.emitReserved("error", "No transports available");
}, 0);
return;
}
else {
transport = this.transports[0];
}
this.readyState = "opening";
// Retry with the next transport if the transport is disabled (jsonp: false)
try {
transport = this.createTransport(transport);
}
catch (e) {
debug("error while creating transport: %s", e);
this.transports.shift();
this.open();
return;
}
transport.open();
this.setTransport(transport);
}
/**
* Sets the current transport. Disables the existing one (if any).
*
* @private
*/
setTransport(transport) {
debug("setting transport %s", transport.name);
if (this.transport) {
debug("clearing existing transport %s", this.transport.name);
this.transport.removeAllListeners();
}
// set up transport
this.transport = transport;
// set up transport listeners
transport
.on("drain", this.onDrain.bind(this))
.on("packet", this.onPacket.bind(this))
.on("error", this.onError.bind(this))
.on("close", (reason) => this.onClose("transport close", reason));
}
/**
* Probes a transport.
*
* @param {String} name - transport name
* @private
*/
probe(name) {
debug('probing transport "%s"', name);
let transport = this.createTransport(name);
let failed = false;
Socket.priorWebsocketSuccess = false;
const onTransportOpen = () => {
if (failed)
return;
debug('probe transport "%s" opened', name);
transport.send([{ type: "ping", data: "probe" }]);
transport.once("packet", (msg) => {
if (failed)
return;
if ("pong" === msg.type && "probe" === msg.data) {
debug('probe transport "%s" pong', name);
this.upgrading = true;
this.emitReserved("upgrading", transport);
if (!transport)
return;
Socket.priorWebsocketSuccess = "websocket" === transport.name;
debug('pausing current transport "%s"', this.transport.name);
this.transport.pause(() => {
if (failed)
return;
if ("closed" === this.readyState)
return;
debug("changing transport and sending upgrade packet");
cleanup();
this.setTransport(transport);
transport.send([{ type: "upgrade" }]);
this.emitReserved("upgrade", transport);
transport = null;
this.upgrading = false;
this.flush();
});
}
else {
debug('probe transport "%s" failed', name);
const err = new Error("probe error");
// @ts-ignore
err.transport = transport.name;
this.emitReserved("upgradeError", err);
}
});
};
function freezeTransport() {
if (failed)
return;
// Any callback called by transport should be ignored since now
failed = true;
cleanup();
transport.close();
transport = null;
}
// Handle any error that happens while probing
const onerror = (err) => {
const error = new Error("probe error: " + err);
// @ts-ignore
error.transport = transport.name;
freezeTransport();
debug('probe transport "%s" failed because of error: %s', name, err);
this.emitReserved("upgradeError", error);
};
function onTransportClose() {
onerror("transport closed");
}
// When the socket is closed while we're probing
function onclose() {
onerror("socket closed");
}
// When the socket is upgraded while we're probing
function onupgrade(to) {
if (transport && to.name !== transport.name) {
debug('"%s" works - aborting "%s"', to.name, transport.name);
freezeTransport();
}
}
// Remove all listeners on the transport and on self
const cleanup = () => {
transport.removeListener("open", onTransportOpen);
transport.removeListener("error", onerror);
transport.removeListener("close", onTransportClose);
this.off("close", onclose);
this.off("upgrading", onupgrade);
};
transport.once("open", onTransportOpen);
transport.once("error", onerror);
transport.once("close", onTransportClose);
this.once("close", onclose);
this.once("upgrading", onupgrade);
if (this.upgrades.indexOf("webtransport") !== -1 &&
name !== "webtransport") {
// favor WebTransport
this.setTimeoutFn(() => {
if (!failed) {
transport.open();
}
}, 200);
}
else {
transport.open();
}
}
/**
* Called when connection is deemed open.
*
* @private
*/
onOpen() {
debug("socket open");
this.readyState = "open";
Socket.priorWebsocketSuccess = "websocket" === this.transport.name;
this.emitReserved("open");
this.flush();
// we check for `readyState` in case an `open`
// listener already closed the socket
if ("open" === this.readyState && this.opts.upgrade) {
debug("starting upgrade probes");
let i = 0;
const l = this.upgrades.length;
for (; i < l; i++) {
this.probe(this.upgrades[i]);
}
}
}
/**
* Handles a packet.
*
* @private
*/
onPacket(packet) {
if ("opening" === this.readyState ||
"open" === this.readyState ||
"closing" === this.readyState) {
debug('socket receive: type "%s", data "%s"', packet.type, packet.data);
this.emitReserved("packet", packet);
// Socket is live - any packet counts
this.emitReserved("heartbeat");
this.resetPingTimeout();
switch (packet.type) {
case "open":
this.onHandshake(JSON.parse(packet.data));
break;
case "ping":
this.sendPacket("pong");
this.emitReserved("ping");
this.emitReserved("pong");
break;
case "error":
const err = new Error("server error");
// @ts-ignore
err.code = packet.data;
this.onError(err);
break;
case "message":
this.emitReserved("data", packet.data);
this.emitReserved("message", packet.data);
break;
}
}
else {
debug('packet received with socket readyState "%s"', this.readyState);
}
}
/**
* Called upon handshake completion.
*
* @param {Object} data - handshake obj
* @private
*/
onHandshake(data) {
this.emitReserved("handshake", data);
this.id = data.sid;
this.transport.query.sid = data.sid;
this.upgrades = this.filterUpgrades(data.upgrades);
this.pingInterval = data.pingInterval;
this.pingTimeout = data.pingTimeout;
this.maxPayload = data.maxPayload;
this.onOpen();
// In case open handler closes socket
if ("closed" === this.readyState)
return;
this.resetPingTimeout();
}
/**
* Sets and resets ping timeout timer based on server pings.
*
* @private
*/
resetPingTimeout() {
this.clearTimeoutFn(this.pingTimeoutTimer);
this.pingTimeoutTimer = this.setTimeoutFn(() => {
this.onClose("ping timeout");
}, this.pingInterval + this.pingTimeout);
if (this.opts.autoUnref) {
this.pingTimeoutTimer.unref();
}
}
/**
* Called on `drain` event
*
* @private
*/
onDrain() {
this.writeBuffer.splice(0, this.prevBufferLen);
// setting prevBufferLen = 0 is very important
// for example, when upgrading, upgrade packet is sent over,
// and a nonzero prevBufferLen could cause problems on `drain`
this.prevBufferLen = 0;
if (0 === this.writeBuffer.length) {
this.emitReserved("drain");
}
else {
this.flush();
}
}
/**
* Flush write buffers.
*
* @private
*/
flush() {
if ("closed" !== this.readyState &&
this.transport.writable &&
!this.upgrading &&
this.writeBuffer.length) {
const packets = this.getWritablePackets();
debug("flushing %d packets in socket", packets.length);
this.transport.send(packets);
// keep track of current length of writeBuffer
// splice writeBuffer and callbackBuffer on `drain`
this.prevBufferLen = packets.length;
this.emitReserved("flush");
}
}
/**
* Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP
* long-polling)
*
* @private
*/
getWritablePackets() {
const shouldCheckPayloadSize = this.maxPayload &&
this.transport.name === "polling" &&
this.writeBuffer.length > 1;
if (!shouldCheckPayloadSize) {
return this.writeBuffer;
}
let payloadSize = 1; // first packet type
for (let i = 0; i < this.writeBuffer.length; i++) {
const data = this.writeBuffer[i].data;
if (data) {
payloadSize += byteLength(data);
}
if (i > 0 && payloadSize > this.maxPayload) {
debug("only send %d out of %d packets", i, this.writeBuffer.length);
return this.writeBuffer.slice(0, i);
}
payloadSize += 2; // separator + packet type
}
debug("payload size is %d (max: %d)", payloadSize, this.maxPayload);
return this.writeBuffer;
}
/**
* Sends a message.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} callback function.
* @return {Socket} for chaining.
*/
write(msg, options, fn) {
this.sendPacket("message", msg, options, fn);
return this;
}
send(msg, options, fn) {
this.sendPacket("message", msg, options, fn);
return this;
}
/**
* Sends a packet.
*
* @param {String} type: packet type.
* @param {String} data.
* @param {Object} options.
* @param {Function} fn - callback function.
* @private
*/
sendPacket(type, data, options, fn) {
if ("function" === typeof data) {
fn = data;
data = undefined;
}
if ("function" === typeof options) {
fn = options;
options = null;
}
if ("closing" === this.readyState || "closed" === this.readyState) {
return;
}
options = options || {};
options.compress = false !== options.compress;
const packet = {
type: type,
data: data,
options: options,
};
this.emitReserved("packetCreate", packet);
this.writeBuffer.push(packet);
if (fn)
this.once("flush", fn);
this.flush();
}
/**
* Closes the connection.
*/
close() {
const close = () => {
this.onClose("forced close");
debug("socket closing - telling transport to close");
this.transport.close();
};
const cleanupAndClose = () => {
this.off("upgrade", cleanupAndClose);
this.off("upgradeError", cleanupAndClose);
close();
};
const waitForUpgrade = () => {
// wait for upgrade to finish since we can't send packets while pausing a transport
this.once("upgrade", cleanupAndClose);
this.once("upgradeError", cleanupAndClose);
};
if ("opening" === this.readyState || "open" === this.readyState) {
this.readyState = "closing";
if (this.writeBuffer.length) {
this.once("drain", () => {
if (this.upgrading) {
waitForUpgrade();
}
else {
close();
}
});
}
else if (this.upgrading) {
waitForUpgrade();
}
else {
close();
}
}
return this;
}
/**
* Called upon transport error
*
* @private
*/
onError(err) {
debug("socket error %j", err);
Socket.priorWebsocketSuccess = false;
this.emitReserved("error", err);
this.onClose("transport error", err);
}
/**
* Called upon transport close.
*
* @private
*/
onClose(reason, description) {
if ("opening" === this.readyState ||
"open" === this.readyState ||
"closing" === this.readyState) {
debug('socket close with reason: "%s"', reason);
// clear timers
this.clearTimeoutFn(this.pingTimeoutTimer);
// stop event from firing again for transport
this.transport.removeAllListeners("close");
// ensure transport won't stay open
this.transport.close();
// ignore further transport communication
this.transport.removeAllListeners();
if (typeof removeEventListener === "function") {
removeEventListener("beforeunload", this.beforeunloadEventListener, false);
removeEventListener("offline", this.offlineEventListener, false);
}
// set ready state
this.readyState = "closed";
// clear session id
this.id = null;
// emit close event
this.emitReserved("close", reason, description);
// clean buffers after, so users can still
// grab the buffers on `close` event
this.writeBuffer = [];
this.prevBufferLen = 0;
}
}
/**
* Filters upgrades, returning only those matching client transports.
*
* @param {Array} upgrades - server upgrades
* @private
*/
filterUpgrades(upgrades) {
const filteredUpgrades = [];
let i = 0;
const j = upgrades.length;
for (; i < j; i++) {
if (~this.transports.indexOf(upgrades[i]))
filteredUpgrades.push(upgrades[i]);
}
return filteredUpgrades;
}
}
Socket.protocol = protocol;

View File

@@ -0,0 +1,106 @@
import type { Packet, RawData } from "engine.io-parser";
import { Emitter } from "@socket.io/component-emitter";
import { SocketOptions } from "./socket.js";
export declare class TransportError extends Error {
readonly description: any;
readonly context: any;
readonly type = "TransportError";
constructor(reason: string, description: any, context: any);
}
export interface CloseDetails {
description: string;
context?: unknown;
}
interface TransportReservedEvents {
open: () => void;
error: (err: TransportError) => void;
packet: (packet: Packet) => void;
close: (details?: CloseDetails) => void;
poll: () => void;
pollComplete: () => void;
drain: () => void;
}
type TransportState = "opening" | "open" | "closed" | "pausing" | "paused";
export declare abstract class Transport extends Emitter<Record<never, never>, Record<never, never>, TransportReservedEvents> {
query: Record<string, string>;
writable: boolean;
protected opts: SocketOptions;
protected supportsBinary: boolean;
protected readyState: TransportState;
protected socket: any;
protected setTimeoutFn: typeof setTimeout;
/**
* Transport abstract constructor.
*
* @param {Object} opts - options
* @protected
*/
constructor(opts: any);
/**
* Emits an error.
*
* @param {String} reason
* @param description
* @param context - the error context
* @return {Transport} for chaining
* @protected
*/
protected onError(reason: string, description: any, context?: any): this;
/**
* Opens the transport.
*/
open(): this;
/**
* Closes the transport.
*/
close(): this;
/**
* Sends multiple packets.
*
* @param {Array} packets
*/
send(packets: any): void;
/**
* Called upon open
*
* @protected
*/
protected onOpen(): void;
/**
* Called with data.
*
* @param {String} data
* @protected
*/
protected onData(data: RawData): void;
/**
* Called with a decoded packet.
*
* @protected
*/
protected onPacket(packet: Packet): void;
/**
* Called upon close.
*
* @protected
*/
protected onClose(details?: CloseDetails): void;
/**
* The name of the transport
*/
abstract get name(): string;
/**
* Pauses the transport, in order not to lose packets during an upgrade.
*
* @param onPause
*/
pause(onPause: () => void): void;
protected createUri(schema: string, query?: Record<string, unknown>): string;
private _hostname;
private _port;
private _query;
protected abstract doOpen(): any;
protected abstract doClose(): any;
protected abstract write(packets: Packet[]): any;
}
export {};

View File

@@ -0,0 +1,144 @@
import { decodePacket } from "engine.io-parser";
import { Emitter } from "@socket.io/component-emitter";
import { installTimerFunctions } from "./util.js";
import debugModule from "debug"; // debug()
import { encode } from "./contrib/parseqs.js";
const debug = debugModule("engine.io-client:transport"); // debug()
export class TransportError extends Error {
constructor(reason, description, context) {
super(reason);
this.description = description;
this.context = context;
this.type = "TransportError";
}
}
export class Transport extends Emitter {
/**
* Transport abstract constructor.
*
* @param {Object} opts - options
* @protected
*/
constructor(opts) {
super();
this.writable = false;
installTimerFunctions(this, opts);
this.opts = opts;
this.query = opts.query;
this.socket = opts.socket;
}
/**
* Emits an error.
*
* @param {String} reason
* @param description
* @param context - the error context
* @return {Transport} for chaining
* @protected
*/
onError(reason, description, context) {
super.emitReserved("error", new TransportError(reason, description, context));
return this;
}
/**
* Opens the transport.
*/
open() {
this.readyState = "opening";
this.doOpen();
return this;
}
/**
* Closes the transport.
*/
close() {
if (this.readyState === "opening" || this.readyState === "open") {
this.doClose();
this.onClose();
}
return this;
}
/**
* Sends multiple packets.
*
* @param {Array} packets
*/
send(packets) {
if (this.readyState === "open") {
this.write(packets);
}
else {
// this might happen if the transport was silently closed in the beforeunload event handler
debug("transport is not open, discarding packets");
}
}
/**
* Called upon open
*
* @protected
*/
onOpen() {
this.readyState = "open";
this.writable = true;
super.emitReserved("open");
}
/**
* Called with data.
*
* @param {String} data
* @protected
*/
onData(data) {
const packet = decodePacket(data, this.socket.binaryType);
this.onPacket(packet);
}
/**
* Called with a decoded packet.
*
* @protected
*/
onPacket(packet) {
super.emitReserved("packet", packet);
}
/**
* Called upon close.
*
* @protected
*/
onClose(details) {
this.readyState = "closed";
super.emitReserved("close", details);
}
/**
* Pauses the transport, in order not to lose packets during an upgrade.
*
* @param onPause
*/
pause(onPause) { }
createUri(schema, query = {}) {
return (schema +
"://" +
this._hostname() +
this._port() +
this.opts.path +
this._query(query));
}
_hostname() {
const hostname = this.opts.hostname;
return hostname.indexOf(":") === -1 ? hostname : "[" + hostname + "]";
}
_port() {
if (this.opts.port &&
((this.opts.secure && Number(this.opts.port !== 443)) ||
(!this.opts.secure && Number(this.opts.port) !== 80))) {
return ":" + this.opts.port;
}
else {
return "";
}
}
_query(query) {
const encodedQuery = encode(query);
return encodedQuery.length ? "?" + encodedQuery : "";
}
}

View File

@@ -0,0 +1,8 @@
import { Polling } from "./polling.js";
import { WS } from "./websocket.js";
import { WT } from "./webtransport.js";
export declare const transports: {
websocket: typeof WS;
webtransport: typeof WT;
polling: typeof Polling;
};

View File

@@ -0,0 +1,8 @@
import { Polling } from "./polling.js";
import { WS } from "./websocket.js";
import { WT } from "./webtransport.js";
export const transports = {
websocket: WS,
webtransport: WT,
polling: Polling,
};

View File

@@ -0,0 +1,137 @@
import { Transport } from "../transport.js";
import { RawData } from "engine.io-parser";
import { Emitter } from "@socket.io/component-emitter";
export declare class Polling extends Transport {
private readonly xd;
private polling;
private pollXhr;
private cookieJar?;
/**
* XHR Polling constructor.
*
* @param {Object} opts
* @package
*/
constructor(opts: any);
get name(): string;
/**
* Opens the socket (triggers polling). We write a PING message to determine
* when the transport is open.
*
* @protected
*/
doOpen(): void;
/**
* Pauses polling.
*
* @param {Function} onPause - callback upon buffers are flushed and transport is paused
* @package
*/
pause(onPause: any): void;
/**
* Starts polling cycle.
*
* @private
*/
poll(): void;
/**
* Overloads onData to detect payloads.
*
* @protected
*/
onData(data: any): void;
/**
* For polling, send a close packet.
*
* @protected
*/
doClose(): void;
/**
* Writes a packets payload.
*
* @param {Array} packets - data packets
* @protected
*/
write(packets: any): void;
/**
* Generates uri for connection.
*
* @private
*/
private uri;
/**
* Creates a request.
*
* @param {String} method
* @private
*/
request(opts?: {}): Request;
/**
* Sends data.
*
* @param {String} data to send.
* @param {Function} called upon flush.
* @private
*/
private doWrite;
/**
* Starts a poll cycle.
*
* @private
*/
private doPoll;
}
interface RequestReservedEvents {
success: () => void;
data: (data: RawData) => void;
error: (err: number | Error, context: unknown) => void;
}
export declare class Request extends Emitter<{}, {}, RequestReservedEvents> {
private readonly opts;
private readonly method;
private readonly uri;
private readonly data;
private xhr;
private setTimeoutFn;
private index;
static requestsCount: number;
static requests: {};
/**
* Request constructor
*
* @param {Object} options
* @package
*/
constructor(uri: any, opts: any);
/**
* Creates the XHR object and sends the request.
*
* @private
*/
private create;
/**
* Called upon error.
*
* @private
*/
private onError;
/**
* Cleans up house.
*
* @private
*/
private cleanup;
/**
* Called upon load.
*
* @private
*/
private onLoad;
/**
* Aborts the request.
*
* @package
*/
abort(): void;
}
export {};

View File

@@ -0,0 +1,406 @@
import { Transport } from "../transport.js";
import debugModule from "debug"; // debug()
import { yeast } from "../contrib/yeast.js";
import { encodePayload, decodePayload } from "engine.io-parser";
import { createCookieJar, XHR as XMLHttpRequest, } from "./xmlhttprequest.js";
import { Emitter } from "@socket.io/component-emitter";
import { installTimerFunctions, pick } from "../util.js";
import { globalThisShim as globalThis } from "../globalThis.js";
const debug = debugModule("engine.io-client:polling"); // debug()
function empty() { }
const hasXHR2 = (function () {
const xhr = new XMLHttpRequest({
xdomain: false,
});
return null != xhr.responseType;
})();
export class Polling extends Transport {
/**
* XHR Polling constructor.
*
* @param {Object} opts
* @package
*/
constructor(opts) {
super(opts);
this.polling = false;
if (typeof location !== "undefined") {
const isSSL = "https:" === location.protocol;
let port = location.port;
// some user agents have empty `location.port`
if (!port) {
port = isSSL ? "443" : "80";
}
this.xd =
(typeof location !== "undefined" &&
opts.hostname !== location.hostname) ||
port !== opts.port;
}
/**
* XHR supports binary
*/
const forceBase64 = opts && opts.forceBase64;
this.supportsBinary = hasXHR2 && !forceBase64;
if (this.opts.withCredentials) {
this.cookieJar = createCookieJar();
}
}
get name() {
return "polling";
}
/**
* Opens the socket (triggers polling). We write a PING message to determine
* when the transport is open.
*
* @protected
*/
doOpen() {
this.poll();
}
/**
* Pauses polling.
*
* @param {Function} onPause - callback upon buffers are flushed and transport is paused
* @package
*/
pause(onPause) {
this.readyState = "pausing";
const pause = () => {
debug("paused");
this.readyState = "paused";
onPause();
};
if (this.polling || !this.writable) {
let total = 0;
if (this.polling) {
debug("we are currently polling - waiting to pause");
total++;
this.once("pollComplete", function () {
debug("pre-pause polling complete");
--total || pause();
});
}
if (!this.writable) {
debug("we are currently writing - waiting to pause");
total++;
this.once("drain", function () {
debug("pre-pause writing complete");
--total || pause();
});
}
}
else {
pause();
}
}
/**
* Starts polling cycle.
*
* @private
*/
poll() {
debug("polling");
this.polling = true;
this.doPoll();
this.emitReserved("poll");
}
/**
* Overloads onData to detect payloads.
*
* @protected
*/
onData(data) {
debug("polling got data %s", data);
const callback = (packet) => {
// if its the first message we consider the transport open
if ("opening" === this.readyState && packet.type === "open") {
this.onOpen();
}
// if its a close packet, we close the ongoing requests
if ("close" === packet.type) {
this.onClose({ description: "transport closed by the server" });
return false;
}
// otherwise bypass onData and handle the message
this.onPacket(packet);
};
// decode payload
decodePayload(data, this.socket.binaryType).forEach(callback);
// if an event did not trigger closing
if ("closed" !== this.readyState) {
// if we got data we're not polling
this.polling = false;
this.emitReserved("pollComplete");
if ("open" === this.readyState) {
this.poll();
}
else {
debug('ignoring poll - transport state "%s"', this.readyState);
}
}
}
/**
* For polling, send a close packet.
*
* @protected
*/
doClose() {
const close = () => {
debug("writing close packet");
this.write([{ type: "close" }]);
};
if ("open" === this.readyState) {
debug("transport open - closing");
close();
}
else {
// in case we're trying to close while
// handshaking is in progress (GH-164)
debug("transport not open - deferring close");
this.once("open", close);
}
}
/**
* Writes a packets payload.
*
* @param {Array} packets - data packets
* @protected
*/
write(packets) {
this.writable = false;
encodePayload(packets, (data) => {
this.doWrite(data, () => {
this.writable = true;
this.emitReserved("drain");
});
});
}
/**
* Generates uri for connection.
*
* @private
*/
uri() {
const schema = this.opts.secure ? "https" : "http";
const query = this.query || {};
// cache busting is forced
if (false !== this.opts.timestampRequests) {
query[this.opts.timestampParam] = yeast();
}
if (!this.supportsBinary && !query.sid) {
query.b64 = 1;
}
return this.createUri(schema, query);
}
/**
* Creates a request.
*
* @param {String} method
* @private
*/
request(opts = {}) {
Object.assign(opts, { xd: this.xd, cookieJar: this.cookieJar }, this.opts);
return new Request(this.uri(), opts);
}
/**
* Sends data.
*
* @param {String} data to send.
* @param {Function} called upon flush.
* @private
*/
doWrite(data, fn) {
const req = this.request({
method: "POST",
data: data,
});
req.on("success", fn);
req.on("error", (xhrStatus, context) => {
this.onError("xhr post error", xhrStatus, context);
});
}
/**
* Starts a poll cycle.
*
* @private
*/
doPoll() {
debug("xhr poll");
const req = this.request();
req.on("data", this.onData.bind(this));
req.on("error", (xhrStatus, context) => {
this.onError("xhr poll error", xhrStatus, context);
});
this.pollXhr = req;
}
}
export class Request extends Emitter {
/**
* Request constructor
*
* @param {Object} options
* @package
*/
constructor(uri, opts) {
super();
installTimerFunctions(this, opts);
this.opts = opts;
this.method = opts.method || "GET";
this.uri = uri;
this.data = undefined !== opts.data ? opts.data : null;
this.create();
}
/**
* Creates the XHR object and sends the request.
*
* @private
*/
create() {
var _a;
const opts = pick(this.opts, "agent", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "autoUnref");
opts.xdomain = !!this.opts.xd;
const xhr = (this.xhr = new XMLHttpRequest(opts));
try {
debug("xhr open %s: %s", this.method, this.uri);
xhr.open(this.method, this.uri, true);
try {
if (this.opts.extraHeaders) {
xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true);
for (let i in this.opts.extraHeaders) {
if (this.opts.extraHeaders.hasOwnProperty(i)) {
xhr.setRequestHeader(i, this.opts.extraHeaders[i]);
}
}
}
}
catch (e) { }
if ("POST" === this.method) {
try {
xhr.setRequestHeader("Content-type", "text/plain;charset=UTF-8");
}
catch (e) { }
}
try {
xhr.setRequestHeader("Accept", "*/*");
}
catch (e) { }
(_a = this.opts.cookieJar) === null || _a === void 0 ? void 0 : _a.addCookies(xhr);
// ie6 check
if ("withCredentials" in xhr) {
xhr.withCredentials = this.opts.withCredentials;
}
if (this.opts.requestTimeout) {
xhr.timeout = this.opts.requestTimeout;
}
xhr.onreadystatechange = () => {
var _a;
if (xhr.readyState === 3) {
(_a = this.opts.cookieJar) === null || _a === void 0 ? void 0 : _a.parseCookies(xhr);
}
if (4 !== xhr.readyState)
return;
if (200 === xhr.status || 1223 === xhr.status) {
this.onLoad();
}
else {
// make sure the `error` event handler that's user-set
// does not throw in the same tick and gets caught here
this.setTimeoutFn(() => {
this.onError(typeof xhr.status === "number" ? xhr.status : 0);
}, 0);
}
};
debug("xhr data %s", this.data);
xhr.send(this.data);
}
catch (e) {
// Need to defer since .create() is called directly from the constructor
// and thus the 'error' event can only be only bound *after* this exception
// occurs. Therefore, also, we cannot throw here at all.
this.setTimeoutFn(() => {
this.onError(e);
}, 0);
return;
}
if (typeof document !== "undefined") {
this.index = Request.requestsCount++;
Request.requests[this.index] = this;
}
}
/**
* Called upon error.
*
* @private
*/
onError(err) {
this.emitReserved("error", err, this.xhr);
this.cleanup(true);
}
/**
* Cleans up house.
*
* @private
*/
cleanup(fromError) {
if ("undefined" === typeof this.xhr || null === this.xhr) {
return;
}
this.xhr.onreadystatechange = empty;
if (fromError) {
try {
this.xhr.abort();
}
catch (e) { }
}
if (typeof document !== "undefined") {
delete Request.requests[this.index];
}
this.xhr = null;
}
/**
* Called upon load.
*
* @private
*/
onLoad() {
const data = this.xhr.responseText;
if (data !== null) {
this.emitReserved("data", data);
this.emitReserved("success");
this.cleanup();
}
}
/**
* Aborts the request.
*
* @package
*/
abort() {
this.cleanup();
}
}
Request.requestsCount = 0;
Request.requests = {};
/**
* Aborts pending requests when unloading the window. This is needed to prevent
* memory leaks (e.g. when using IE) and to ensure that no spurious error is
* emitted.
*/
if (typeof document !== "undefined") {
// @ts-ignore
if (typeof attachEvent === "function") {
// @ts-ignore
attachEvent("onunload", unloadHandler);
}
else if (typeof addEventListener === "function") {
const terminationEvent = "onpagehide" in globalThis ? "pagehide" : "unload";
addEventListener(terminationEvent, unloadHandler, false);
}
}
function unloadHandler() {
for (let i in Request.requests) {
if (Request.requests.hasOwnProperty(i)) {
Request.requests[i].abort();
}
}
}

View File

@@ -0,0 +1,4 @@
export declare const nextTick: (cb: any, setTimeoutFn: any) => any;
export declare const WebSocket: any;
export declare const usingBrowserWebSocket = true;
export declare const defaultBinaryType = "arraybuffer";

View File

@@ -0,0 +1,13 @@
import { globalThisShim as globalThis } from "../globalThis.js";
export const nextTick = (() => {
const isPromiseAvailable = typeof Promise === "function" && typeof Promise.resolve === "function";
if (isPromiseAvailable) {
return (cb) => Promise.resolve().then(cb);
}
else {
return (cb, setTimeoutFn) => setTimeoutFn(cb, 0);
}
})();
export const WebSocket = globalThis.WebSocket || globalThis.MozWebSocket;
export const usingBrowserWebSocket = true;
export const defaultBinaryType = "arraybuffer";

View File

@@ -0,0 +1,4 @@
export declare const WebSocket: any;
export declare const usingBrowserWebSocket = false;
export declare const defaultBinaryType = "nodebuffer";
export declare const nextTick: (callback: Function, ...args: any[]) => void;

View File

@@ -0,0 +1,5 @@
import ws from "ws";
export const WebSocket = ws;
export const usingBrowserWebSocket = false;
export const defaultBinaryType = "nodebuffer";
export const nextTick = process.nextTick;

View File

@@ -0,0 +1,34 @@
import { Transport } from "../transport.js";
export declare class WS extends Transport {
private ws;
/**
* WebSocket transport constructor.
*
* @param {Object} opts - connection options
* @protected
*/
constructor(opts: any);
get name(): string;
doOpen(): this;
/**
* Adds event listeners to the socket
*
* @private
*/
private addEventListeners;
write(packets: any): void;
doClose(): void;
/**
* Generates uri for connection.
*
* @private
*/
private uri;
/**
* Feature detection for WebSocket.
*
* @return {Boolean} whether this transport is available.
* @private
*/
private check;
}

View File

@@ -0,0 +1,155 @@
import { Transport } from "../transport.js";
import { yeast } from "../contrib/yeast.js";
import { pick } from "../util.js";
import { nextTick, usingBrowserWebSocket, WebSocket, } from "./websocket-constructor.js";
import debugModule from "debug"; // debug()
import { encodePacket } from "engine.io-parser";
const debug = debugModule("engine.io-client:websocket"); // debug()
// detect ReactNative environment
const isReactNative = typeof navigator !== "undefined" &&
typeof navigator.product === "string" &&
navigator.product.toLowerCase() === "reactnative";
export class WS extends Transport {
/**
* WebSocket transport constructor.
*
* @param {Object} opts - connection options
* @protected
*/
constructor(opts) {
super(opts);
this.supportsBinary = !opts.forceBase64;
}
get name() {
return "websocket";
}
doOpen() {
if (!this.check()) {
// let probe timeout
return;
}
const uri = this.uri();
const protocols = this.opts.protocols;
// React Native only supports the 'headers' option, and will print a warning if anything else is passed
const opts = isReactNative
? {}
: pick(this.opts, "agent", "perMessageDeflate", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "localAddress", "protocolVersion", "origin", "maxPayload", "family", "checkServerIdentity");
if (this.opts.extraHeaders) {
opts.headers = this.opts.extraHeaders;
}
try {
this.ws =
usingBrowserWebSocket && !isReactNative
? protocols
? new WebSocket(uri, protocols)
: new WebSocket(uri)
: new WebSocket(uri, protocols, opts);
}
catch (err) {
return this.emitReserved("error", err);
}
this.ws.binaryType = this.socket.binaryType;
this.addEventListeners();
}
/**
* Adds event listeners to the socket
*
* @private
*/
addEventListeners() {
this.ws.onopen = () => {
if (this.opts.autoUnref) {
this.ws._socket.unref();
}
this.onOpen();
};
this.ws.onclose = (closeEvent) => this.onClose({
description: "websocket connection closed",
context: closeEvent,
});
this.ws.onmessage = (ev) => this.onData(ev.data);
this.ws.onerror = (e) => this.onError("websocket error", e);
}
write(packets) {
this.writable = false;
// encodePacket efficient as it uses WS framing
// no need for encodePayload
for (let i = 0; i < packets.length; i++) {
const packet = packets[i];
const lastPacket = i === packets.length - 1;
encodePacket(packet, this.supportsBinary, (data) => {
// always create a new object (GH-437)
const opts = {};
if (!usingBrowserWebSocket) {
if (packet.options) {
opts.compress = packet.options.compress;
}
if (this.opts.perMessageDeflate) {
const len =
// @ts-ignore
"string" === typeof data ? Buffer.byteLength(data) : data.length;
if (len < this.opts.perMessageDeflate.threshold) {
opts.compress = false;
}
}
}
// Sometimes the websocket has already been closed but the browser didn't
// have a chance of informing us about it yet, in that case send will
// throw an error
try {
if (usingBrowserWebSocket) {
// TypeError is thrown when passing the second argument on Safari
this.ws.send(data);
}
else {
this.ws.send(data, opts);
}
}
catch (e) {
debug("websocket closed before onclose event");
}
if (lastPacket) {
// fake drain
// defer to next tick to allow Socket to clear writeBuffer
nextTick(() => {
this.writable = true;
this.emitReserved("drain");
}, this.setTimeoutFn);
}
});
}
}
doClose() {
if (typeof this.ws !== "undefined") {
this.ws.close();
this.ws = null;
}
}
/**
* Generates uri for connection.
*
* @private
*/
uri() {
const schema = this.opts.secure ? "wss" : "ws";
const query = this.query || {};
// append timestamp to URI
if (this.opts.timestampRequests) {
query[this.opts.timestampParam] = yeast();
}
// communicate binary support capabilities
if (!this.supportsBinary) {
query.b64 = 1;
}
return this.createUri(schema, query);
}
/**
* Feature detection for WebSocket.
*
* @return {Boolean} whether this transport is available.
* @private
*/
check() {
return !!WebSocket;
}
}

View File

@@ -0,0 +1,10 @@
import { Transport } from "../transport.js";
import { Packet } from "engine.io-parser";
export declare class WT extends Transport {
private transport;
private writer;
get name(): string;
protected doOpen(): void;
protected write(packets: Packet[]): void;
protected doClose(): void;
}

View File

@@ -0,0 +1,78 @@
import { Transport } from "../transport.js";
import { nextTick } from "./websocket-constructor.js";
import { createPacketDecoderStream, createPacketEncoderStream, } from "engine.io-parser";
import debugModule from "debug"; // debug()
const debug = debugModule("engine.io-client:webtransport"); // debug()
export class WT extends Transport {
get name() {
return "webtransport";
}
doOpen() {
// @ts-ignore
if (typeof WebTransport !== "function") {
return;
}
// @ts-ignore
this.transport = new WebTransport(this.createUri("https"), this.opts.transportOptions[this.name]);
this.transport.closed
.then(() => {
debug("transport closed gracefully");
this.onClose();
})
.catch((err) => {
debug("transport closed due to %s", err);
this.onError("webtransport error", err);
});
// note: we could have used async/await, but that would require some additional polyfills
this.transport.ready.then(() => {
this.transport.createBidirectionalStream().then((stream) => {
const decoderStream = createPacketDecoderStream(Number.MAX_SAFE_INTEGER, this.socket.binaryType);
const reader = stream.readable.pipeThrough(decoderStream).getReader();
const encoderStream = createPacketEncoderStream();
encoderStream.readable.pipeTo(stream.writable);
this.writer = encoderStream.writable.getWriter();
const read = () => {
reader
.read()
.then(({ done, value }) => {
if (done) {
debug("session is closed");
return;
}
debug("received chunk: %o", value);
this.onPacket(value);
read();
})
.catch((err) => {
debug("an error occurred while reading: %s", err);
});
};
read();
const packet = { type: "open" };
if (this.query.sid) {
packet.data = `{"sid":"${this.query.sid}"}`;
}
this.writer.write(packet).then(() => this.onOpen());
});
});
}
write(packets) {
this.writable = false;
for (let i = 0; i < packets.length; i++) {
const packet = packets[i];
const lastPacket = i === packets.length - 1;
this.writer.write(packet).then(() => {
if (lastPacket) {
nextTick(() => {
this.writable = true;
this.emitReserved("drain");
}, this.setTimeoutFn);
}
});
}
}
doClose() {
var _a;
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.close();
}
}

View File

@@ -0,0 +1,2 @@
export declare function XHR(opts: any): any;
export declare function createCookieJar(): void;

View File

@@ -0,0 +1,20 @@
// browser shim for xmlhttprequest module
import { hasCORS } from "../contrib/has-cors.js";
import { globalThisShim as globalThis } from "../globalThis.js";
export function XHR(opts) {
const xdomain = opts.xdomain;
// XMLHttpRequest can be disabled on IE
try {
if ("undefined" !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {
return new XMLHttpRequest();
}
}
catch (e) { }
if (!xdomain) {
try {
return new globalThis[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP");
}
catch (e) { }
}
}
export function createCookieJar() { }

View File

@@ -0,0 +1,17 @@
export declare const XHR: any;
export declare function createCookieJar(): CookieJar;
interface Cookie {
name: string;
value: string;
expires?: Date;
}
/**
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
*/
export declare function parse(setCookieString: string): Cookie;
export declare class CookieJar {
private cookies;
parseCookies(xhr: any): void;
addCookies(xhr: any): void;
}
export {};

View File

@@ -0,0 +1,82 @@
import * as XMLHttpRequestModule from "xmlhttprequest-ssl";
export const XHR = XMLHttpRequestModule.default || XMLHttpRequestModule;
export function createCookieJar() {
return new CookieJar();
}
/**
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
*/
export function parse(setCookieString) {
const parts = setCookieString.split("; ");
const i = parts[0].indexOf("=");
if (i === -1) {
return;
}
const name = parts[0].substring(0, i).trim();
if (!name.length) {
return;
}
let value = parts[0].substring(i + 1).trim();
if (value.charCodeAt(0) === 0x22) {
// remove double quotes
value = value.slice(1, -1);
}
const cookie = {
name,
value,
};
for (let j = 1; j < parts.length; j++) {
const subParts = parts[j].split("=");
if (subParts.length !== 2) {
continue;
}
const key = subParts[0].trim();
const value = subParts[1].trim();
switch (key) {
case "Expires":
cookie.expires = new Date(value);
break;
case "Max-Age":
const expiration = new Date();
expiration.setUTCSeconds(expiration.getUTCSeconds() + parseInt(value, 10));
cookie.expires = expiration;
break;
default:
// ignore other keys
}
}
return cookie;
}
export class CookieJar {
constructor() {
this.cookies = new Map();
}
parseCookies(xhr) {
const values = xhr.getResponseHeader("set-cookie");
if (!values) {
return;
}
values.forEach((value) => {
const parsed = parse(value);
if (parsed) {
this.cookies.set(parsed.name, parsed);
}
});
}
addCookies(xhr) {
const cookies = [];
this.cookies.forEach((cookie, name) => {
var _a;
if (((_a = cookie.expires) === null || _a === void 0 ? void 0 : _a.getTime()) < Date.now()) {
this.cookies.delete(name);
}
else {
cookies.push(`${name}=${cookie.value}`);
}
});
if (cookies.length) {
xhr.setDisableHeaderCheck(true);
xhr.setRequestHeader("cookie", cookies.join("; "));
}
}
}

View File

@@ -0,0 +1,3 @@
export declare function pick(obj: any, ...attr: any[]): any;
export declare function installTimerFunctions(obj: any, opts: any): void;
export declare function byteLength(obj: any): number;

52
node_modules/engine.io-client/build/esm-debug/util.js generated vendored Normal file
View File

@@ -0,0 +1,52 @@
import { globalThisShim as globalThis } from "./globalThis.js";
export function pick(obj, ...attr) {
return attr.reduce((acc, k) => {
if (obj.hasOwnProperty(k)) {
acc[k] = obj[k];
}
return acc;
}, {});
}
// Keep a reference to the real timeout functions so they can be used when overridden
const NATIVE_SET_TIMEOUT = globalThis.setTimeout;
const NATIVE_CLEAR_TIMEOUT = globalThis.clearTimeout;
export function installTimerFunctions(obj, opts) {
if (opts.useNativeTimers) {
obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(globalThis);
obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(globalThis);
}
else {
obj.setTimeoutFn = globalThis.setTimeout.bind(globalThis);
obj.clearTimeoutFn = globalThis.clearTimeout.bind(globalThis);
}
}
// base64 encoded buffers are about 33% bigger (https://en.wikipedia.org/wiki/Base64)
const BASE64_OVERHEAD = 1.33;
// we could also have used `new Blob([obj]).size`, but it isn't supported in IE9
export function byteLength(obj) {
if (typeof obj === "string") {
return utf8Length(obj);
}
// arraybuffer or blob
return Math.ceil((obj.byteLength || obj.size) * BASE64_OVERHEAD);
}
function utf8Length(str) {
let c = 0, length = 0;
for (let i = 0, l = str.length; i < l; i++) {
c = str.charCodeAt(i);
if (c < 0x80) {
length += 1;
}
else if (c < 0x800) {
length += 2;
}
else if (c < 0xd800 || c >= 0xe000) {
length += 3;
}
else {
i++;
length += 4;
}
}
return length;
}

View File

@@ -0,0 +1,3 @@
import { Socket } from "./socket.js";
declare const _default: (uri: any, opts: any) => Socket;
export default _default;

View File

@@ -0,0 +1,2 @@
import { Socket } from "./socket.js";
export default (uri, opts) => new Socket(uri, opts);

View File

@@ -0,0 +1 @@
export declare const hasCORS: boolean;

View File

@@ -0,0 +1,11 @@
// imported from https://github.com/component/has-cors
let value = false;
try {
value = typeof XMLHttpRequest !== 'undefined' &&
'withCredentials' in new XMLHttpRequest();
}
catch (err) {
// if XMLHttp support is disabled in IE then it will throw
// when trying to create
}
export const hasCORS = value;

View File

@@ -0,0 +1,15 @@
/**
* Compiles a querystring
* Returns string representation of the object
*
* @param {Object}
* @api private
*/
export declare function encode(obj: any): string;
/**
* Parses a simple querystring into an object
*
* @param {String} qs
* @api private
*/
export declare function decode(qs: any): {};

View File

@@ -0,0 +1,34 @@
// imported from https://github.com/galkn/querystring
/**
* Compiles a querystring
* Returns string representation of the object
*
* @param {Object}
* @api private
*/
export function encode(obj) {
let str = '';
for (let i in obj) {
if (obj.hasOwnProperty(i)) {
if (str.length)
str += '&';
str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
}
}
return str;
}
/**
* Parses a simple querystring into an object
*
* @param {String} qs
* @api private
*/
export function decode(qs) {
let qry = {};
let pairs = qs.split('&');
for (let i = 0, l = pairs.length; i < l; i++) {
let pair = pairs[i].split('=');
qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return qry;
}

View File

@@ -0,0 +1 @@
export declare function parse(str: string): any;

View File

@@ -0,0 +1,64 @@
// imported from https://github.com/galkn/parseuri
/**
* Parses a URI
*
* Note: we could also have used the built-in URL object, but it isn't supported on all platforms.
*
* See:
* - https://developer.mozilla.org/en-US/docs/Web/API/URL
* - https://caniuse.com/url
* - https://www.rfc-editor.org/rfc/rfc3986#appendix-B
*
* History of the parse() method:
* - first commit: https://github.com/socketio/socket.io-client/commit/4ee1d5d94b3906a9c052b459f1a818b15f38f91c
* - export into its own module: https://github.com/socketio/engine.io-client/commit/de2c561e4564efeb78f1bdb1ba39ef81b2822cb3
* - reimport: https://github.com/socketio/engine.io-client/commit/df32277c3f6d622eec5ed09f493cae3f3391d242
*
* @author Steven Levithan <stevenlevithan.com> (MIT license)
* @api private
*/
const re = /^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
const parts = [
'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
];
export function parse(str) {
if (str.length > 2000) {
throw "URI too long";
}
const src = str, b = str.indexOf('['), e = str.indexOf(']');
if (b != -1 && e != -1) {
str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
}
let m = re.exec(str || ''), uri = {}, i = 14;
while (i--) {
uri[parts[i]] = m[i] || '';
}
if (b != -1 && e != -1) {
uri.source = src;
uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
uri.ipv6uri = true;
}
uri.pathNames = pathNames(uri, uri['path']);
uri.queryKey = queryKey(uri, uri['query']);
return uri;
}
function pathNames(obj, path) {
const regx = /\/{2,9}/g, names = path.replace(regx, "/").split("/");
if (path.slice(0, 1) == '/' || path.length === 0) {
names.splice(0, 1);
}
if (path.slice(-1) == '/') {
names.splice(names.length - 1, 1);
}
return names;
}
function queryKey(uri, query) {
const data = {};
query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) {
if ($1) {
data[$1] = $2;
}
});
return data;
}

View File

@@ -0,0 +1,23 @@
/**
* Return a string representing the specified number.
*
* @param {Number} num The number to convert.
* @returns {String} The string representation of the number.
* @api public
*/
export declare function encode(num: any): string;
/**
* Return the integer value specified by the given string.
*
* @param {String} str The string to convert.
* @returns {Number} The integer value represented by the string.
* @api public
*/
export declare function decode(str: any): number;
/**
* Yeast: A tiny growing id generator.
*
* @returns {String} A unique id.
* @api public
*/
export declare function yeast(): string;

View File

@@ -0,0 +1,50 @@
// imported from https://github.com/unshiftio/yeast
'use strict';
const alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split(''), length = 64, map = {};
let seed = 0, i = 0, prev;
/**
* Return a string representing the specified number.
*
* @param {Number} num The number to convert.
* @returns {String} The string representation of the number.
* @api public
*/
export function encode(num) {
let encoded = '';
do {
encoded = alphabet[num % length] + encoded;
num = Math.floor(num / length);
} while (num > 0);
return encoded;
}
/**
* Return the integer value specified by the given string.
*
* @param {String} str The string to convert.
* @returns {Number} The integer value represented by the string.
* @api public
*/
export function decode(str) {
let decoded = 0;
for (i = 0; i < str.length; i++) {
decoded = decoded * length + map[str.charAt(i)];
}
return decoded;
}
/**
* Yeast: A tiny growing id generator.
*
* @returns {String} A unique id.
* @api public
*/
export function yeast() {
const now = encode(+new Date());
if (now !== prev)
return seed = 0, prev = now;
return now + '.' + encode(seed++);
}
//
// Map each character to its index.
//
for (; i < length; i++)
map[alphabet[i]] = i;

View File

@@ -0,0 +1 @@
export declare const globalThisShim: any;

View File

@@ -0,0 +1,11 @@
export const globalThisShim = (() => {
if (typeof self !== "undefined") {
return self;
}
else if (typeof window !== "undefined") {
return window;
}
else {
return Function("return this")();
}
})();

View File

@@ -0,0 +1 @@
export declare const globalThisShim: typeof globalThis;

View File

@@ -0,0 +1 @@
export const globalThisShim = global;

9
node_modules/engine.io-client/build/esm/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
import { Socket } from "./socket.js";
export { Socket };
export { SocketOptions } from "./socket.js";
export declare const protocol: number;
export { Transport, TransportError } from "./transport.js";
export { transports } from "./transports/index.js";
export { installTimerFunctions } from "./util.js";
export { parse } from "./contrib/parseuri.js";
export { nextTick } from "./transports/websocket-constructor.js";

8
node_modules/engine.io-client/build/esm/index.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
import { Socket } from "./socket.js";
export { Socket };
export const protocol = Socket.protocol;
export { Transport, TransportError } from "./transport.js";
export { transports } from "./transports/index.js";
export { installTimerFunctions } from "./util.js";
export { parse } from "./contrib/parseuri.js";
export { nextTick } from "./transports/websocket-constructor.js";

10
node_modules/engine.io-client/build/esm/package.json generated vendored Normal file
View File

@@ -0,0 +1,10 @@
{
"name": "engine.io-client",
"type": "module",
"browser": {
"ws": false,
"./transports/xmlhttprequest.js": "./transports/xmlhttprequest.browser.js",
"./transports/websocket-constructor.js": "./transports/websocket-constructor.browser.js",
"./globalThis.js": "./globalThis.browser.js"
}
}

362
node_modules/engine.io-client/build/esm/socket.d.ts generated vendored Normal file
View File

@@ -0,0 +1,362 @@
import { Emitter } from "@socket.io/component-emitter";
import type { Packet, BinaryType, RawData } from "engine.io-parser";
import { CloseDetails, Transport } from "./transport.js";
export interface SocketOptions {
/**
* The host that we're connecting to. Set from the URI passed when connecting
*/
host: string;
/**
* The hostname for our connection. Set from the URI passed when connecting
*/
hostname: string;
/**
* If this is a secure connection. Set from the URI passed when connecting
*/
secure: boolean;
/**
* The port for our connection. Set from the URI passed when connecting
*/
port: string | number;
/**
* Any query parameters in our uri. Set from the URI passed when connecting
*/
query: {
[key: string]: any;
};
/**
* `http.Agent` to use, defaults to `false` (NodeJS only)
*
* Note: the type should be "undefined | http.Agent | https.Agent | false", but this would break browser-only clients.
*
* @see https://nodejs.org/api/http.html#httprequestoptions-callback
*/
agent: string | boolean;
/**
* Whether the client should try to upgrade the transport from
* long-polling to something better.
* @default true
*/
upgrade: boolean;
/**
* Forces base 64 encoding for polling transport even when XHR2
* responseType is available and WebSocket even if the used standard
* supports binary.
*/
forceBase64: boolean;
/**
* The param name to use as our timestamp key
* @default 't'
*/
timestampParam: string;
/**
* Whether to add the timestamp with each transport request. Note: this
* is ignored if the browser is IE or Android, in which case requests
* are always stamped
* @default false
*/
timestampRequests: boolean;
/**
* A list of transports to try (in order). Engine.io always attempts to
* connect directly with the first one, provided the feature detection test
* for it passes.
*
* @default ['polling','websocket', 'webtransport']
*/
transports: string[];
/**
* If true and if the previous websocket connection to the server succeeded,
* the connection attempt will bypass the normal upgrade process and will
* initially try websocket. A connection attempt following a transport error
* will use the normal upgrade process. It is recommended you turn this on
* only when using SSL/TLS connections, or if you know that your network does
* not block websockets.
* @default false
*/
rememberUpgrade: boolean;
/**
* Are we only interested in transports that support binary?
*/
onlyBinaryUpgrades: boolean;
/**
* Timeout for xhr-polling requests in milliseconds (0) (only for polling transport)
*/
requestTimeout: number;
/**
* Transport options for Node.js client (headers etc)
*/
transportOptions: Object;
/**
* (SSL) Certificate, Private key and CA certificates to use for SSL.
* Can be used in Node.js client environment to manually specify
* certificate information.
*/
pfx: string;
/**
* (SSL) Private key to use for SSL. Can be used in Node.js client
* environment to manually specify certificate information.
*/
key: string;
/**
* (SSL) A string or passphrase for the private key or pfx. Can be
* used in Node.js client environment to manually specify certificate
* information.
*/
passphrase: string;
/**
* (SSL) Public x509 certificate to use. Can be used in Node.js client
* environment to manually specify certificate information.
*/
cert: string;
/**
* (SSL) An authority certificate or array of authority certificates to
* check the remote host against.. Can be used in Node.js client
* environment to manually specify certificate information.
*/
ca: string | string[];
/**
* (SSL) A string describing the ciphers to use or exclude. Consult the
* [cipher format list]
* (http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT) for
* details on the format.. Can be used in Node.js client environment to
* manually specify certificate information.
*/
ciphers: string;
/**
* (SSL) If true, the server certificate is verified against the list of
* supplied CAs. An 'error' event is emitted if verification fails.
* Verification happens at the connection level, before the HTTP request
* is sent. Can be used in Node.js client environment to manually specify
* certificate information.
*/
rejectUnauthorized: boolean;
/**
* Headers that will be passed for each request to the server (via xhr-polling and via websockets).
* These values then can be used during handshake or for special proxies.
*/
extraHeaders?: {
[header: string]: string;
};
/**
* Whether to include credentials (cookies, authorization headers, TLS
* client certificates, etc.) with cross-origin XHR polling requests
* @default false
*/
withCredentials: boolean;
/**
* Whether to automatically close the connection whenever the beforeunload event is received.
* @default false
*/
closeOnBeforeunload: boolean;
/**
* Whether to always use the native timeouts. This allows the client to
* reconnect when the native timeout functions are overridden, such as when
* mock clocks are installed.
* @default false
*/
useNativeTimers: boolean;
/**
* weather we should unref the reconnect timer when it is
* create automatically
* @default false
*/
autoUnref: boolean;
/**
* parameters of the WebSocket permessage-deflate extension (see ws module api docs). Set to false to disable.
* @default false
*/
perMessageDeflate: {
threshold: number;
};
/**
* The path to get our client file from, in the case of the server
* serving it
* @default '/engine.io'
*/
path: string;
/**
* Whether we should add a trailing slash to the request path.
* @default true
*/
addTrailingSlash: boolean;
/**
* Either a single protocol string or an array of protocol strings. These strings are used to indicate sub-protocols,
* so that a single server can implement multiple WebSocket sub-protocols (for example, you might want one server to
* be able to handle different types of interactions depending on the specified protocol)
* @default []
*/
protocols: string | string[];
}
interface HandshakeData {
sid: string;
upgrades: string[];
pingInterval: number;
pingTimeout: number;
maxPayload: number;
}
interface SocketReservedEvents {
open: () => void;
handshake: (data: HandshakeData) => void;
packet: (packet: Packet) => void;
packetCreate: (packet: Packet) => void;
data: (data: any) => void;
message: (data: any) => void;
drain: () => void;
flush: () => void;
heartbeat: () => void;
ping: () => void;
pong: () => void;
error: (err: string | Error) => void;
upgrading: (transport: any) => void;
upgrade: (transport: any) => void;
upgradeError: (err: Error) => void;
close: (reason: string, description?: CloseDetails | Error) => void;
}
type SocketState = "opening" | "open" | "closing" | "closed";
export declare class Socket extends Emitter<Record<never, never>, Record<never, never>, SocketReservedEvents> {
id: string;
transport: Transport;
binaryType: BinaryType;
readyState: SocketState;
writeBuffer: Packet[];
private prevBufferLen;
private upgrades;
private pingInterval;
private pingTimeout;
private pingTimeoutTimer;
private setTimeoutFn;
private clearTimeoutFn;
private readonly beforeunloadEventListener;
private readonly offlineEventListener;
private upgrading;
private maxPayload?;
private readonly opts;
private readonly secure;
private readonly hostname;
private readonly port;
private readonly transports;
static priorWebsocketSuccess: boolean;
static protocol: number;
/**
* Socket constructor.
*
* @param {String|Object} uri - uri or options
* @param {Object} opts - options
*/
constructor(uri: any, opts?: Partial<SocketOptions>);
/**
* Creates transport of the given type.
*
* @param {String} name - transport name
* @return {Transport}
* @private
*/
private createTransport;
/**
* Initializes transport to use and starts probe.
*
* @private
*/
private open;
/**
* Sets the current transport. Disables the existing one (if any).
*
* @private
*/
private setTransport;
/**
* Probes a transport.
*
* @param {String} name - transport name
* @private
*/
private probe;
/**
* Called when connection is deemed open.
*
* @private
*/
private onOpen;
/**
* Handles a packet.
*
* @private
*/
private onPacket;
/**
* Called upon handshake completion.
*
* @param {Object} data - handshake obj
* @private
*/
private onHandshake;
/**
* Sets and resets ping timeout timer based on server pings.
*
* @private
*/
private resetPingTimeout;
/**
* Called on `drain` event
*
* @private
*/
private onDrain;
/**
* Flush write buffers.
*
* @private
*/
private flush;
/**
* Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP
* long-polling)
*
* @private
*/
private getWritablePackets;
/**
* Sends a message.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} callback function.
* @return {Socket} for chaining.
*/
write(msg: RawData, options?: any, fn?: any): this;
send(msg: RawData, options?: any, fn?: any): this;
/**
* Sends a packet.
*
* @param {String} type: packet type.
* @param {String} data.
* @param {Object} options.
* @param {Function} fn - callback function.
* @private
*/
private sendPacket;
/**
* Closes the connection.
*/
close(): this;
/**
* Called upon transport error
*
* @private
*/
private onError;
/**
* Called upon transport close.
*
* @private
*/
private onClose;
/**
* Filters upgrades, returning only those matching client transports.
*
* @param {Array} upgrades - server upgrades
* @private
*/
private filterUpgrades;
}
export {};

594
node_modules/engine.io-client/build/esm/socket.js generated vendored Normal file
View File

@@ -0,0 +1,594 @@
import { transports } from "./transports/index.js";
import { installTimerFunctions, byteLength } from "./util.js";
import { decode } from "./contrib/parseqs.js";
import { parse } from "./contrib/parseuri.js";
import { Emitter } from "@socket.io/component-emitter";
import { protocol } from "engine.io-parser";
import { defaultBinaryType } from "./transports/websocket-constructor.js";
export class Socket extends Emitter {
/**
* Socket constructor.
*
* @param {String|Object} uri - uri or options
* @param {Object} opts - options
*/
constructor(uri, opts = {}) {
super();
this.binaryType = defaultBinaryType;
this.writeBuffer = [];
if (uri && "object" === typeof uri) {
opts = uri;
uri = null;
}
if (uri) {
uri = parse(uri);
opts.hostname = uri.host;
opts.secure = uri.protocol === "https" || uri.protocol === "wss";
opts.port = uri.port;
if (uri.query)
opts.query = uri.query;
}
else if (opts.host) {
opts.hostname = parse(opts.host).host;
}
installTimerFunctions(this, opts);
this.secure =
null != opts.secure
? opts.secure
: typeof location !== "undefined" && "https:" === location.protocol;
if (opts.hostname && !opts.port) {
// if no port is specified manually, use the protocol default
opts.port = this.secure ? "443" : "80";
}
this.hostname =
opts.hostname ||
(typeof location !== "undefined" ? location.hostname : "localhost");
this.port =
opts.port ||
(typeof location !== "undefined" && location.port
? location.port
: this.secure
? "443"
: "80");
this.transports = opts.transports || [
"polling",
"websocket",
"webtransport",
];
this.writeBuffer = [];
this.prevBufferLen = 0;
this.opts = Object.assign({
path: "/engine.io",
agent: false,
withCredentials: false,
upgrade: true,
timestampParam: "t",
rememberUpgrade: false,
addTrailingSlash: true,
rejectUnauthorized: true,
perMessageDeflate: {
threshold: 1024,
},
transportOptions: {},
closeOnBeforeunload: false,
}, opts);
this.opts.path =
this.opts.path.replace(/\/$/, "") +
(this.opts.addTrailingSlash ? "/" : "");
if (typeof this.opts.query === "string") {
this.opts.query = decode(this.opts.query);
}
// set on handshake
this.id = null;
this.upgrades = null;
this.pingInterval = null;
this.pingTimeout = null;
// set on heartbeat
this.pingTimeoutTimer = null;
if (typeof addEventListener === "function") {
if (this.opts.closeOnBeforeunload) {
// Firefox closes the connection when the "beforeunload" event is emitted but not Chrome. This event listener
// ensures every browser behaves the same (no "disconnect" event at the Socket.IO level when the page is
// closed/reloaded)
this.beforeunloadEventListener = () => {
if (this.transport) {
// silently close the transport
this.transport.removeAllListeners();
this.transport.close();
}
};
addEventListener("beforeunload", this.beforeunloadEventListener, false);
}
if (this.hostname !== "localhost") {
this.offlineEventListener = () => {
this.onClose("transport close", {
description: "network connection lost",
});
};
addEventListener("offline", this.offlineEventListener, false);
}
}
this.open();
}
/**
* Creates transport of the given type.
*
* @param {String} name - transport name
* @return {Transport}
* @private
*/
createTransport(name) {
const query = Object.assign({}, this.opts.query);
// append engine.io protocol identifier
query.EIO = protocol;
// transport name
query.transport = name;
// session id if we already have one
if (this.id)
query.sid = this.id;
const opts = Object.assign({}, this.opts, {
query,
socket: this,
hostname: this.hostname,
secure: this.secure,
port: this.port,
}, this.opts.transportOptions[name]);
return new transports[name](opts);
}
/**
* Initializes transport to use and starts probe.
*
* @private
*/
open() {
let transport;
if (this.opts.rememberUpgrade &&
Socket.priorWebsocketSuccess &&
this.transports.indexOf("websocket") !== -1) {
transport = "websocket";
}
else if (0 === this.transports.length) {
// Emit error on next tick so it can be listened to
this.setTimeoutFn(() => {
this.emitReserved("error", "No transports available");
}, 0);
return;
}
else {
transport = this.transports[0];
}
this.readyState = "opening";
// Retry with the next transport if the transport is disabled (jsonp: false)
try {
transport = this.createTransport(transport);
}
catch (e) {
this.transports.shift();
this.open();
return;
}
transport.open();
this.setTransport(transport);
}
/**
* Sets the current transport. Disables the existing one (if any).
*
* @private
*/
setTransport(transport) {
if (this.transport) {
this.transport.removeAllListeners();
}
// set up transport
this.transport = transport;
// set up transport listeners
transport
.on("drain", this.onDrain.bind(this))
.on("packet", this.onPacket.bind(this))
.on("error", this.onError.bind(this))
.on("close", (reason) => this.onClose("transport close", reason));
}
/**
* Probes a transport.
*
* @param {String} name - transport name
* @private
*/
probe(name) {
let transport = this.createTransport(name);
let failed = false;
Socket.priorWebsocketSuccess = false;
const onTransportOpen = () => {
if (failed)
return;
transport.send([{ type: "ping", data: "probe" }]);
transport.once("packet", (msg) => {
if (failed)
return;
if ("pong" === msg.type && "probe" === msg.data) {
this.upgrading = true;
this.emitReserved("upgrading", transport);
if (!transport)
return;
Socket.priorWebsocketSuccess = "websocket" === transport.name;
this.transport.pause(() => {
if (failed)
return;
if ("closed" === this.readyState)
return;
cleanup();
this.setTransport(transport);
transport.send([{ type: "upgrade" }]);
this.emitReserved("upgrade", transport);
transport = null;
this.upgrading = false;
this.flush();
});
}
else {
const err = new Error("probe error");
// @ts-ignore
err.transport = transport.name;
this.emitReserved("upgradeError", err);
}
});
};
function freezeTransport() {
if (failed)
return;
// Any callback called by transport should be ignored since now
failed = true;
cleanup();
transport.close();
transport = null;
}
// Handle any error that happens while probing
const onerror = (err) => {
const error = new Error("probe error: " + err);
// @ts-ignore
error.transport = transport.name;
freezeTransport();
this.emitReserved("upgradeError", error);
};
function onTransportClose() {
onerror("transport closed");
}
// When the socket is closed while we're probing
function onclose() {
onerror("socket closed");
}
// When the socket is upgraded while we're probing
function onupgrade(to) {
if (transport && to.name !== transport.name) {
freezeTransport();
}
}
// Remove all listeners on the transport and on self
const cleanup = () => {
transport.removeListener("open", onTransportOpen);
transport.removeListener("error", onerror);
transport.removeListener("close", onTransportClose);
this.off("close", onclose);
this.off("upgrading", onupgrade);
};
transport.once("open", onTransportOpen);
transport.once("error", onerror);
transport.once("close", onTransportClose);
this.once("close", onclose);
this.once("upgrading", onupgrade);
if (this.upgrades.indexOf("webtransport") !== -1 &&
name !== "webtransport") {
// favor WebTransport
this.setTimeoutFn(() => {
if (!failed) {
transport.open();
}
}, 200);
}
else {
transport.open();
}
}
/**
* Called when connection is deemed open.
*
* @private
*/
onOpen() {
this.readyState = "open";
Socket.priorWebsocketSuccess = "websocket" === this.transport.name;
this.emitReserved("open");
this.flush();
// we check for `readyState` in case an `open`
// listener already closed the socket
if ("open" === this.readyState && this.opts.upgrade) {
let i = 0;
const l = this.upgrades.length;
for (; i < l; i++) {
this.probe(this.upgrades[i]);
}
}
}
/**
* Handles a packet.
*
* @private
*/
onPacket(packet) {
if ("opening" === this.readyState ||
"open" === this.readyState ||
"closing" === this.readyState) {
this.emitReserved("packet", packet);
// Socket is live - any packet counts
this.emitReserved("heartbeat");
this.resetPingTimeout();
switch (packet.type) {
case "open":
this.onHandshake(JSON.parse(packet.data));
break;
case "ping":
this.sendPacket("pong");
this.emitReserved("ping");
this.emitReserved("pong");
break;
case "error":
const err = new Error("server error");
// @ts-ignore
err.code = packet.data;
this.onError(err);
break;
case "message":
this.emitReserved("data", packet.data);
this.emitReserved("message", packet.data);
break;
}
}
else {
}
}
/**
* Called upon handshake completion.
*
* @param {Object} data - handshake obj
* @private
*/
onHandshake(data) {
this.emitReserved("handshake", data);
this.id = data.sid;
this.transport.query.sid = data.sid;
this.upgrades = this.filterUpgrades(data.upgrades);
this.pingInterval = data.pingInterval;
this.pingTimeout = data.pingTimeout;
this.maxPayload = data.maxPayload;
this.onOpen();
// In case open handler closes socket
if ("closed" === this.readyState)
return;
this.resetPingTimeout();
}
/**
* Sets and resets ping timeout timer based on server pings.
*
* @private
*/
resetPingTimeout() {
this.clearTimeoutFn(this.pingTimeoutTimer);
this.pingTimeoutTimer = this.setTimeoutFn(() => {
this.onClose("ping timeout");
}, this.pingInterval + this.pingTimeout);
if (this.opts.autoUnref) {
this.pingTimeoutTimer.unref();
}
}
/**
* Called on `drain` event
*
* @private
*/
onDrain() {
this.writeBuffer.splice(0, this.prevBufferLen);
// setting prevBufferLen = 0 is very important
// for example, when upgrading, upgrade packet is sent over,
// and a nonzero prevBufferLen could cause problems on `drain`
this.prevBufferLen = 0;
if (0 === this.writeBuffer.length) {
this.emitReserved("drain");
}
else {
this.flush();
}
}
/**
* Flush write buffers.
*
* @private
*/
flush() {
if ("closed" !== this.readyState &&
this.transport.writable &&
!this.upgrading &&
this.writeBuffer.length) {
const packets = this.getWritablePackets();
this.transport.send(packets);
// keep track of current length of writeBuffer
// splice writeBuffer and callbackBuffer on `drain`
this.prevBufferLen = packets.length;
this.emitReserved("flush");
}
}
/**
* Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP
* long-polling)
*
* @private
*/
getWritablePackets() {
const shouldCheckPayloadSize = this.maxPayload &&
this.transport.name === "polling" &&
this.writeBuffer.length > 1;
if (!shouldCheckPayloadSize) {
return this.writeBuffer;
}
let payloadSize = 1; // first packet type
for (let i = 0; i < this.writeBuffer.length; i++) {
const data = this.writeBuffer[i].data;
if (data) {
payloadSize += byteLength(data);
}
if (i > 0 && payloadSize > this.maxPayload) {
return this.writeBuffer.slice(0, i);
}
payloadSize += 2; // separator + packet type
}
return this.writeBuffer;
}
/**
* Sends a message.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} callback function.
* @return {Socket} for chaining.
*/
write(msg, options, fn) {
this.sendPacket("message", msg, options, fn);
return this;
}
send(msg, options, fn) {
this.sendPacket("message", msg, options, fn);
return this;
}
/**
* Sends a packet.
*
* @param {String} type: packet type.
* @param {String} data.
* @param {Object} options.
* @param {Function} fn - callback function.
* @private
*/
sendPacket(type, data, options, fn) {
if ("function" === typeof data) {
fn = data;
data = undefined;
}
if ("function" === typeof options) {
fn = options;
options = null;
}
if ("closing" === this.readyState || "closed" === this.readyState) {
return;
}
options = options || {};
options.compress = false !== options.compress;
const packet = {
type: type,
data: data,
options: options,
};
this.emitReserved("packetCreate", packet);
this.writeBuffer.push(packet);
if (fn)
this.once("flush", fn);
this.flush();
}
/**
* Closes the connection.
*/
close() {
const close = () => {
this.onClose("forced close");
this.transport.close();
};
const cleanupAndClose = () => {
this.off("upgrade", cleanupAndClose);
this.off("upgradeError", cleanupAndClose);
close();
};
const waitForUpgrade = () => {
// wait for upgrade to finish since we can't send packets while pausing a transport
this.once("upgrade", cleanupAndClose);
this.once("upgradeError", cleanupAndClose);
};
if ("opening" === this.readyState || "open" === this.readyState) {
this.readyState = "closing";
if (this.writeBuffer.length) {
this.once("drain", () => {
if (this.upgrading) {
waitForUpgrade();
}
else {
close();
}
});
}
else if (this.upgrading) {
waitForUpgrade();
}
else {
close();
}
}
return this;
}
/**
* Called upon transport error
*
* @private
*/
onError(err) {
Socket.priorWebsocketSuccess = false;
this.emitReserved("error", err);
this.onClose("transport error", err);
}
/**
* Called upon transport close.
*
* @private
*/
onClose(reason, description) {
if ("opening" === this.readyState ||
"open" === this.readyState ||
"closing" === this.readyState) {
// clear timers
this.clearTimeoutFn(this.pingTimeoutTimer);
// stop event from firing again for transport
this.transport.removeAllListeners("close");
// ensure transport won't stay open
this.transport.close();
// ignore further transport communication
this.transport.removeAllListeners();
if (typeof removeEventListener === "function") {
removeEventListener("beforeunload", this.beforeunloadEventListener, false);
removeEventListener("offline", this.offlineEventListener, false);
}
// set ready state
this.readyState = "closed";
// clear session id
this.id = null;
// emit close event
this.emitReserved("close", reason, description);
// clean buffers after, so users can still
// grab the buffers on `close` event
this.writeBuffer = [];
this.prevBufferLen = 0;
}
}
/**
* Filters upgrades, returning only those matching client transports.
*
* @param {Array} upgrades - server upgrades
* @private
*/
filterUpgrades(upgrades) {
const filteredUpgrades = [];
let i = 0;
const j = upgrades.length;
for (; i < j; i++) {
if (~this.transports.indexOf(upgrades[i]))
filteredUpgrades.push(upgrades[i]);
}
return filteredUpgrades;
}
}
Socket.protocol = protocol;

106
node_modules/engine.io-client/build/esm/transport.d.ts generated vendored Normal file
View File

@@ -0,0 +1,106 @@
import type { Packet, RawData } from "engine.io-parser";
import { Emitter } from "@socket.io/component-emitter";
import { SocketOptions } from "./socket.js";
export declare class TransportError extends Error {
readonly description: any;
readonly context: any;
readonly type = "TransportError";
constructor(reason: string, description: any, context: any);
}
export interface CloseDetails {
description: string;
context?: unknown;
}
interface TransportReservedEvents {
open: () => void;
error: (err: TransportError) => void;
packet: (packet: Packet) => void;
close: (details?: CloseDetails) => void;
poll: () => void;
pollComplete: () => void;
drain: () => void;
}
type TransportState = "opening" | "open" | "closed" | "pausing" | "paused";
export declare abstract class Transport extends Emitter<Record<never, never>, Record<never, never>, TransportReservedEvents> {
query: Record<string, string>;
writable: boolean;
protected opts: SocketOptions;
protected supportsBinary: boolean;
protected readyState: TransportState;
protected socket: any;
protected setTimeoutFn: typeof setTimeout;
/**
* Transport abstract constructor.
*
* @param {Object} opts - options
* @protected
*/
constructor(opts: any);
/**
* Emits an error.
*
* @param {String} reason
* @param description
* @param context - the error context
* @return {Transport} for chaining
* @protected
*/
protected onError(reason: string, description: any, context?: any): this;
/**
* Opens the transport.
*/
open(): this;
/**
* Closes the transport.
*/
close(): this;
/**
* Sends multiple packets.
*
* @param {Array} packets
*/
send(packets: any): void;
/**
* Called upon open
*
* @protected
*/
protected onOpen(): void;
/**
* Called with data.
*
* @param {String} data
* @protected
*/
protected onData(data: RawData): void;
/**
* Called with a decoded packet.
*
* @protected
*/
protected onPacket(packet: Packet): void;
/**
* Called upon close.
*
* @protected
*/
protected onClose(details?: CloseDetails): void;
/**
* The name of the transport
*/
abstract get name(): string;
/**
* Pauses the transport, in order not to lose packets during an upgrade.
*
* @param onPause
*/
pause(onPause: () => void): void;
protected createUri(schema: string, query?: Record<string, unknown>): string;
private _hostname;
private _port;
private _query;
protected abstract doOpen(): any;
protected abstract doClose(): any;
protected abstract write(packets: Packet[]): any;
}
export {};

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