1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-03 17:59:55 +02:00

Getting ready for WebRTC

This commit is contained in:
Daniel Neto 2025-01-10 18:25:30 -03:00
parent 018f5d1f12
commit 132249f01a
310 changed files with 37290 additions and 661 deletions

View file

@ -2111,7 +2111,6 @@ $t['Watch now'] = '';
$t['Watching Time'] = 'Tempo de exibição'; $t['Watching Time'] = 'Tempo de exibição';
$t['We could not add you on the plan, we also refund you the payment'] = ''; $t['We could not add you on the plan, we also refund you the payment'] = '';
$t['We go live in...'] = ''; $t['We go live in...'] = '';
$t['WebRTC Player'] = '';
$t['Wednsday'] = ''; $t['Wednsday'] = '';
$t['When the video is saved like this, it will show up under the menu-point'] = 'Quando o vídeo for salvo assim, ele aparecerá sob o ponto de menu'; $t['When the video is saved like this, it will show up under the menu-point'] = 'Quando o vídeo for salvo assim, ele aparecerá sob o ponto de menu';
$t['Will start in'] = ''; $t['Will start in'] = '';

View file

@ -1607,7 +1607,6 @@ $t['Watch now'] = 'Assista agora';
$t['Watching Time'] = 'Tempo de exibição'; $t['Watching Time'] = 'Tempo de exibição';
$t['We could not add you on the plan, we also refund you the payment'] = 'Não conseguimos adicionar você ao plano, também reembolsamos o pagamento'; $t['We could not add you on the plan, we also refund you the payment'] = 'Não conseguimos adicionar você ao plano, também reembolsamos o pagamento';
$t['We go live in...'] = 'Entraremos ao vivo em...'; $t['We go live in...'] = 'Entraremos ao vivo em...';
$t['WebRTC Player'] = 'Player WebRTC';
$t['Wednsday'] = 'Quarta-feira'; $t['Wednsday'] = 'Quarta-feira';
$t['When the video is saved like this, it will show up under the menu-point'] = 'Quando o vídeo for salvo assim, ele aparecerá sob o ponto de menu'; $t['When the video is saved like this, it will show up under the menu-point'] = 'Quando o vídeo for salvo assim, ele aparecerá sob o ponto de menu';
$t['Will start in'] = 'Começará em'; $t['Will start in'] = 'Começará em';

100
node_modules/.package-lock.json generated vendored
View file

@ -251,6 +251,11 @@
"video.js": ">= 6 < 9" "video.js": ">= 6 < 9"
} }
}, },
"node_modules/@socket.io/component-emitter": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="
},
"node_modules/@videojs/http-streaming": { "node_modules/@videojs/http-streaming": {
"version": "3.16.2", "version": "3.16.2",
"resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.16.2.tgz", "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.16.2.tgz",
@ -483,6 +488,22 @@
"resolved": "https://registry.npmjs.org/croppie/-/croppie-2.6.5.tgz", "resolved": "https://registry.npmjs.org/croppie/-/croppie-2.6.5.tgz",
"integrity": "sha512-IlChnVUGG5T3w2gRZIaQgBtlvyuYnlUWs2YZIXXR3H9KrlO1PtBT3j+ykxvy9eZIWhk+V5SpBmhCQz5UXKrEKQ==" "integrity": "sha512-IlChnVUGG5T3w2gRZIaQgBtlvyuYnlUWs2YZIXXR3H9KrlO1PtBT3j+ykxvy9eZIWhk+V5SpBmhCQz5UXKrEKQ=="
}, },
"node_modules/debug": {
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/deferred-leveldown": { "node_modules/deferred-leveldown": {
"version": "5.3.0", "version": "5.3.0",
"resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz",
@ -532,6 +553,26 @@
"write-stream": "~0.4.3" "write-stream": "~0.4.3"
} }
}, },
"node_modules/engine.io-client": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.2.tgz",
"integrity": "sha512-TAr+NKeoVTjEVW8P3iHguO1LO6RlUz9O5Y8o7EY0fU+gY1NYqas7NN3slpFtbXEsLMHk0h90fJMfKjRkQ0qUIw==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1",
"engine.io-parser": "~5.2.1",
"ws": "~8.17.1",
"xmlhttprequest-ssl": "~2.1.1"
}
},
"node_modules/engine.io-parser": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/errno": { "node_modules/errno": {
"version": "0.1.8", "version": "0.1.8",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
@ -1072,6 +1113,11 @@
"mpd-to-m3u8-json": "bin/parse.js" "mpd-to-m3u8-json": "bin/parse.js"
} }
}, },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/mux.js": { "node_modules/mux.js": {
"version": "7.1.0", "version": "7.1.0",
"resolved": "https://registry.npmjs.org/mux.js/-/mux.js-7.1.0.tgz", "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-7.1.0.tgz",
@ -1292,6 +1338,32 @@
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz",
"integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==" "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ=="
}, },
"node_modules/socket.io-client": {
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz",
"integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2",
"engine.io-client": "~6.6.1",
"socket.io-parser": "~4.2.4"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-parser": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/spark-md5": { "node_modules/spark-md5": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz", "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz",
@ -1934,6 +2006,34 @@
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-0.0.4.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-0.0.4.tgz",
"integrity": "sha512-azrivNydKRYt7zwLV5wWUK7YzKTWs3q87xSmY6DlHapPrCvaT6ZrukvM5erV+yCSSPmZT8zkSdttOHQpWWm9zw==" "integrity": "sha512-azrivNydKRYt7zwLV5wWUK7YzKTWs3q87xSmY6DlHapPrCvaT6ZrukvM5erV+yCSSPmZT8zkSdttOHQpWWm9zw=="
}, },
"node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/xmlhttprequest-ssl": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz",
"integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/xtend": { "node_modules/xtend": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",

24
node_modules/@socket.io/component-emitter/LICENSE generated vendored Normal file
View file

@ -0,0 +1,24 @@
(The MIT License)
Copyright (c) 2014 Component contributors <dev@component.io>
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.

79
node_modules/@socket.io/component-emitter/Readme.md generated vendored Normal file
View file

@ -0,0 +1,79 @@
# `@socket.io/component-emitter`
Event emitter component.
This project is a fork of the [`component-emitter`](https://github.com/sindresorhus/component-emitter) project, with [Socket.IO](https://socket.io/)-specific TypeScript typings.
## Installation
```
$ npm i @socket.io/component-emitter
```
## API
### Emitter(obj)
The `Emitter` may also be used as a mixin. For example
a "plain" object may become an emitter, or you may
extend an existing prototype.
As an `Emitter` instance:
```js
import { Emitter } from '@socket.io/component-emitter';
var emitter = new Emitter;
emitter.emit('something');
```
As a mixin:
```js
import { Emitter } from '@socket.io/component-emitter';
var user = { name: 'tobi' };
Emitter(user);
user.emit('im a user');
```
As a prototype mixin:
```js
import { Emitter } from '@socket.io/component-emitter';
Emitter(User.prototype);
```
### Emitter#on(event, fn)
Register an `event` handler `fn`.
### Emitter#once(event, fn)
Register a single-shot `event` handler `fn`,
removed immediately after it is invoked the
first time.
### Emitter#off(event, fn)
* Pass `event` and `fn` to remove a listener.
* Pass `event` to remove all listeners on that event.
* Pass nothing to remove all listeners on all events.
### Emitter#emit(event, ...)
Emit an `event` with variable option args.
### Emitter#listeners(event)
Return an array of callbacks, or an empty array.
### Emitter#hasListeners(event)
Check if this emitter has `event` handlers.
## License
MIT

View file

@ -0,0 +1,179 @@
/**
* An events map is an interface that maps event names to their value, which
* represents the type of the `on` listener.
*/
export interface EventsMap {
[event: string]: any;
}
/**
* The default events map, used if no EventsMap is given. Using this EventsMap
* is equivalent to accepting all event names, and any data.
*/
export interface DefaultEventsMap {
[event: string]: (...args: any[]) => void;
}
/**
* Returns a union type containing all the keys of an event map.
*/
export type EventNames<Map extends EventsMap> = keyof Map & (string | symbol);
/** The tuple type representing the parameters of an event listener */
export type EventParams<
Map extends EventsMap,
Ev extends EventNames<Map>
> = Parameters<Map[Ev]>;
/**
* The event names that are either in ReservedEvents or in UserEvents
*/
export type ReservedOrUserEventNames<
ReservedEventsMap extends EventsMap,
UserEvents extends EventsMap
> = EventNames<ReservedEventsMap> | EventNames<UserEvents>;
/**
* Type of a listener of a user event or a reserved event. If `Ev` is in
* `ReservedEvents`, the reserved event listener is returned.
*/
export type ReservedOrUserListener<
ReservedEvents extends EventsMap,
UserEvents extends EventsMap,
Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents>
> = FallbackToUntypedListener<
Ev extends EventNames<ReservedEvents>
? ReservedEvents[Ev]
: Ev extends EventNames<UserEvents>
? UserEvents[Ev]
: never
>;
/**
* Returns an untyped listener type if `T` is `never`; otherwise, returns `T`.
*
* This is a hack to mitigate https://github.com/socketio/socket.io/issues/3833.
* Needed because of https://github.com/microsoft/TypeScript/issues/41778
*/
type FallbackToUntypedListener<T> = [T] extends [never]
? (...args: any[]) => void | Promise<void>
: T;
/**
* Strictly typed version of an `EventEmitter`. A `TypedEventEmitter` takes type
* parameters for mappings of event names to event data types, and strictly
* types method calls to the `EventEmitter` according to these event maps.
*
* @typeParam ListenEvents - `EventsMap` of user-defined events that can be
* listened to with `on` or `once`
* @typeParam EmitEvents - `EventsMap` of user-defined events that can be
* emitted with `emit`
* @typeParam ReservedEvents - `EventsMap` of reserved events, that can be
* emitted by socket.io with `emitReserved`, and can be listened to with
* `listen`.
*/
export class Emitter<
ListenEvents extends EventsMap,
EmitEvents extends EventsMap,
ReservedEvents extends EventsMap = {}
> {
/**
* Adds the `listener` function as an event listener for `ev`.
*
* @param ev Name of the event
* @param listener Callback function
*/
on<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
ev: Ev,
listener: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
): this;
/**
* Adds a one-time `listener` function as an event listener for `ev`.
*
* @param ev Name of the event
* @param listener Callback function
*/
once<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
ev: Ev,
listener: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
): this;
/**
* Removes the `listener` function as an event listener for `ev`.
*
* @param ev Name of the event
* @param listener Callback function
*/
off<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
ev?: Ev,
listener?: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
): this;
/**
* Emits an event.
*
* @param ev Name of the event
* @param args Values to send to listeners of this event
*/
emit<Ev extends EventNames<EmitEvents>>(
ev: Ev,
...args: EventParams<EmitEvents, Ev>
): this;
/**
* Emits a reserved event.
*
* This method is `protected`, so that only a class extending
* `StrictEventEmitter` can emit its own reserved events.
*
* @param ev Reserved event name
* @param args Arguments to emit along with the event
*/
protected emitReserved<Ev extends EventNames<ReservedEvents>>(
ev: Ev,
...args: EventParams<ReservedEvents, Ev>
): this;
/**
* Returns the listeners listening to an event.
*
* @param event Event name
* @returns Array of listeners subscribed to `event`
*/
listeners<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
event: Ev
): ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>[];
/**
* Returns true if there is a listener for this event.
*
* @param event Event name
* @returns boolean
*/
hasListeners<
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>
>(event: Ev): boolean;
/**
* Removes the `listener` function as an event listener for `ev`.
*
* @param ev Name of the event
* @param listener Callback function
*/
removeListener<
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>
>(
ev?: Ev,
listener?: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
): this;
/**
* Removes all `listener` function as an event listener for `ev`.
*
* @param ev Name of the event
*/
removeAllListeners<
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>
>(ev?: Ev): this;
}

View file

@ -0,0 +1,176 @@
/**
* Expose `Emitter`.
*/
exports.Emitter = Emitter;
/**
* Initialize a new `Emitter`.
*
* @api public
*/
function Emitter(obj) {
if (obj) return mixin(obj);
}
/**
* Mixin the emitter properties.
*
* @param {Object} obj
* @return {Object}
* @api private
*/
function mixin(obj) {
for (var key in Emitter.prototype) {
obj[key] = Emitter.prototype[key];
}
return obj;
}
/**
* Listen on the given `event` with `fn`.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.on =
Emitter.prototype.addEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
(this._callbacks['$' + event] = this._callbacks['$' + event] || [])
.push(fn);
return this;
};
/**
* Adds an `event` listener that will be invoked a single
* time then automatically removed.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.once = function(event, fn){
function on() {
this.off(event, on);
fn.apply(this, arguments);
}
on.fn = fn;
this.on(event, on);
return this;
};
/**
* Remove the given callback for `event` or all
* registered callbacks.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.off =
Emitter.prototype.removeListener =
Emitter.prototype.removeAllListeners =
Emitter.prototype.removeEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
// all
if (0 == arguments.length) {
this._callbacks = {};
return this;
}
// specific event
var callbacks = this._callbacks['$' + event];
if (!callbacks) return this;
// remove all handlers
if (1 == arguments.length) {
delete this._callbacks['$' + event];
return this;
}
// remove specific handler
var cb;
for (var i = 0; i < callbacks.length; i++) {
cb = callbacks[i];
if (cb === fn || cb.fn === fn) {
callbacks.splice(i, 1);
break;
}
}
// Remove event specific arrays for event types that no
// one is subscribed for to avoid memory leak.
if (callbacks.length === 0) {
delete this._callbacks['$' + event];
}
return this;
};
/**
* Emit `event` with the given args.
*
* @param {String} event
* @param {Mixed} ...
* @return {Emitter}
*/
Emitter.prototype.emit = function(event){
this._callbacks = this._callbacks || {};
var args = new Array(arguments.length - 1)
, callbacks = this._callbacks['$' + event];
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
if (callbacks) {
callbacks = callbacks.slice(0);
for (var i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
return this;
};
// alias used for reserved events (protected method)
Emitter.prototype.emitReserved = Emitter.prototype.emit;
/**
* Return array of callbacks for `event`.
*
* @param {String} event
* @return {Array}
* @api public
*/
Emitter.prototype.listeners = function(event){
this._callbacks = this._callbacks || {};
return this._callbacks['$' + event] || [];
};
/**
* Check if this emitter has `event` handlers.
*
* @param {String} event
* @return {Boolean}
* @api public
*/
Emitter.prototype.hasListeners = function(event){
return !! this.listeners(event).length;
};

View file

@ -0,0 +1,4 @@
{
"name": "@socket.io/component-emitter",
"type": "commonjs"
}

View file

@ -0,0 +1,179 @@
/**
* An events map is an interface that maps event names to their value, which
* represents the type of the `on` listener.
*/
export interface EventsMap {
[event: string]: any;
}
/**
* The default events map, used if no EventsMap is given. Using this EventsMap
* is equivalent to accepting all event names, and any data.
*/
export interface DefaultEventsMap {
[event: string]: (...args: any[]) => void;
}
/**
* Returns a union type containing all the keys of an event map.
*/
export type EventNames<Map extends EventsMap> = keyof Map & (string | symbol);
/** The tuple type representing the parameters of an event listener */
export type EventParams<
Map extends EventsMap,
Ev extends EventNames<Map>
> = Parameters<Map[Ev]>;
/**
* The event names that are either in ReservedEvents or in UserEvents
*/
export type ReservedOrUserEventNames<
ReservedEventsMap extends EventsMap,
UserEvents extends EventsMap
> = EventNames<ReservedEventsMap> | EventNames<UserEvents>;
/**
* Type of a listener of a user event or a reserved event. If `Ev` is in
* `ReservedEvents`, the reserved event listener is returned.
*/
export type ReservedOrUserListener<
ReservedEvents extends EventsMap,
UserEvents extends EventsMap,
Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents>
> = FallbackToUntypedListener<
Ev extends EventNames<ReservedEvents>
? ReservedEvents[Ev]
: Ev extends EventNames<UserEvents>
? UserEvents[Ev]
: never
>;
/**
* Returns an untyped listener type if `T` is `never`; otherwise, returns `T`.
*
* This is a hack to mitigate https://github.com/socketio/socket.io/issues/3833.
* Needed because of https://github.com/microsoft/TypeScript/issues/41778
*/
type FallbackToUntypedListener<T> = [T] extends [never]
? (...args: any[]) => void | Promise<void>
: T;
/**
* Strictly typed version of an `EventEmitter`. A `TypedEventEmitter` takes type
* parameters for mappings of event names to event data types, and strictly
* types method calls to the `EventEmitter` according to these event maps.
*
* @typeParam ListenEvents - `EventsMap` of user-defined events that can be
* listened to with `on` or `once`
* @typeParam EmitEvents - `EventsMap` of user-defined events that can be
* emitted with `emit`
* @typeParam ReservedEvents - `EventsMap` of reserved events, that can be
* emitted by socket.io with `emitReserved`, and can be listened to with
* `listen`.
*/
export class Emitter<
ListenEvents extends EventsMap,
EmitEvents extends EventsMap,
ReservedEvents extends EventsMap = {}
> {
/**
* Adds the `listener` function as an event listener for `ev`.
*
* @param ev Name of the event
* @param listener Callback function
*/
on<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
ev: Ev,
listener: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
): this;
/**
* Adds a one-time `listener` function as an event listener for `ev`.
*
* @param ev Name of the event
* @param listener Callback function
*/
once<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
ev: Ev,
listener: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
): this;
/**
* Removes the `listener` function as an event listener for `ev`.
*
* @param ev Name of the event
* @param listener Callback function
*/
off<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
ev?: Ev,
listener?: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
): this;
/**
* Emits an event.
*
* @param ev Name of the event
* @param args Values to send to listeners of this event
*/
emit<Ev extends EventNames<EmitEvents>>(
ev: Ev,
...args: EventParams<EmitEvents, Ev>
): this;
/**
* Emits a reserved event.
*
* This method is `protected`, so that only a class extending
* `StrictEventEmitter` can emit its own reserved events.
*
* @param ev Reserved event name
* @param args Arguments to emit along with the event
*/
protected emitReserved<Ev extends EventNames<ReservedEvents>>(
ev: Ev,
...args: EventParams<ReservedEvents, Ev>
): this;
/**
* Returns the listeners listening to an event.
*
* @param event Event name
* @returns Array of listeners subscribed to `event`
*/
listeners<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
event: Ev
): ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>[];
/**
* Returns true if there is a listener for this event.
*
* @param event Event name
* @returns boolean
*/
hasListeners<
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>
>(event: Ev): boolean;
/**
* Removes the `listener` function as an event listener for `ev`.
*
* @param ev Name of the event
* @param listener Callback function
*/
removeListener<
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>
>(
ev?: Ev,
listener?: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
): this;
/**
* Removes all `listener` function as an event listener for `ev`.
*
* @param ev Name of the event
*/
removeAllListeners<
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>
>(ev?: Ev): this;
}

View file

@ -0,0 +1,169 @@
/**
* Initialize a new `Emitter`.
*
* @api public
*/
export function Emitter(obj) {
if (obj) return mixin(obj);
}
/**
* Mixin the emitter properties.
*
* @param {Object} obj
* @return {Object}
* @api private
*/
function mixin(obj) {
for (var key in Emitter.prototype) {
obj[key] = Emitter.prototype[key];
}
return obj;
}
/**
* Listen on the given `event` with `fn`.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.on =
Emitter.prototype.addEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
(this._callbacks['$' + event] = this._callbacks['$' + event] || [])
.push(fn);
return this;
};
/**
* Adds an `event` listener that will be invoked a single
* time then automatically removed.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.once = function(event, fn){
function on() {
this.off(event, on);
fn.apply(this, arguments);
}
on.fn = fn;
this.on(event, on);
return this;
};
/**
* Remove the given callback for `event` or all
* registered callbacks.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.off =
Emitter.prototype.removeListener =
Emitter.prototype.removeAllListeners =
Emitter.prototype.removeEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
// all
if (0 == arguments.length) {
this._callbacks = {};
return this;
}
// specific event
var callbacks = this._callbacks['$' + event];
if (!callbacks) return this;
// remove all handlers
if (1 == arguments.length) {
delete this._callbacks['$' + event];
return this;
}
// remove specific handler
var cb;
for (var i = 0; i < callbacks.length; i++) {
cb = callbacks[i];
if (cb === fn || cb.fn === fn) {
callbacks.splice(i, 1);
break;
}
}
// Remove event specific arrays for event types that no
// one is subscribed for to avoid memory leak.
if (callbacks.length === 0) {
delete this._callbacks['$' + event];
}
return this;
};
/**
* Emit `event` with the given args.
*
* @param {String} event
* @param {Mixed} ...
* @return {Emitter}
*/
Emitter.prototype.emit = function(event){
this._callbacks = this._callbacks || {};
var args = new Array(arguments.length - 1)
, callbacks = this._callbacks['$' + event];
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
if (callbacks) {
callbacks = callbacks.slice(0);
for (var i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
return this;
};
// alias used for reserved events (protected method)
Emitter.prototype.emitReserved = Emitter.prototype.emit;
/**
* Return array of callbacks for `event`.
*
* @param {String} event
* @return {Array}
* @api public
*/
Emitter.prototype.listeners = function(event){
this._callbacks = this._callbacks || {};
return this._callbacks['$' + event] || [];
};
/**
* Check if this emitter has `event` handlers.
*
* @param {String} event
* @return {Boolean}
* @api public
*/
Emitter.prototype.hasListeners = function(event){
return !! this.listeners(event).length;
};

View file

@ -0,0 +1,4 @@
{
"name": "@socket.io/component-emitter",
"type": "module"
}

28
node_modules/@socket.io/component-emitter/package.json generated vendored Normal file
View file

@ -0,0 +1,28 @@
{
"name": "@socket.io/component-emitter",
"description": "Event emitter",
"version": "3.1.2",
"license": "MIT",
"devDependencies": {
"mocha": "*",
"should": "*"
},
"component": {
"scripts": {
"emitter/index.js": "index.js"
}
},
"main": "./lib/cjs/index.js",
"module": "./lib/esm/index.js",
"types": "./lib/cjs/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/socketio/emitter.git"
},
"scripts": {
"test": "make test"
},
"files": [
"lib/"
]
}

20
node_modules/debug/LICENSE generated vendored Normal file
View file

@ -0,0 +1,20 @@
(The MIT License)
Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca>
Copyright (c) 2018-2021 Josh Junon
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.

481
node_modules/debug/README.md generated vendored Normal file
View file

@ -0,0 +1,481 @@
# debug
[![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers)
[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors)
<img width="647" src="https://user-images.githubusercontent.com/71256/29091486-fa38524c-7c37-11e7-895f-e7ec8e1039b6.png">
A tiny JavaScript debugging utility modelled after Node.js core's debugging
technique. Works in Node.js and web browsers.
## Installation
```bash
$ npm install debug
```
## Usage
`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.
Example [_app.js_](./examples/node/app.js):
```js
var debug = require('debug')('http')
, http = require('http')
, name = 'My App';
// fake app
debug('booting %o', name);
http.createServer(function(req, res){
debug(req.method + ' ' + req.url);
res.end('hello\n');
}).listen(3000, function(){
debug('listening');
});
// fake worker of some kind
require('./worker');
```
Example [_worker.js_](./examples/node/worker.js):
```js
var a = require('debug')('worker:a')
, b = require('debug')('worker:b');
function work() {
a('doing lots of uninteresting work');
setTimeout(work, Math.random() * 1000);
}
work();
function workb() {
b('doing some work');
setTimeout(workb, Math.random() * 2000);
}
workb();
```
The `DEBUG` environment variable is then used to enable these based on space or
comma-delimited names.
Here are some examples:
<img width="647" alt="screen shot 2017-08-08 at 12 53 04 pm" src="https://user-images.githubusercontent.com/71256/29091703-a6302cdc-7c38-11e7-8304-7c0b3bc600cd.png">
<img width="647" alt="screen shot 2017-08-08 at 12 53 38 pm" src="https://user-images.githubusercontent.com/71256/29091700-a62a6888-7c38-11e7-800b-db911291ca2b.png">
<img width="647" alt="screen shot 2017-08-08 at 12 53 25 pm" src="https://user-images.githubusercontent.com/71256/29091701-a62ea114-7c38-11e7-826a-2692bedca740.png">
#### Windows command prompt notes
##### CMD
On Windows the environment variable is set using the `set` command.
```cmd
set DEBUG=*,-not_this
```
Example:
```cmd
set DEBUG=* & node app.js
```
##### PowerShell (VS Code default)
PowerShell uses different syntax to set environment variables.
```cmd
$env:DEBUG = "*,-not_this"
```
Example:
```cmd
$env:DEBUG='app';node app.js
```
Then, run the program to be debugged as usual.
npm script example:
```js
"windowsDebug": "@powershell -Command $env:DEBUG='*';node app.js",
```
## Namespace Colors
Every debug instance has a color generated for it based on its namespace name.
This helps when visually parsing the debug output to identify which debug instance
a debug line belongs to.
#### Node.js
In Node.js, colors are enabled when stderr is a TTY. You also _should_ install
the [`supports-color`](https://npmjs.org/supports-color) module alongside debug,
otherwise debug will only use a small handful of basic colors.
<img width="521" src="https://user-images.githubusercontent.com/71256/29092181-47f6a9e6-7c3a-11e7-9a14-1928d8a711cd.png">
#### Web Browser
Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
option. These are WebKit web inspectors, Firefox ([since version
31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))
and the Firebug plugin for Firefox (any version).
<img width="524" src="https://user-images.githubusercontent.com/71256/29092033-b65f9f2e-7c39-11e7-8e32-f6f0d8e865c1.png">
## Millisecond diff
When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
<img width="647" src="https://user-images.githubusercontent.com/71256/29091486-fa38524c-7c37-11e7-895f-e7ec8e1039b6.png">
When stdout is not a TTY, `Date#toISOString()` is used, making it more useful for logging the debug information as shown below:
<img width="647" src="https://user-images.githubusercontent.com/71256/29091956-6bd78372-7c39-11e7-8c55-c948396d6edd.png">
## Conventions
If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". If you append a "*" to the end of your name, it will always be enabled regardless of the setting of the DEBUG environment variable. You can then use it for normal output as well as debug output.
## Wildcards
The `*` character may be used as a wildcard. Suppose for example your library has
debuggers named "connect:bodyParser", "connect:compress", "connect:session",
instead of listing all three with
`DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do
`DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
You can also exclude specific debuggers by prefixing them with a "-" character.
For example, `DEBUG=*,-connect:*` would include all debuggers except those
starting with "connect:".
## Environment Variables
When running through Node.js, you can set a few environment variables that will
change the behavior of the debug logging:
| Name | Purpose |
|-----------|-------------------------------------------------|
| `DEBUG` | Enables/disables specific debugging namespaces. |
| `DEBUG_HIDE_DATE` | Hide date from debug output (non-TTY). |
| `DEBUG_COLORS`| Whether or not to use colors in the debug output. |
| `DEBUG_DEPTH` | Object inspection depth. |
| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
__Note:__ The environment variables beginning with `DEBUG_` end up being
converted into an Options object that gets used with `%o`/`%O` formatters.
See the Node.js documentation for
[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options)
for the complete list.
## Formatters
Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting.
Below are the officially supported formatters:
| Formatter | Representation |
|-----------|----------------|
| `%O` | Pretty-print an Object on multiple lines. |
| `%o` | Pretty-print an Object all on a single line. |
| `%s` | String. |
| `%d` | Number (both integer and float). |
| `%j` | JSON. Replaced with the string '[Circular]' if the argument contains circular references. |
| `%%` | Single percent sign ('%'). This does not consume an argument. |
### Custom formatters
You can add custom formatters by extending the `debug.formatters` object.
For example, if you wanted to add support for rendering a Buffer as hex with
`%h`, you could do something like:
```js
const createDebug = require('debug')
createDebug.formatters.h = (v) => {
return v.toString('hex')
}
// …elsewhere
const debug = createDebug('foo')
debug('this is hex: %h', new Buffer('hello world'))
// foo this is hex: 68656c6c6f20776f726c6421 +0ms
```
## Browser Support
You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify),
or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest),
if you don't want to build it yourself.
Debug's enable state is currently persisted by `localStorage`.
Consider the situation shown below where you have `worker:a` and `worker:b`,
and wish to debug both. You can enable this using `localStorage.debug`:
```js
localStorage.debug = 'worker:*'
```
And then refresh the page.
```js
a = debug('worker:a');
b = debug('worker:b');
setInterval(function(){
a('doing some work');
}, 1000);
setInterval(function(){
b('doing some work');
}, 1200);
```
In Chromium-based web browsers (e.g. Brave, Chrome, and Electron), the JavaScript console will—by default—only show messages logged by `debug` if the "Verbose" log level is _enabled_.
<img width="647" src="https://user-images.githubusercontent.com/7143133/152083257-29034707-c42c-4959-8add-3cee850e6fcf.png">
## Output streams
By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method:
Example [_stdout.js_](./examples/node/stdout.js):
```js
var debug = require('debug');
var error = debug('app:error');
// by default stderr is used
error('goes to stderr!');
var log = debug('app:log');
// set this namespace to log via console.log
log.log = console.log.bind(console); // don't forget to bind to console!
log('goes to stdout');
error('still goes to stderr!');
// set all output to go via console.info
// overrides all per-namespace log settings
debug.log = console.info.bind(console);
error('now goes to stdout via console.info');
log('still goes to stdout, but via console.info now');
```
## Extend
You can simply extend debugger
```js
const log = require('debug')('auth');
//creates new debug instance with extended namespace
const logSign = log.extend('sign');
const logLogin = log.extend('login');
log('hello'); // auth hello
logSign('hello'); //auth:sign hello
logLogin('hello'); //auth:login hello
```
## Set dynamically
You can also enable debug dynamically by calling the `enable()` method :
```js
let debug = require('debug');
console.log(1, debug.enabled('test'));
debug.enable('test');
console.log(2, debug.enabled('test'));
debug.disable();
console.log(3, debug.enabled('test'));
```
print :
```
1 false
2 true
3 false
```
Usage :
`enable(namespaces)`
`namespaces` can include modes separated by a colon and wildcards.
Note that calling `enable()` completely overrides previously set DEBUG variable :
```
$ DEBUG=foo node -e 'var dbg = require("debug"); dbg.enable("bar"); console.log(dbg.enabled("foo"))'
=> false
```
`disable()`
Will disable all namespaces. The functions returns the namespaces currently
enabled (and skipped). This can be useful if you want to disable debugging
temporarily without knowing what was enabled to begin with.
For example:
```js
let debug = require('debug');
debug.enable('foo:*,-foo:bar');
let namespaces = debug.disable();
debug.enable(namespaces);
```
Note: There is no guarantee that the string will be identical to the initial
enable string, but semantically they will be identical.
## Checking whether a debug target is enabled
After you've created a debug instance, you can determine whether or not it is
enabled by checking the `enabled` property:
```javascript
const debug = require('debug')('http');
if (debug.enabled) {
// do stuff...
}
```
You can also manually toggle this property to force the debug instance to be
enabled or disabled.
## Usage in child processes
Due to the way `debug` detects if the output is a TTY or not, colors are not shown in child processes when `stderr` is piped. A solution is to pass the `DEBUG_COLORS=1` environment variable to the child process.
For example:
```javascript
worker = fork(WORKER_WRAP_PATH, [workerPath], {
stdio: [
/* stdin: */ 0,
/* stdout: */ 'pipe',
/* stderr: */ 'pipe',
'ipc',
],
env: Object.assign({}, process.env, {
DEBUG_COLORS: 1 // without this settings, colors won't be shown
}),
});
worker.stderr.pipe(process.stderr, { end: false });
```
## Authors
- TJ Holowaychuk
- Nathan Rajlich
- Andrew Rhyne
- Josh Junon
## Backers
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)]
<a href="https://opencollective.com/debug/backer/0/website" target="_blank"><img src="https://opencollective.com/debug/backer/0/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/1/website" target="_blank"><img src="https://opencollective.com/debug/backer/1/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/2/website" target="_blank"><img src="https://opencollective.com/debug/backer/2/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/3/website" target="_blank"><img src="https://opencollective.com/debug/backer/3/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/4/website" target="_blank"><img src="https://opencollective.com/debug/backer/4/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/5/website" target="_blank"><img src="https://opencollective.com/debug/backer/5/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/6/website" target="_blank"><img src="https://opencollective.com/debug/backer/6/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/7/website" target="_blank"><img src="https://opencollective.com/debug/backer/7/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/8/website" target="_blank"><img src="https://opencollective.com/debug/backer/8/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/9/website" target="_blank"><img src="https://opencollective.com/debug/backer/9/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/10/website" target="_blank"><img src="https://opencollective.com/debug/backer/10/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/11/website" target="_blank"><img src="https://opencollective.com/debug/backer/11/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/12/website" target="_blank"><img src="https://opencollective.com/debug/backer/12/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/13/website" target="_blank"><img src="https://opencollective.com/debug/backer/13/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/14/website" target="_blank"><img src="https://opencollective.com/debug/backer/14/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/15/website" target="_blank"><img src="https://opencollective.com/debug/backer/15/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/16/website" target="_blank"><img src="https://opencollective.com/debug/backer/16/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/17/website" target="_blank"><img src="https://opencollective.com/debug/backer/17/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/18/website" target="_blank"><img src="https://opencollective.com/debug/backer/18/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/19/website" target="_blank"><img src="https://opencollective.com/debug/backer/19/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/20/website" target="_blank"><img src="https://opencollective.com/debug/backer/20/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/21/website" target="_blank"><img src="https://opencollective.com/debug/backer/21/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/22/website" target="_blank"><img src="https://opencollective.com/debug/backer/22/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/23/website" target="_blank"><img src="https://opencollective.com/debug/backer/23/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/24/website" target="_blank"><img src="https://opencollective.com/debug/backer/24/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/25/website" target="_blank"><img src="https://opencollective.com/debug/backer/25/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/26/website" target="_blank"><img src="https://opencollective.com/debug/backer/26/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/27/website" target="_blank"><img src="https://opencollective.com/debug/backer/27/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/28/website" target="_blank"><img src="https://opencollective.com/debug/backer/28/avatar.svg"></a>
<a href="https://opencollective.com/debug/backer/29/website" target="_blank"><img src="https://opencollective.com/debug/backer/29/avatar.svg"></a>
## Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)]
<a href="https://opencollective.com/debug/sponsor/0/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/1/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/2/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/3/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/4/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/5/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/6/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/7/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/8/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/9/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/9/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/10/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/10/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/11/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/11/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/12/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/12/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/13/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/13/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/14/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/14/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/15/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/15/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/16/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/16/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/17/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/17/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/18/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/18/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/19/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/19/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/20/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/20/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/21/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/21/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/22/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/22/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/23/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/23/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/24/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/24/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/25/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/25/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/26/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/26/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/27/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/27/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/28/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/28/avatar.svg"></a>
<a href="https://opencollective.com/debug/sponsor/29/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/29/avatar.svg"></a>
## License
(The MIT License)
Copyright (c) 2014-2017 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
Copyright (c) 2018-2021 Josh Junon
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.

60
node_modules/debug/package.json generated vendored Normal file
View file

@ -0,0 +1,60 @@
{
"name": "debug",
"version": "4.3.7",
"repository": {
"type": "git",
"url": "git://github.com/debug-js/debug.git"
},
"description": "Lightweight debugging utility for Node.js and the browser",
"keywords": [
"debug",
"log",
"debugger"
],
"files": [
"src",
"LICENSE",
"README.md"
],
"author": "Josh Junon (https://github.com/qix-)",
"contributors": [
"TJ Holowaychuk <tj@vision-media.ca>",
"Nathan Rajlich <nathan@tootallnate.net> (http://n8.io)",
"Andrew Rhyne <rhyneandrew@gmail.com>"
],
"license": "MIT",
"scripts": {
"lint": "xo",
"test": "npm run test:node && npm run test:browser && npm run lint",
"test:node": "istanbul cover _mocha -- test.js test.node.js",
"test:browser": "karma start --single-run",
"test:coverage": "cat ./coverage/lcov.info | coveralls"
},
"dependencies": {
"ms": "^2.1.3"
},
"devDependencies": {
"brfs": "^2.0.1",
"browserify": "^16.2.3",
"coveralls": "^3.0.2",
"istanbul": "^0.4.5",
"karma": "^3.1.4",
"karma-browserify": "^6.0.0",
"karma-chrome-launcher": "^2.2.0",
"karma-mocha": "^1.3.0",
"mocha": "^5.2.0",
"mocha-lcov-reporter": "^1.2.0",
"sinon": "^14.0.0",
"xo": "^0.23.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
},
"main": "./src/index.js",
"browser": "./src/browser.js",
"engines": {
"node": ">=6.0"
}
}

271
node_modules/debug/src/browser.js generated vendored Normal file
View file

@ -0,0 +1,271 @@
/* eslint-env browser */
/**
* This is the web browser implementation of `debug()`.
*/
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
exports.storage = localstorage();
exports.destroy = (() => {
let warned = false;
return () => {
if (!warned) {
warned = true;
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
}
};
})();
/**
* Colors.
*/
exports.colors = [
'#0000CC',
'#0000FF',
'#0033CC',
'#0033FF',
'#0066CC',
'#0066FF',
'#0099CC',
'#0099FF',
'#00CC00',
'#00CC33',
'#00CC66',
'#00CC99',
'#00CCCC',
'#00CCFF',
'#3300CC',
'#3300FF',
'#3333CC',
'#3333FF',
'#3366CC',
'#3366FF',
'#3399CC',
'#3399FF',
'#33CC00',
'#33CC33',
'#33CC66',
'#33CC99',
'#33CCCC',
'#33CCFF',
'#6600CC',
'#6600FF',
'#6633CC',
'#6633FF',
'#66CC00',
'#66CC33',
'#9900CC',
'#9900FF',
'#9933CC',
'#9933FF',
'#99CC00',
'#99CC33',
'#CC0000',
'#CC0033',
'#CC0066',
'#CC0099',
'#CC00CC',
'#CC00FF',
'#CC3300',
'#CC3333',
'#CC3366',
'#CC3399',
'#CC33CC',
'#CC33FF',
'#CC6600',
'#CC6633',
'#CC9900',
'#CC9933',
'#CCCC00',
'#CCCC33',
'#FF0000',
'#FF0033',
'#FF0066',
'#FF0099',
'#FF00CC',
'#FF00FF',
'#FF3300',
'#FF3333',
'#FF3366',
'#FF3399',
'#FF33CC',
'#FF33FF',
'#FF6600',
'#FF6633',
'#FF9900',
'#FF9933',
'#FFCC00',
'#FFCC33'
];
/**
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
* and the Firebug extension (any Firefox version) are known
* to support "%c" CSS customizations.
*
* TODO: add a `localStorage` variable to explicitly enable/disable colors
*/
// eslint-disable-next-line complexity
function useColors() {
// NB: In an Electron preload script, document will be defined but not fully
// initialized. Since we know we're in Chrome, we'll just detect this case
// explicitly
if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
return true;
}
// Internet Explorer and Edge do not support colors.
if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
return false;
}
let m;
// Is webkit? http://stackoverflow.com/a/16459606/376773
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
// Is firebug? http://stackoverflow.com/a/398120/376773
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
// Is firefox >= v31?
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) ||
// Double check webkit in userAgent just in case we are in a worker
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
}
/**
* Colorize log arguments if enabled.
*
* @api public
*/
function formatArgs(args) {
args[0] = (this.useColors ? '%c' : '') +
this.namespace +
(this.useColors ? ' %c' : ' ') +
args[0] +
(this.useColors ? '%c ' : ' ') +
'+' + module.exports.humanize(this.diff);
if (!this.useColors) {
return;
}
const c = 'color: ' + this.color;
args.splice(1, 0, c, 'color: inherit');
// The final "%c" is somewhat tricky, because there could be other
// arguments passed either before or after the %c, so we need to
// figure out the correct index to insert the CSS into
let index = 0;
let lastC = 0;
args[0].replace(/%[a-zA-Z%]/g, match => {
if (match === '%%') {
return;
}
index++;
if (match === '%c') {
// We only are interested in the *last* %c
// (the user may have provided their own)
lastC = index;
}
});
args.splice(lastC, 0, c);
}
/**
* Invokes `console.debug()` when available.
* No-op when `console.debug` is not a "function".
* If `console.debug` is not available, falls back
* to `console.log`.
*
* @api public
*/
exports.log = console.debug || console.log || (() => {});
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
try {
if (namespaces) {
exports.storage.setItem('debug', namespaces);
} else {
exports.storage.removeItem('debug');
}
} catch (error) {
// Swallow
// XXX (@Qix-) should we be logging these?
}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
let r;
try {
r = exports.storage.getItem('debug');
} catch (error) {
// Swallow
// XXX (@Qix-) should we be logging these?
}
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
if (!r && typeof process !== 'undefined' && 'env' in process) {
r = process.env.DEBUG;
}
return r;
}
/**
* Localstorage attempts to return the localstorage.
*
* This is necessary because safari throws
* when a user disables cookies/localstorage
* and you attempt to access it.
*
* @return {LocalStorage}
* @api private
*/
function localstorage() {
try {
// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
// The Browser also has localStorage in the global context.
return localStorage;
} catch (error) {
// Swallow
// XXX (@Qix-) should we be logging these?
}
}
module.exports = require('./common')(exports);
const {formatters} = module.exports;
/**
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
*/
formatters.j = function (v) {
try {
return JSON.stringify(v);
} catch (error) {
return '[UnexpectedJSONParseError]: ' + error.message;
}
};

274
node_modules/debug/src/common.js generated vendored Normal file
View file

@ -0,0 +1,274 @@
/**
* This is the common logic for both the Node.js and web browser
* implementations of `debug()`.
*/
function setup(env) {
createDebug.debug = createDebug;
createDebug.default = createDebug;
createDebug.coerce = coerce;
createDebug.disable = disable;
createDebug.enable = enable;
createDebug.enabled = enabled;
createDebug.humanize = require('ms');
createDebug.destroy = destroy;
Object.keys(env).forEach(key => {
createDebug[key] = env[key];
});
/**
* The currently active debug mode names, and names to skip.
*/
createDebug.names = [];
createDebug.skips = [];
/**
* Map of special "%n" handling functions, for the debug "format" argument.
*
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
*/
createDebug.formatters = {};
/**
* Selects a color for a debug namespace
* @param {String} namespace The namespace string for the debug instance to be colored
* @return {Number|String} An ANSI color code for the given namespace
* @api private
*/
function selectColor(namespace) {
let hash = 0;
for (let i = 0; i < namespace.length; i++) {
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
hash |= 0; // Convert to 32bit integer
}
return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
}
createDebug.selectColor = selectColor;
/**
* Create a debugger with the given `namespace`.
*
* @param {String} namespace
* @return {Function}
* @api public
*/
function createDebug(namespace) {
let prevTime;
let enableOverride = null;
let namespacesCache;
let enabledCache;
function debug(...args) {
// Disabled?
if (!debug.enabled) {
return;
}
const self = debug;
// Set `diff` timestamp
const curr = Number(new Date());
const ms = curr - (prevTime || curr);
self.diff = ms;
self.prev = prevTime;
self.curr = curr;
prevTime = curr;
args[0] = createDebug.coerce(args[0]);
if (typeof args[0] !== 'string') {
// Anything else let's inspect with %O
args.unshift('%O');
}
// Apply any `formatters` transformations
let index = 0;
args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
// If we encounter an escaped % then don't increase the array index
if (match === '%%') {
return '%';
}
index++;
const formatter = createDebug.formatters[format];
if (typeof formatter === 'function') {
const val = args[index];
match = formatter.call(self, val);
// Now we need to remove `args[index]` since it's inlined in the `format`
args.splice(index, 1);
index--;
}
return match;
});
// Apply env-specific formatting (colors, etc.)
createDebug.formatArgs.call(self, args);
const logFn = self.log || createDebug.log;
logFn.apply(self, args);
}
debug.namespace = namespace;
debug.useColors = createDebug.useColors();
debug.color = createDebug.selectColor(namespace);
debug.extend = extend;
debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.
Object.defineProperty(debug, 'enabled', {
enumerable: true,
configurable: false,
get: () => {
if (enableOverride !== null) {
return enableOverride;
}
if (namespacesCache !== createDebug.namespaces) {
namespacesCache = createDebug.namespaces;
enabledCache = createDebug.enabled(namespace);
}
return enabledCache;
},
set: v => {
enableOverride = v;
}
});
// Env-specific initialization logic for debug instances
if (typeof createDebug.init === 'function') {
createDebug.init(debug);
}
return debug;
}
function extend(namespace, delimiter) {
const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
newDebug.log = this.log;
return newDebug;
}
/**
* Enables a debug mode by namespaces. This can include modes
* separated by a colon and wildcards.
*
* @param {String} namespaces
* @api public
*/
function enable(namespaces) {
createDebug.save(namespaces);
createDebug.namespaces = namespaces;
createDebug.names = [];
createDebug.skips = [];
let i;
const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
const len = split.length;
for (i = 0; i < len; i++) {
if (!split[i]) {
// ignore empty strings
continue;
}
namespaces = split[i].replace(/\*/g, '.*?');
if (namespaces[0] === '-') {
createDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$'));
} else {
createDebug.names.push(new RegExp('^' + namespaces + '$'));
}
}
}
/**
* Disable debug output.
*
* @return {String} namespaces
* @api public
*/
function disable() {
const namespaces = [
...createDebug.names.map(toNamespace),
...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
].join(',');
createDebug.enable('');
return namespaces;
}
/**
* Returns true if the given mode name is enabled, false otherwise.
*
* @param {String} name
* @return {Boolean}
* @api public
*/
function enabled(name) {
if (name[name.length - 1] === '*') {
return true;
}
let i;
let len;
for (i = 0, len = createDebug.skips.length; i < len; i++) {
if (createDebug.skips[i].test(name)) {
return false;
}
}
for (i = 0, len = createDebug.names.length; i < len; i++) {
if (createDebug.names[i].test(name)) {
return true;
}
}
return false;
}
/**
* Convert regexp to namespace
*
* @param {RegExp} regxep
* @return {String} namespace
* @api private
*/
function toNamespace(regexp) {
return regexp.toString()
.substring(2, regexp.toString().length - 2)
.replace(/\.\*\?$/, '*');
}
/**
* Coerce `val`.
*
* @param {Mixed} val
* @return {Mixed}
* @api private
*/
function coerce(val) {
if (val instanceof Error) {
return val.stack || val.message;
}
return val;
}
/**
* XXX DO NOT USE. This is a temporary stub function.
* XXX It WILL be removed in the next major release.
*/
function destroy() {
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
}
createDebug.enable(createDebug.load());
return createDebug;
}
module.exports = setup;

10
node_modules/debug/src/index.js generated vendored Normal file
View file

@ -0,0 +1,10 @@
/**
* Detect Electron renderer / nwjs process, which is node, but we should
* treat as a browser.
*/
if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) {
module.exports = require('./browser.js');
} else {
module.exports = require('./node.js');
}

263
node_modules/debug/src/node.js generated vendored Normal file
View file

@ -0,0 +1,263 @@
/**
* Module dependencies.
*/
const tty = require('tty');
const util = require('util');
/**
* This is the Node.js implementation of `debug()`.
*/
exports.init = init;
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
exports.destroy = util.deprecate(
() => {},
'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'
);
/**
* Colors.
*/
exports.colors = [6, 2, 3, 4, 5, 1];
try {
// Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json)
// eslint-disable-next-line import/no-extraneous-dependencies
const supportsColor = require('supports-color');
if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
exports.colors = [
20,
21,
26,
27,
32,
33,
38,
39,
40,
41,
42,
43,
44,
45,
56,
57,
62,
63,
68,
69,
74,
75,
76,
77,
78,
79,
80,
81,
92,
93,
98,
99,
112,
113,
128,
129,
134,
135,
148,
149,
160,
161,
162,
163,
164,
165,
166,
167,
168,
169,
170,
171,
172,
173,
178,
179,
184,
185,
196,
197,
198,
199,
200,
201,
202,
203,
204,
205,
206,
207,
208,
209,
214,
215,
220,
221
];
}
} catch (error) {
// Swallow - we only care if `supports-color` is available; it doesn't have to be.
}
/**
* Build up the default `inspectOpts` object from the environment variables.
*
* $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
*/
exports.inspectOpts = Object.keys(process.env).filter(key => {
return /^debug_/i.test(key);
}).reduce((obj, key) => {
// Camel-case
const prop = key
.substring(6)
.toLowerCase()
.replace(/_([a-z])/g, (_, k) => {
return k.toUpperCase();
});
// Coerce string value into JS value
let val = process.env[key];
if (/^(yes|on|true|enabled)$/i.test(val)) {
val = true;
} else if (/^(no|off|false|disabled)$/i.test(val)) {
val = false;
} else if (val === 'null') {
val = null;
} else {
val = Number(val);
}
obj[prop] = val;
return obj;
}, {});
/**
* Is stdout a TTY? Colored output is enabled when `true`.
*/
function useColors() {
return 'colors' in exports.inspectOpts ?
Boolean(exports.inspectOpts.colors) :
tty.isatty(process.stderr.fd);
}
/**
* Adds ANSI color escape codes if enabled.
*
* @api public
*/
function formatArgs(args) {
const {namespace: name, useColors} = this;
if (useColors) {
const c = this.color;
const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c);
const prefix = ` ${colorCode};1m${name} \u001B[0m`;
args[0] = prefix + args[0].split('\n').join('\n' + prefix);
args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m');
} else {
args[0] = getDate() + name + ' ' + args[0];
}
}
function getDate() {
if (exports.inspectOpts.hideDate) {
return '';
}
return new Date().toISOString() + ' ';
}
/**
* Invokes `util.formatWithOptions()` with the specified arguments and writes to stderr.
*/
function log(...args) {
return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + '\n');
}
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
if (namespaces) {
process.env.DEBUG = namespaces;
} else {
// If you set a process.env field to null or undefined, it gets cast to the
// string 'null' or 'undefined'. Just delete instead.
delete process.env.DEBUG;
}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
return process.env.DEBUG;
}
/**
* Init logic for `debug` instances.
*
* Create a new `inspectOpts` object in case `useColors` is set
* differently for a particular `debug` instance.
*/
function init(debug) {
debug.inspectOpts = {};
const keys = Object.keys(exports.inspectOpts);
for (let i = 0; i < keys.length; i++) {
debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
}
}
module.exports = require('./common')(exports);
const {formatters} = module.exports;
/**
* Map %o to `util.inspect()`, all on a single line.
*/
formatters.o = function (v) {
this.inspectOpts.colors = this.useColors;
return util.inspect(v, this.inspectOpts)
.split('\n')
.map(str => str.trim())
.join(' ');
};
/**
* Map %O to `util.inspect()`, allowing multiple lines if needed.
*/
formatters.O = function (v) {
this.inspectOpts.colors = this.useColors;
return util.inspect(v, this.inspectOpts);
};

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

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

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

@ -0,0 +1,331 @@
# 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.
- `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,38 @@
"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.encode = encode;
exports.decode = decode;
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
*/
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,67 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = parse;
// 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 > 8000) {
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;
}

4
node_modules/engine.io-client/build/cjs/globals.d.ts generated vendored Normal file
View file

@ -0,0 +1,4 @@
export declare const nextTick: (cb: any, setTimeoutFn: any) => any;
export declare const globalThisShim: any;
export declare const defaultBinaryType = "arraybuffer";
export declare function createCookieJar(): void;

26
node_modules/engine.io-client/build/cjs/globals.js generated vendored Normal file
View file

@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultBinaryType = exports.globalThisShim = exports.nextTick = void 0;
exports.createCookieJar = createCookieJar;
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.globalThisShim = (() => {
if (typeof self !== "undefined") {
return self;
}
else if (typeof window !== "undefined") {
return window;
}
else {
return Function("return this")();
}
})();
exports.defaultBinaryType = "arraybuffer";
function createCookieJar() { }

View file

@ -0,0 +1,21 @@
export declare const nextTick: (callback: Function, ...args: any[]) => void;
export declare const globalThisShim: typeof globalThis;
export declare const defaultBinaryType = "nodebuffer";
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(values: string[]): void;
get cookies(): IterableIterator<[string, Cookie]>;
addCookies(xhr: any): void;
appendCookies(headers: Headers): void;
}
export {};

View file

@ -0,0 +1,97 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CookieJar = exports.defaultBinaryType = exports.globalThisShim = exports.nextTick = void 0;
exports.createCookieJar = createCookieJar;
exports.parse = parse;
exports.nextTick = process.nextTick;
exports.globalThisShim = global;
exports.defaultBinaryType = "nodebuffer";
function createCookieJar() {
return new CookieJar();
}
/**
* @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;
}
class CookieJar {
constructor() {
this._cookies = new Map();
}
parseCookies(values) {
if (!values) {
return;
}
values.forEach((value) => {
const parsed = parse(value);
if (parsed) {
this._cookies.set(parsed.name, parsed);
}
});
}
get cookies() {
const now = Date.now();
this._cookies.forEach((cookie, name) => {
var _a;
if (((_a = cookie.expires) === null || _a === void 0 ? void 0 : _a.getTime()) < now) {
this._cookies.delete(name);
}
});
return this._cookies.entries();
}
addCookies(xhr) {
const cookies = [];
for (const [name, cookie] of this.cookies) {
cookies.push(`${name}=${cookie.value}`);
}
if (cookies.length) {
xhr.setDisableHeaderCheck(true);
xhr.setRequestHeader("cookie", cookies.join("; "));
}
}
appendCookies(headers) {
for (const [name, cookie] of this.cookies) {
headers.append("cookie", `${name}=${cookie.value}`);
}
}
}
exports.CookieJar = CookieJar;

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

@ -0,0 +1,15 @@
import { Socket } from "./socket.js";
export { Socket };
export { SocketOptions, SocketWithoutUpgrade, SocketWithUpgrade, } 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 "./globals.node.js";
export { Fetch } from "./transports/polling-fetch.js";
export { XHR as NodeXHR } from "./transports/polling-xhr.node.js";
export { XHR } from "./transports/polling-xhr.js";
export { WS as NodeWebSocket } from "./transports/websocket.node.js";
export { WS as WebSocket } from "./transports/websocket.js";
export { WT as WebTransport } from "./transports/webtransport.js";

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

@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebTransport = exports.WebSocket = exports.NodeWebSocket = exports.XHR = exports.NodeXHR = exports.Fetch = exports.nextTick = exports.parse = exports.installTimerFunctions = exports.transports = exports.TransportError = exports.Transport = exports.protocol = exports.SocketWithUpgrade = exports.SocketWithoutUpgrade = exports.Socket = void 0;
const socket_js_1 = require("./socket.js");
Object.defineProperty(exports, "Socket", { enumerable: true, get: function () { return socket_js_1.Socket; } });
var socket_js_2 = require("./socket.js");
Object.defineProperty(exports, "SocketWithoutUpgrade", { enumerable: true, get: function () { return socket_js_2.SocketWithoutUpgrade; } });
Object.defineProperty(exports, "SocketWithUpgrade", { enumerable: true, get: function () { return socket_js_2.SocketWithUpgrade; } });
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 globals_node_js_1 = require("./globals.node.js");
Object.defineProperty(exports, "nextTick", { enumerable: true, get: function () { return globals_node_js_1.nextTick; } });
var polling_fetch_js_1 = require("./transports/polling-fetch.js");
Object.defineProperty(exports, "Fetch", { enumerable: true, get: function () { return polling_fetch_js_1.Fetch; } });
var polling_xhr_node_js_1 = require("./transports/polling-xhr.node.js");
Object.defineProperty(exports, "NodeXHR", { enumerable: true, get: function () { return polling_xhr_node_js_1.XHR; } });
var polling_xhr_js_1 = require("./transports/polling-xhr.js");
Object.defineProperty(exports, "XHR", { enumerable: true, get: function () { return polling_xhr_js_1.XHR; } });
var websocket_node_js_1 = require("./transports/websocket.node.js");
Object.defineProperty(exports, "NodeWebSocket", { enumerable: true, get: function () { return websocket_node_js_1.WS; } });
var websocket_js_1 = require("./transports/websocket.js");
Object.defineProperty(exports, "WebSocket", { enumerable: true, get: function () { return websocket_js_1.WS; } });
var webtransport_js_1 = require("./transports/webtransport.js");
Object.defineProperty(exports, "WebTransport", { enumerable: true, get: function () { return webtransport_js_1.WT; } });

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/polling-xhr.node.js": "./transports/polling-xhr.js",
"./transports/websocket.node.js": "./transports/websocket.js",
"./globals.node.js": "./globals.js"
}
}

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

@ -0,0 +1,482 @@
import { Emitter } from "@socket.io/component-emitter";
import type { Packet, BinaryType, RawData } from "engine.io-parser";
import { CloseDetails, Transport } from "./transport.js";
import { CookieJar } from "./globals.node.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?: ("polling" | "websocket" | "webtransport" | string)[] | TransportCtor[];
/**
* Whether all the transports should be tested, instead of just the first one.
*
* If set to `true`, the client will first try to connect with HTTP long-polling, and then with WebSocket in case of
* failure, and finally with WebTransport if the previous attempts have failed.
*
* If set to `false` (default), if the connection with HTTP long-polling fails, then the client will not test the
* other transports and will abort the connection.
*
* @default false
*/
tryAllTransports?: boolean;
/**
* 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;
/**
* 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;
/**
* Whether the heartbeat timer should be unref'ed, in order not to keep the Node.js event loop active.
*
* @see https://nodejs.org/api/timers.html#timeoutunref
* @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[];
}
type TransportCtor = {
new (o: any): Transport;
};
type BaseSocketOptions = Omit<SocketOptions, "transports"> & {
transports: TransportCtor[];
};
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: RawData) => void;
message: (data: RawData) => void;
drain: () => void;
flush: () => void;
heartbeat: () => void;
ping: () => void;
pong: () => void;
error: (err: string | Error) => void;
upgrading: (transport: Transport) => void;
upgrade: (transport: Transport) => void;
upgradeError: (err: Error) => void;
close: (reason: string, description?: CloseDetails | Error) => void;
}
type SocketState = "opening" | "open" | "closing" | "closed";
interface WriteOptions {
compress?: boolean;
}
/**
* This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
* with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
*
* This class comes without upgrade mechanism, which means that it will keep the first low-level transport that
* successfully establishes the connection.
*
* In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory.
*
* @example
* import { SocketWithoutUpgrade, WebSocket } from "engine.io-client";
*
* const socket = new SocketWithoutUpgrade({
* transports: [WebSocket]
* });
*
* socket.on("open", () => {
* socket.send("hello");
* });
*
* @see SocketWithUpgrade
* @see Socket
*/
export declare class SocketWithoutUpgrade extends Emitter<Record<never, never>, Record<never, never>, SocketReservedEvents> {
id: string;
transport: Transport;
binaryType: BinaryType;
readyState: SocketState;
writeBuffer: Packet[];
protected readonly opts: BaseSocketOptions;
protected readonly transports: string[];
protected upgrading: boolean;
protected setTimeoutFn: typeof setTimeout;
private _prevBufferLen;
private _pingInterval;
private _pingTimeout;
private _maxPayload?;
private _pingTimeoutTimer;
/**
* The expiration timestamp of the {@link _pingTimeoutTimer} object is tracked, in case the timer is throttled and the
* callback is not fired on time. This can happen for example when a laptop is suspended or when a phone is locked.
*/
private _pingTimeoutTime;
private clearTimeoutFn;
private readonly _beforeunloadEventListener;
private readonly _offlineEventListener;
private readonly secure;
private readonly hostname;
private readonly port;
private readonly _transportsByName;
/**
* The cookie jar will store the cookies sent by the server (Node. js only).
*/
readonly _cookieJar: CookieJar;
static priorWebsocketSuccess: boolean;
static protocol: number;
/**
* Socket constructor.
*
* @param {String|Object} uri - uri or options
* @param {Object} opts - options
*/
constructor(uri: string | BaseSocketOptions, opts: BaseSocketOptions);
/**
* Creates transport of the given type.
*
* @param {String} name - transport name
* @return {Transport}
* @private
*/
protected createTransport(name: string): Transport;
/**
* Initializes transport to use and starts probe.
*
* @private
*/
private _open;
/**
* Sets the current transport. Disables the existing one (if any).
*
* @private
*/
protected setTransport(transport: Transport): void;
/**
* Called when connection is deemed open.
*
* @private
*/
protected onOpen(): void;
/**
* Handles a packet.
*
* @private
*/
private _onPacket;
/**
* Called upon handshake completion.
*
* @param {Object} data - handshake obj
* @private
*/
protected onHandshake(data: HandshakeData): void;
/**
* Sets and resets ping timeout timer based on server pings.
*
* @private
*/
private _resetPingTimeout;
/**
* Called on `drain` event
*
* @private
*/
private _onDrain;
/**
* Flush write buffers.
*
* @private
*/
protected flush(): void;
/**
* Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP
* long-polling)
*
* @private
*/
private _getWritablePackets;
/**
* Checks whether the heartbeat timer has expired but the socket has not yet been notified.
*
* Note: this method is private for now because it does not really fit the WebSocket API, but if we put it in the
* `write()` method then the message would not be buffered by the Socket.IO client.
*
* @return {boolean}
* @private
*/
_hasPingExpired(): boolean;
/**
* Sends a message.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} fn - callback function.
* @return {Socket} for chaining.
*/
write(msg: RawData, options?: WriteOptions, fn?: () => void): this;
/**
* Sends a message. Alias of {@link Socket#write}.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} fn - callback function.
* @return {Socket} for chaining.
*/
send(msg: RawData, options?: WriteOptions, fn?: () => void): 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;
}
/**
* This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
* with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
*
* This class comes with an upgrade mechanism, which means that once the connection is established with the first
* low-level transport, it will try to upgrade to a better transport.
*
* In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory.
*
* @example
* import { SocketWithUpgrade, WebSocket } from "engine.io-client";
*
* const socket = new SocketWithUpgrade({
* transports: [WebSocket]
* });
*
* socket.on("open", () => {
* socket.send("hello");
* });
*
* @see SocketWithoutUpgrade
* @see Socket
*/
export declare class SocketWithUpgrade extends SocketWithoutUpgrade {
private _upgrades;
onOpen(): void;
/**
* Probes a transport.
*
* @param {String} name - transport name
* @private
*/
private _probe;
onHandshake(data: HandshakeData): void;
/**
* Filters upgrades, returning only those matching client transports.
*
* @param {Array} upgrades - server upgrades
* @private
*/
private _filterUpgrades;
}
/**
* This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
* with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
*
* This class comes with an upgrade mechanism, which means that once the connection is established with the first
* low-level transport, it will try to upgrade to a better transport.
*
* @example
* import { Socket } from "engine.io-client";
*
* const socket = new Socket();
*
* socket.on("open", () => {
* socket.send("hello");
* });
*
* @see SocketWithoutUpgrade
* @see SocketWithUpgrade
*/
export declare class Socket extends SocketWithUpgrade {
constructor(uri?: string, opts?: SocketOptions);
constructor(opts: SocketOptions);
}
export {};

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

@ -0,0 +1,765 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Socket = exports.SocketWithUpgrade = exports.SocketWithoutUpgrade = 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 component_emitter_1 = require("@socket.io/component-emitter");
const engine_io_parser_1 = require("engine.io-parser");
const globals_node_js_1 = require("./globals.node.js");
const debug_1 = __importDefault(require("debug")); // debug()
const debug = (0, debug_1.default)("engine.io-client:socket"); // debug()
const withEventListeners = typeof addEventListener === "function" &&
typeof removeEventListener === "function";
const OFFLINE_EVENT_LISTENERS = [];
if (withEventListeners) {
// within a ServiceWorker, any event handler for the 'offline' event must be added on the initial evaluation of the
// script, so we create one single event listener here which will forward the event to the socket instances
addEventListener("offline", () => {
debug("closing %d connection(s) because the network was lost", OFFLINE_EVENT_LISTENERS.length);
OFFLINE_EVENT_LISTENERS.forEach((listener) => listener());
}, false);
}
/**
* This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
* with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
*
* This class comes without upgrade mechanism, which means that it will keep the first low-level transport that
* successfully establishes the connection.
*
* In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory.
*
* @example
* import { SocketWithoutUpgrade, WebSocket } from "engine.io-client";
*
* const socket = new SocketWithoutUpgrade({
* transports: [WebSocket]
* });
*
* socket.on("open", () => {
* socket.send("hello");
* });
*
* @see SocketWithUpgrade
* @see Socket
*/
class SocketWithoutUpgrade extends component_emitter_1.Emitter {
/**
* Socket constructor.
*
* @param {String|Object} uri - uri or options
* @param {Object} opts - options
*/
constructor(uri, opts) {
super();
this.binaryType = globals_node_js_1.defaultBinaryType;
this.writeBuffer = [];
this._prevBufferLen = 0;
this._pingInterval = -1;
this._pingTimeout = -1;
this._maxPayload = -1;
/**
* The expiration timestamp of the {@link _pingTimeoutTimer} object is tracked, in case the timer is throttled and the
* callback is not fired on time. This can happen for example when a laptop is suspended or when a phone is locked.
*/
this._pingTimeoutTime = Infinity;
if (uri && "object" === typeof uri) {
opts = uri;
uri = null;
}
if (uri) {
const parsedUri = (0, parseuri_js_1.parse)(uri);
opts.hostname = parsedUri.host;
opts.secure =
parsedUri.protocol === "https" || parsedUri.protocol === "wss";
opts.port = parsedUri.port;
if (parsedUri.query)
opts.query = parsedUri.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 = [];
this._transportsByName = {};
opts.transports.forEach((t) => {
const transportName = t.prototype.name;
this.transports.push(transportName);
this._transportsByName[transportName] = t;
});
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);
}
if (withEventListeners) {
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") {
debug("adding listener for the 'offline' event");
this._offlineEventListener = () => {
this._onClose("transport close", {
description: "network connection lost",
});
};
OFFLINE_EVENT_LISTENERS.push(this._offlineEventListener);
}
}
if (this.opts.withCredentials) {
this._cookieJar = (0, globals_node_js_1.createCookieJar)();
}
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 this._transportsByName[name](opts);
}
/**
* Initializes transport to use and starts probe.
*
* @private
*/
_open() {
if (this.transports.length === 0) {
// Emit error on next tick so it can be listened to
this.setTimeoutFn(() => {
this.emitReserved("error", "No transports available");
}, 0);
return;
}
const transportName = this.opts.rememberUpgrade &&
SocketWithoutUpgrade.priorWebsocketSuccess &&
this.transports.indexOf("websocket") !== -1
? "websocket"
: this.transports[0];
this.readyState = "opening";
const transport = this.createTransport(transportName);
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));
}
/**
* Called when connection is deemed open.
*
* @private
*/
onOpen() {
debug("socket open");
this.readyState = "open";
SocketWithoutUpgrade.priorWebsocketSuccess =
"websocket" === this.transport.name;
this.emitReserved("open");
this.flush();
}
/**
* 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");
switch (packet.type) {
case "open":
this.onHandshake(JSON.parse(packet.data));
break;
case "ping":
this._sendPacket("pong");
this.emitReserved("ping");
this.emitReserved("pong");
this._resetPingTimeout();
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._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);
const delay = this._pingInterval + this._pingTimeout;
this._pingTimeoutTime = Date.now() + delay;
this._pingTimeoutTimer = this.setTimeoutFn(() => {
this._onClose("ping timeout");
}, delay);
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;
}
/**
* Checks whether the heartbeat timer has expired but the socket has not yet been notified.
*
* Note: this method is private for now because it does not really fit the WebSocket API, but if we put it in the
* `write()` method then the message would not be buffered by the Socket.IO client.
*
* @return {boolean}
* @private
*/
/* private */ _hasPingExpired() {
if (!this._pingTimeoutTime)
return true;
const hasExpired = Date.now() > this._pingTimeoutTime;
if (hasExpired) {
debug("throttled timer detected, scheduling connection close");
this._pingTimeoutTime = 0;
(0, globals_node_js_1.nextTick)(() => {
this._onClose("ping timeout");
}, this.setTimeoutFn);
}
return hasExpired;
}
/**
* Sends a message.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} fn - callback function.
* @return {Socket} for chaining.
*/
write(msg, options, fn) {
this._sendPacket("message", msg, options, fn);
return this;
}
/**
* Sends a message. Alias of {@link Socket#write}.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} fn - callback function.
* @return {Socket} for chaining.
*/
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);
SocketWithoutUpgrade.priorWebsocketSuccess = false;
if (this.opts.tryAllTransports &&
this.transports.length > 1 &&
this.readyState === "opening") {
debug("trying next transport");
this.transports.shift();
return this._open();
}
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 (withEventListeners) {
if (this._beforeunloadEventListener) {
removeEventListener("beforeunload", this._beforeunloadEventListener, false);
}
if (this._offlineEventListener) {
const i = OFFLINE_EVENT_LISTENERS.indexOf(this._offlineEventListener);
if (i !== -1) {
debug("removing listener for the 'offline' event");
OFFLINE_EVENT_LISTENERS.splice(i, 1);
}
}
}
// 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;
}
}
}
exports.SocketWithoutUpgrade = SocketWithoutUpgrade;
SocketWithoutUpgrade.protocol = engine_io_parser_1.protocol;
/**
* This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
* with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
*
* This class comes with an upgrade mechanism, which means that once the connection is established with the first
* low-level transport, it will try to upgrade to a better transport.
*
* In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory.
*
* @example
* import { SocketWithUpgrade, WebSocket } from "engine.io-client";
*
* const socket = new SocketWithUpgrade({
* transports: [WebSocket]
* });
*
* socket.on("open", () => {
* socket.send("hello");
* });
*
* @see SocketWithoutUpgrade
* @see Socket
*/
class SocketWithUpgrade extends SocketWithoutUpgrade {
constructor() {
super(...arguments);
this._upgrades = [];
}
onOpen() {
super.onOpen();
if ("open" === this.readyState && this.opts.upgrade) {
debug("starting upgrade probes");
for (let i = 0; i < this._upgrades.length; i++) {
this._probe(this._upgrades[i]);
}
}
}
/**
* Probes a transport.
*
* @param {String} name - transport name
* @private
*/
_probe(name) {
debug('probing transport "%s"', name);
let transport = this.createTransport(name);
let failed = false;
SocketWithoutUpgrade.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;
SocketWithoutUpgrade.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();
}
}
onHandshake(data) {
this._upgrades = this._filterUpgrades(data.upgrades);
super.onHandshake(data);
}
/**
* Filters upgrades, returning only those matching client transports.
*
* @param {Array} upgrades - server upgrades
* @private
*/
_filterUpgrades(upgrades) {
const filteredUpgrades = [];
for (let i = 0; i < upgrades.length; i++) {
if (~this.transports.indexOf(upgrades[i]))
filteredUpgrades.push(upgrades[i]);
}
return filteredUpgrades;
}
}
exports.SocketWithUpgrade = SocketWithUpgrade;
/**
* This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
* with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
*
* This class comes with an upgrade mechanism, which means that once the connection is established with the first
* low-level transport, it will try to upgrade to a better transport.
*
* @example
* import { Socket } from "engine.io-client";
*
* const socket = new Socket();
*
* socket.on("open", () => {
* socket.send("hello");
* });
*
* @see SocketWithoutUpgrade
* @see SocketWithUpgrade
*/
class Socket extends SocketWithUpgrade {
constructor(uri, opts = {}) {
const o = typeof uri === "object" ? uri : opts;
if (!o.transports ||
(o.transports && typeof o.transports[0] === "string")) {
o.transports = (o.transports || ["polling", "websocket", "webtransport"])
.map((transportName) => index_js_1.transports[transportName])
.filter((t) => !!t);
}
super(uri, o);
}
}
exports.Socket = Socket;

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 type { Socket, 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: Socket;
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 {};

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

@ -0,0 +1,153 @@
"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 parseqs_js_1 = require("./contrib/parseqs.js");
const debug_1 = __importDefault(require("debug")); // debug()
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;
this.supportsBinary = !opts.forceBase64;
}
/**
* 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 { XHR } from "./polling-xhr.node.js";
import { WS } from "./websocket.node.js";
import { WT } from "./webtransport.js";
export declare const transports: {
websocket: typeof WS;
webtransport: typeof WT;
polling: typeof XHR;
};

View file

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

View file

@ -0,0 +1,15 @@
import { Polling } from "./polling.js";
/**
* HTTP long-polling based on the built-in `fetch()` method.
*
* Usage: browser, Node.js (since v18), Deno, Bun
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/fetch
* @see https://caniuse.com/fetch
* @see https://nodejs.org/api/globals.html#fetch
*/
export declare class Fetch extends Polling {
doPoll(): void;
doWrite(data: string, callback: () => void): void;
private _fetch;
}

View file

@ -0,0 +1,60 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Fetch = void 0;
const polling_js_1 = require("./polling.js");
/**
* HTTP long-polling based on the built-in `fetch()` method.
*
* Usage: browser, Node.js (since v18), Deno, Bun
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/fetch
* @see https://caniuse.com/fetch
* @see https://nodejs.org/api/globals.html#fetch
*/
class Fetch extends polling_js_1.Polling {
doPoll() {
this._fetch()
.then((res) => {
if (!res.ok) {
return this.onError("fetch read error", res.status, res);
}
res.text().then((data) => this.onData(data));
})
.catch((err) => {
this.onError("fetch read error", err);
});
}
doWrite(data, callback) {
this._fetch(data)
.then((res) => {
if (!res.ok) {
return this.onError("fetch write error", res.status, res);
}
callback();
})
.catch((err) => {
this.onError("fetch write error", err);
});
}
_fetch(data) {
var _a;
const isPost = data !== undefined;
const headers = new Headers(this.opts.extraHeaders);
if (isPost) {
headers.set("content-type", "text/plain;charset=UTF-8");
}
(_a = this.socket._cookieJar) === null || _a === void 0 ? void 0 : _a.appendCookies(headers);
return fetch(this.uri(), {
method: isPost ? "POST" : "GET",
body: isPost ? data : null,
headers,
credentials: this.opts.withCredentials ? "include" : "omit",
}).then((res) => {
var _a;
// @ts-ignore getSetCookie() was added in Node.js v19.7.0
(_a = this.socket._cookieJar) === null || _a === void 0 ? void 0 : _a.parseCookies(res.headers.getSetCookie());
return res;
});
}
}
exports.Fetch = Fetch;

View file

@ -0,0 +1,108 @@
import { Polling } from "./polling.js";
import { Emitter } from "@socket.io/component-emitter";
import type { SocketOptions } from "../socket.js";
import type { CookieJar } from "../globals.node.js";
import type { RawData } from "engine.io-parser";
export declare abstract class BaseXHR extends Polling {
protected readonly xd: boolean;
private pollXhr;
/**
* XHR Polling constructor.
*
* @param {Object} opts
* @package
*/
constructor(opts: any);
/**
* Creates a request.
*
* @private
*/
abstract request(opts?: Record<string, any>): any;
/**
* Sends data.
*
* @param {String} data to send.
* @param {Function} called upon flush.
* @private
*/
doWrite(data: any, fn: any): void;
/**
* Starts a poll cycle.
*
* @private
*/
doPoll(): void;
}
interface RequestReservedEvents {
success: () => void;
data: (data: RawData) => void;
error: (err: number | Error, context: unknown) => void;
}
export type RequestOptions = SocketOptions & {
method?: string;
data?: RawData;
xd: boolean;
cookieJar: CookieJar;
};
export declare class Request extends Emitter<Record<never, never>, Record<never, never>, RequestReservedEvents> {
private readonly createRequest;
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(createRequest: (opts: RequestOptions) => XMLHttpRequest, uri: string, opts: RequestOptions);
/**
* 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;
}
/**
* HTTP long-polling based on the built-in `XMLHttpRequest` object.
*
* Usage: browser
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
*/
export declare class XHR extends BaseXHR {
constructor(opts: any);
request(opts?: Record<string, any>): Request;
}
export {};

View file

@ -0,0 +1,285 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.XHR = exports.Request = exports.BaseXHR = void 0;
const polling_js_1 = require("./polling.js");
const component_emitter_1 = require("@socket.io/component-emitter");
const util_js_1 = require("../util.js");
const globals_node_js_1 = require("../globals.node.js");
const has_cors_js_1 = require("../contrib/has-cors.js");
const debug_1 = __importDefault(require("debug")); // debug()
const debug = (0, debug_1.default)("engine.io-client:polling"); // debug()
function empty() { }
class BaseXHR extends polling_js_1.Polling {
/**
* XHR Polling constructor.
*
* @param {Object} opts
* @package
*/
constructor(opts) {
super(opts);
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;
}
}
/**
* 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.BaseXHR = BaseXHR;
class Request extends component_emitter_1.Emitter {
/**
* Request constructor
*
* @param {Object} options
* @package
*/
constructor(createRequest, uri, opts) {
super();
this.createRequest = createRequest;
(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 = this.createRequest(opts));
try {
debug("xhr open %s: %s", this._method, this._uri);
xhr.open(this._method, this._uri, true);
try {
if (this._opts.extraHeaders) {
// @ts-ignore
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(
// @ts-ignore
xhr.getResponseHeader("set-cookie"));
}
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 globals_node_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();
}
}
}
const hasXHR2 = (function () {
const xhr = newRequest({
xdomain: false,
});
return xhr && xhr.responseType !== null;
})();
/**
* HTTP long-polling based on the built-in `XMLHttpRequest` object.
*
* Usage: browser
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
*/
class XHR extends BaseXHR {
constructor(opts) {
super(opts);
const forceBase64 = opts && opts.forceBase64;
this.supportsBinary = hasXHR2 && !forceBase64;
}
request(opts = {}) {
Object.assign(opts, { xd: this.xd }, this.opts);
return new Request(newRequest, this.uri(), opts);
}
}
exports.XHR = XHR;
function newRequest(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 globals_node_js_1.globalThisShim[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP");
}
catch (e) { }
}
}

View file

@ -0,0 +1,11 @@
import { BaseXHR, Request } from "./polling-xhr.js";
/**
* HTTP long-polling based on the `XMLHttpRequest` object provided by the `xmlhttprequest-ssl` package.
*
* Usage: Node.js, Deno (compat), Bun (compat)
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
*/
export declare class XHR extends BaseXHR {
request(opts?: Record<string, any>): Request;
}

View file

@ -0,0 +1,44 @@
"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.XHR = void 0;
const XMLHttpRequestModule = __importStar(require("xmlhttprequest-ssl"));
const polling_xhr_js_1 = require("./polling-xhr.js");
const XMLHttpRequest = XMLHttpRequestModule.default || XMLHttpRequestModule;
/**
* HTTP long-polling based on the `XMLHttpRequest` object provided by the `xmlhttprequest-ssl` package.
*
* Usage: Node.js, Deno (compat), Bun (compat)
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
*/
class XHR extends polling_xhr_js_1.BaseXHR {
request(opts = {}) {
var _a;
Object.assign(opts, { xd: this.xd, cookieJar: (_a = this.socket) === null || _a === void 0 ? void 0 : _a._cookieJar }, this.opts);
return new polling_xhr_js_1.Request((opts) => new XMLHttpRequest(opts), this.uri(), opts);
}
}
exports.XHR = XHR;

View file

@ -0,0 +1,52 @@
import { Transport } from "../transport.js";
export declare abstract class Polling extends Transport {
private _polling;
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
*/
private _poll;
/**
* 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
*/
protected uri(): string;
abstract doPoll(): any;
abstract doWrite(data: string, callback: () => void): any;
}

View file

@ -0,0 +1,165 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Polling = void 0;
const transport_js_1 = require("../transport.js");
const util_js_1 = require("../util.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:polling"); // debug()
class Polling extends transport_js_1.Transport {
constructor() {
super(...arguments);
this._polling = false;
}
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, util_js_1.randomString)();
}
if (!this.supportsBinary && !query.sid) {
query.b64 = 1;
}
return this.createUri(schema, query);
}
}
exports.Polling = Polling;

View file

@ -0,0 +1,36 @@
import { Transport } from "../transport.js";
import type { Packet, RawData } from "engine.io-parser";
export declare abstract class BaseWS extends Transport {
protected ws: any;
get name(): string;
doOpen(): this;
abstract createSocket(uri: string, protocols: string | string[] | undefined, opts: Record<string, any>): any;
/**
* Adds event listeners to the socket
*
* @private
*/
private addEventListeners;
write(packets: any): void;
abstract doWrite(packet: Packet, data: RawData): any;
doClose(): void;
/**
* Generates uri for connection.
*
* @private
*/
private uri;
}
/**
* WebSocket transport based on the built-in `WebSocket` object.
*
* Usage: browser, Node.js (since v21), Deno, Bun
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
* @see https://caniuse.com/mdn-api_websocket
* @see https://nodejs.org/api/globals.html#websocket
*/
export declare class WS extends BaseWS {
createSocket(uri: string, protocols: string | string[] | undefined, opts: Record<string, any>): any;
doWrite(_packet: Packet, data: RawData): void;
}

View file

@ -0,0 +1,136 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WS = exports.BaseWS = void 0;
const transport_js_1 = require("../transport.js");
const util_js_1 = require("../util.js");
const engine_io_parser_1 = require("engine.io-parser");
const globals_node_js_1 = require("../globals.node.js");
const debug_1 = __importDefault(require("debug")); // debug()
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 BaseWS extends transport_js_1.Transport {
get name() {
return "websocket";
}
doOpen() {
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 = this.createSocket(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) => {
// 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 {
this.doWrite(packet, data);
}
catch (e) {
debug("websocket closed before onclose event");
}
if (lastPacket) {
// fake drain
// defer to next tick to allow Socket to clear writeBuffer
(0, globals_node_js_1.nextTick)(() => {
this.writable = true;
this.emitReserved("drain");
}, this.setTimeoutFn);
}
});
}
}
doClose() {
if (typeof this.ws !== "undefined") {
this.ws.onerror = () => { };
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, util_js_1.randomString)();
}
// communicate binary support capabilities
if (!this.supportsBinary) {
query.b64 = 1;
}
return this.createUri(schema, query);
}
}
exports.BaseWS = BaseWS;
const WebSocketCtor = globals_node_js_1.globalThisShim.WebSocket || globals_node_js_1.globalThisShim.MozWebSocket;
/**
* WebSocket transport based on the built-in `WebSocket` object.
*
* Usage: browser, Node.js (since v21), Deno, Bun
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
* @see https://caniuse.com/mdn-api_websocket
* @see https://nodejs.org/api/globals.html#websocket
*/
class WS extends BaseWS {
createSocket(uri, protocols, opts) {
return !isReactNative
? protocols
? new WebSocketCtor(uri, protocols)
: new WebSocketCtor(uri)
: new WebSocketCtor(uri, protocols, opts);
}
doWrite(_packet, data) {
this.ws.send(data);
}
}
exports.WS = WS;

View file

@ -0,0 +1,14 @@
import type { Packet, RawData } from "engine.io-parser";
import { BaseWS } from "./websocket.js";
/**
* WebSocket transport based on the `WebSocket` object provided by the `ws` package.
*
* Usage: Node.js, Deno (compat), Bun (compat)
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
* @see https://caniuse.com/mdn-api_websocket
*/
export declare class WS extends BaseWS {
createSocket(uri: string, protocols: string | string[] | undefined, opts: Record<string, any>): any;
doWrite(packet: Packet, data: RawData): void;
}

View file

@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WS = void 0;
const ws_1 = require("ws");
const websocket_js_1 = require("./websocket.js");
/**
* WebSocket transport based on the `WebSocket` object provided by the `ws` package.
*
* Usage: Node.js, Deno (compat), Bun (compat)
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
* @see https://caniuse.com/mdn-api_websocket
*/
class WS extends websocket_js_1.BaseWS {
createSocket(uri, protocols, opts) {
var _a;
if ((_a = this.socket) === null || _a === void 0 ? void 0 : _a._cookieJar) {
opts.headers = opts.headers || {};
opts.headers.cookie =
typeof opts.headers.cookie === "string"
? [opts.headers.cookie]
: opts.headers.cookie || [];
for (const [name, cookie] of this.socket._cookieJar.cookies) {
opts.headers.cookie.push(`${name}=${cookie.value}`);
}
}
return new ws_1.WebSocket(uri, protocols, opts);
}
doWrite(packet, data) {
const opts = {};
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;
}
}
this.ws.send(data, opts);
}
}
exports.WS = WS;

View file

@ -0,0 +1,18 @@
import { Transport } from "../transport.js";
import { Packet } from "engine.io-parser";
/**
* WebTransport transport based on the built-in `WebTransport` object.
*
* Usage: browser, Node.js (with the `@fails-components/webtransport` package)
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebTransport
* @see https://caniuse.com/webtransport
*/
export declare class WT extends Transport {
private _transport;
private _writer;
get name(): string;
protected doOpen(): this;
protected write(packets: Packet[]): void;
protected doClose(): void;
}

View file

@ -0,0 +1,94 @@
"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 globals_node_js_1 = require("../globals.node.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()
/**
* WebTransport transport based on the built-in `WebTransport` object.
*
* Usage: browser, Node.js (with the `@fails-components/webtransport` package)
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebTransport
* @see https://caniuse.com/webtransport
*/
class WT extends transport_js_1.Transport {
get name() {
return "webtransport";
}
doOpen() {
try {
// @ts-ignore
this._transport = new WebTransport(this.createUri("https"), this.opts.transportOptions[this.name]);
}
catch (err) {
return this.emitReserved("error", err);
}
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, globals_node_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;

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

@ -0,0 +1,7 @@
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;
/**
* Generates a random 8-characters string.
*/
export declare function randomString(): string;

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

@ -0,0 +1,65 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.pick = pick;
exports.installTimerFunctions = installTimerFunctions;
exports.byteLength = byteLength;
exports.randomString = randomString;
const globals_node_js_1 = require("./globals.node.js");
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 = globals_node_js_1.globalThisShim.setTimeout;
const NATIVE_CLEAR_TIMEOUT = globals_node_js_1.globalThisShim.clearTimeout;
function installTimerFunctions(obj, opts) {
if (opts.useNativeTimers) {
obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(globals_node_js_1.globalThisShim);
obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(globals_node_js_1.globalThisShim);
}
else {
obj.setTimeoutFn = globals_node_js_1.globalThisShim.setTimeout.bind(globals_node_js_1.globalThisShim);
obj.clearTimeoutFn = globals_node_js_1.globalThisShim.clearTimeout.bind(globals_node_js_1.globalThisShim);
}
}
// 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);
}
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;
}
/**
* Generates a random 8-characters string.
*/
function randomString() {
return (Date.now().toString(36).substring(3) +
Math.random().toString(36).substring(2, 5));
}

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 > 8000) {
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,4 @@
export declare const nextTick: (cb: any, setTimeoutFn: any) => any;
export declare const globalThisShim: any;
export declare const defaultBinaryType = "arraybuffer";
export declare function createCookieJar(): void;

View file

@ -0,0 +1,22 @@
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 globalThisShim = (() => {
if (typeof self !== "undefined") {
return self;
}
else if (typeof window !== "undefined") {
return window;
}
else {
return Function("return this")();
}
})();
export const defaultBinaryType = "arraybuffer";
export function createCookieJar() { }

View file

@ -0,0 +1,21 @@
export declare const nextTick: (callback: Function, ...args: any[]) => void;
export declare const globalThisShim: typeof globalThis;
export declare const defaultBinaryType = "nodebuffer";
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(values: string[]): void;
get cookies(): IterableIterator<[string, Cookie]>;
addCookies(xhr: any): void;
appendCookies(headers: Headers): void;
}
export {};

View file

@ -0,0 +1,91 @@
export const nextTick = process.nextTick;
export const globalThisShim = global;
export const defaultBinaryType = "nodebuffer";
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(values) {
if (!values) {
return;
}
values.forEach((value) => {
const parsed = parse(value);
if (parsed) {
this._cookies.set(parsed.name, parsed);
}
});
}
get cookies() {
const now = Date.now();
this._cookies.forEach((cookie, name) => {
var _a;
if (((_a = cookie.expires) === null || _a === void 0 ? void 0 : _a.getTime()) < now) {
this._cookies.delete(name);
}
});
return this._cookies.entries();
}
addCookies(xhr) {
const cookies = [];
for (const [name, cookie] of this.cookies) {
cookies.push(`${name}=${cookie.value}`);
}
if (cookies.length) {
xhr.setDisableHeaderCheck(true);
xhr.setRequestHeader("cookie", cookies.join("; "));
}
}
appendCookies(headers) {
for (const [name, cookie] of this.cookies) {
headers.append("cookie", `${name}=${cookie.value}`);
}
}
}

View file

@ -0,0 +1,15 @@
import { Socket } from "./socket.js";
export { Socket };
export { SocketOptions, SocketWithoutUpgrade, SocketWithUpgrade, } 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 "./globals.node.js";
export { Fetch } from "./transports/polling-fetch.js";
export { XHR as NodeXHR } from "./transports/polling-xhr.node.js";
export { XHR } from "./transports/polling-xhr.js";
export { WS as NodeWebSocket } from "./transports/websocket.node.js";
export { WS as WebSocket } from "./transports/websocket.js";
export { WT as WebTransport } from "./transports/webtransport.js";

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

@ -0,0 +1,15 @@
import { Socket } from "./socket.js";
export { Socket };
export { SocketWithoutUpgrade, SocketWithUpgrade, } from "./socket.js";
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 "./globals.node.js";
export { Fetch } from "./transports/polling-fetch.js";
export { XHR as NodeXHR } from "./transports/polling-xhr.node.js";
export { XHR } from "./transports/polling-xhr.js";
export { WS as NodeWebSocket } from "./transports/websocket.node.js";
export { WS as WebSocket } from "./transports/websocket.js";
export { WT as WebTransport } from "./transports/webtransport.js";

View file

@ -0,0 +1,10 @@
{
"name": "engine.io-client",
"type": "module",
"browser": {
"ws": false,
"./transports/polling-xhr.node.js": "./transports/polling-xhr.js",
"./transports/websocket.node.js": "./transports/websocket.js",
"./globals.node.js": "./globals.js"
}
}

View file

@ -0,0 +1,482 @@
import { Emitter } from "@socket.io/component-emitter";
import type { Packet, BinaryType, RawData } from "engine.io-parser";
import { CloseDetails, Transport } from "./transport.js";
import { CookieJar } from "./globals.node.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?: ("polling" | "websocket" | "webtransport" | string)[] | TransportCtor[];
/**
* Whether all the transports should be tested, instead of just the first one.
*
* If set to `true`, the client will first try to connect with HTTP long-polling, and then with WebSocket in case of
* failure, and finally with WebTransport if the previous attempts have failed.
*
* If set to `false` (default), if the connection with HTTP long-polling fails, then the client will not test the
* other transports and will abort the connection.
*
* @default false
*/
tryAllTransports?: boolean;
/**
* 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;
/**
* 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;
/**
* Whether the heartbeat timer should be unref'ed, in order not to keep the Node.js event loop active.
*
* @see https://nodejs.org/api/timers.html#timeoutunref
* @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[];
}
type TransportCtor = {
new (o: any): Transport;
};
type BaseSocketOptions = Omit<SocketOptions, "transports"> & {
transports: TransportCtor[];
};
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: RawData) => void;
message: (data: RawData) => void;
drain: () => void;
flush: () => void;
heartbeat: () => void;
ping: () => void;
pong: () => void;
error: (err: string | Error) => void;
upgrading: (transport: Transport) => void;
upgrade: (transport: Transport) => void;
upgradeError: (err: Error) => void;
close: (reason: string, description?: CloseDetails | Error) => void;
}
type SocketState = "opening" | "open" | "closing" | "closed";
interface WriteOptions {
compress?: boolean;
}
/**
* This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
* with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
*
* This class comes without upgrade mechanism, which means that it will keep the first low-level transport that
* successfully establishes the connection.
*
* In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory.
*
* @example
* import { SocketWithoutUpgrade, WebSocket } from "engine.io-client";
*
* const socket = new SocketWithoutUpgrade({
* transports: [WebSocket]
* });
*
* socket.on("open", () => {
* socket.send("hello");
* });
*
* @see SocketWithUpgrade
* @see Socket
*/
export declare class SocketWithoutUpgrade extends Emitter<Record<never, never>, Record<never, never>, SocketReservedEvents> {
id: string;
transport: Transport;
binaryType: BinaryType;
readyState: SocketState;
writeBuffer: Packet[];
protected readonly opts: BaseSocketOptions;
protected readonly transports: string[];
protected upgrading: boolean;
protected setTimeoutFn: typeof setTimeout;
private _prevBufferLen;
private _pingInterval;
private _pingTimeout;
private _maxPayload?;
private _pingTimeoutTimer;
/**
* The expiration timestamp of the {@link _pingTimeoutTimer} object is tracked, in case the timer is throttled and the
* callback is not fired on time. This can happen for example when a laptop is suspended or when a phone is locked.
*/
private _pingTimeoutTime;
private clearTimeoutFn;
private readonly _beforeunloadEventListener;
private readonly _offlineEventListener;
private readonly secure;
private readonly hostname;
private readonly port;
private readonly _transportsByName;
/**
* The cookie jar will store the cookies sent by the server (Node. js only).
*/
readonly _cookieJar: CookieJar;
static priorWebsocketSuccess: boolean;
static protocol: number;
/**
* Socket constructor.
*
* @param {String|Object} uri - uri or options
* @param {Object} opts - options
*/
constructor(uri: string | BaseSocketOptions, opts: BaseSocketOptions);
/**
* Creates transport of the given type.
*
* @param {String} name - transport name
* @return {Transport}
* @private
*/
protected createTransport(name: string): Transport;
/**
* Initializes transport to use and starts probe.
*
* @private
*/
private _open;
/**
* Sets the current transport. Disables the existing one (if any).
*
* @private
*/
protected setTransport(transport: Transport): void;
/**
* Called when connection is deemed open.
*
* @private
*/
protected onOpen(): void;
/**
* Handles a packet.
*
* @private
*/
private _onPacket;
/**
* Called upon handshake completion.
*
* @param {Object} data - handshake obj
* @private
*/
protected onHandshake(data: HandshakeData): void;
/**
* Sets and resets ping timeout timer based on server pings.
*
* @private
*/
private _resetPingTimeout;
/**
* Called on `drain` event
*
* @private
*/
private _onDrain;
/**
* Flush write buffers.
*
* @private
*/
protected flush(): void;
/**
* Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP
* long-polling)
*
* @private
*/
private _getWritablePackets;
/**
* Checks whether the heartbeat timer has expired but the socket has not yet been notified.
*
* Note: this method is private for now because it does not really fit the WebSocket API, but if we put it in the
* `write()` method then the message would not be buffered by the Socket.IO client.
*
* @return {boolean}
* @private
*/
_hasPingExpired(): boolean;
/**
* Sends a message.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} fn - callback function.
* @return {Socket} for chaining.
*/
write(msg: RawData, options?: WriteOptions, fn?: () => void): this;
/**
* Sends a message. Alias of {@link Socket#write}.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} fn - callback function.
* @return {Socket} for chaining.
*/
send(msg: RawData, options?: WriteOptions, fn?: () => void): 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;
}
/**
* This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
* with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
*
* This class comes with an upgrade mechanism, which means that once the connection is established with the first
* low-level transport, it will try to upgrade to a better transport.
*
* In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory.
*
* @example
* import { SocketWithUpgrade, WebSocket } from "engine.io-client";
*
* const socket = new SocketWithUpgrade({
* transports: [WebSocket]
* });
*
* socket.on("open", () => {
* socket.send("hello");
* });
*
* @see SocketWithoutUpgrade
* @see Socket
*/
export declare class SocketWithUpgrade extends SocketWithoutUpgrade {
private _upgrades;
onOpen(): void;
/**
* Probes a transport.
*
* @param {String} name - transport name
* @private
*/
private _probe;
onHandshake(data: HandshakeData): void;
/**
* Filters upgrades, returning only those matching client transports.
*
* @param {Array} upgrades - server upgrades
* @private
*/
private _filterUpgrades;
}
/**
* This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
* with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
*
* This class comes with an upgrade mechanism, which means that once the connection is established with the first
* low-level transport, it will try to upgrade to a better transport.
*
* @example
* import { Socket } from "engine.io-client";
*
* const socket = new Socket();
*
* socket.on("open", () => {
* socket.send("hello");
* });
*
* @see SocketWithoutUpgrade
* @see SocketWithUpgrade
*/
export declare class Socket extends SocketWithUpgrade {
constructor(uri?: string, opts?: SocketOptions);
constructor(opts: SocketOptions);
}
export {};

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

@ -0,0 +1,756 @@
import { transports as DEFAULT_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 { createCookieJar, defaultBinaryType, nextTick, } from "./globals.node.js";
import debugModule from "debug"; // debug()
const debug = debugModule("engine.io-client:socket"); // debug()
const withEventListeners = typeof addEventListener === "function" &&
typeof removeEventListener === "function";
const OFFLINE_EVENT_LISTENERS = [];
if (withEventListeners) {
// within a ServiceWorker, any event handler for the 'offline' event must be added on the initial evaluation of the
// script, so we create one single event listener here which will forward the event to the socket instances
addEventListener("offline", () => {
debug("closing %d connection(s) because the network was lost", OFFLINE_EVENT_LISTENERS.length);
OFFLINE_EVENT_LISTENERS.forEach((listener) => listener());
}, false);
}
/**
* This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
* with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
*
* This class comes without upgrade mechanism, which means that it will keep the first low-level transport that
* successfully establishes the connection.
*
* In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory.
*
* @example
* import { SocketWithoutUpgrade, WebSocket } from "engine.io-client";
*
* const socket = new SocketWithoutUpgrade({
* transports: [WebSocket]
* });
*
* socket.on("open", () => {
* socket.send("hello");
* });
*
* @see SocketWithUpgrade
* @see Socket
*/
export class SocketWithoutUpgrade extends Emitter {
/**
* Socket constructor.
*
* @param {String|Object} uri - uri or options
* @param {Object} opts - options
*/
constructor(uri, opts) {
super();
this.binaryType = defaultBinaryType;
this.writeBuffer = [];
this._prevBufferLen = 0;
this._pingInterval = -1;
this._pingTimeout = -1;
this._maxPayload = -1;
/**
* The expiration timestamp of the {@link _pingTimeoutTimer} object is tracked, in case the timer is throttled and the
* callback is not fired on time. This can happen for example when a laptop is suspended or when a phone is locked.
*/
this._pingTimeoutTime = Infinity;
if (uri && "object" === typeof uri) {
opts = uri;
uri = null;
}
if (uri) {
const parsedUri = parse(uri);
opts.hostname = parsedUri.host;
opts.secure =
parsedUri.protocol === "https" || parsedUri.protocol === "wss";
opts.port = parsedUri.port;
if (parsedUri.query)
opts.query = parsedUri.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 = [];
this._transportsByName = {};
opts.transports.forEach((t) => {
const transportName = t.prototype.name;
this.transports.push(transportName);
this._transportsByName[transportName] = t;
});
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);
}
if (withEventListeners) {
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") {
debug("adding listener for the 'offline' event");
this._offlineEventListener = () => {
this._onClose("transport close", {
description: "network connection lost",
});
};
OFFLINE_EVENT_LISTENERS.push(this._offlineEventListener);
}
}
if (this.opts.withCredentials) {
this._cookieJar = createCookieJar();
}
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 this._transportsByName[name](opts);
}
/**
* Initializes transport to use and starts probe.
*
* @private
*/
_open() {
if (this.transports.length === 0) {
// Emit error on next tick so it can be listened to
this.setTimeoutFn(() => {
this.emitReserved("error", "No transports available");
}, 0);
return;
}
const transportName = this.opts.rememberUpgrade &&
SocketWithoutUpgrade.priorWebsocketSuccess &&
this.transports.indexOf("websocket") !== -1
? "websocket"
: this.transports[0];
this.readyState = "opening";
const transport = this.createTransport(transportName);
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));
}
/**
* Called when connection is deemed open.
*
* @private
*/
onOpen() {
debug("socket open");
this.readyState = "open";
SocketWithoutUpgrade.priorWebsocketSuccess =
"websocket" === this.transport.name;
this.emitReserved("open");
this.flush();
}
/**
* 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");
switch (packet.type) {
case "open":
this.onHandshake(JSON.parse(packet.data));
break;
case "ping":
this._sendPacket("pong");
this.emitReserved("ping");
this.emitReserved("pong");
this._resetPingTimeout();
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._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);
const delay = this._pingInterval + this._pingTimeout;
this._pingTimeoutTime = Date.now() + delay;
this._pingTimeoutTimer = this.setTimeoutFn(() => {
this._onClose("ping timeout");
}, delay);
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;
}
/**
* Checks whether the heartbeat timer has expired but the socket has not yet been notified.
*
* Note: this method is private for now because it does not really fit the WebSocket API, but if we put it in the
* `write()` method then the message would not be buffered by the Socket.IO client.
*
* @return {boolean}
* @private
*/
/* private */ _hasPingExpired() {
if (!this._pingTimeoutTime)
return true;
const hasExpired = Date.now() > this._pingTimeoutTime;
if (hasExpired) {
debug("throttled timer detected, scheduling connection close");
this._pingTimeoutTime = 0;
nextTick(() => {
this._onClose("ping timeout");
}, this.setTimeoutFn);
}
return hasExpired;
}
/**
* Sends a message.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} fn - callback function.
* @return {Socket} for chaining.
*/
write(msg, options, fn) {
this._sendPacket("message", msg, options, fn);
return this;
}
/**
* Sends a message. Alias of {@link Socket#write}.
*
* @param {String} msg - message.
* @param {Object} options.
* @param {Function} fn - callback function.
* @return {Socket} for chaining.
*/
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);
SocketWithoutUpgrade.priorWebsocketSuccess = false;
if (this.opts.tryAllTransports &&
this.transports.length > 1 &&
this.readyState === "opening") {
debug("trying next transport");
this.transports.shift();
return this._open();
}
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 (withEventListeners) {
if (this._beforeunloadEventListener) {
removeEventListener("beforeunload", this._beforeunloadEventListener, false);
}
if (this._offlineEventListener) {
const i = OFFLINE_EVENT_LISTENERS.indexOf(this._offlineEventListener);
if (i !== -1) {
debug("removing listener for the 'offline' event");
OFFLINE_EVENT_LISTENERS.splice(i, 1);
}
}
}
// 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;
}
}
}
SocketWithoutUpgrade.protocol = protocol;
/**
* This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
* with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
*
* This class comes with an upgrade mechanism, which means that once the connection is established with the first
* low-level transport, it will try to upgrade to a better transport.
*
* In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory.
*
* @example
* import { SocketWithUpgrade, WebSocket } from "engine.io-client";
*
* const socket = new SocketWithUpgrade({
* transports: [WebSocket]
* });
*
* socket.on("open", () => {
* socket.send("hello");
* });
*
* @see SocketWithoutUpgrade
* @see Socket
*/
export class SocketWithUpgrade extends SocketWithoutUpgrade {
constructor() {
super(...arguments);
this._upgrades = [];
}
onOpen() {
super.onOpen();
if ("open" === this.readyState && this.opts.upgrade) {
debug("starting upgrade probes");
for (let i = 0; i < this._upgrades.length; i++) {
this._probe(this._upgrades[i]);
}
}
}
/**
* Probes a transport.
*
* @param {String} name - transport name
* @private
*/
_probe(name) {
debug('probing transport "%s"', name);
let transport = this.createTransport(name);
let failed = false;
SocketWithoutUpgrade.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;
SocketWithoutUpgrade.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();
}
}
onHandshake(data) {
this._upgrades = this._filterUpgrades(data.upgrades);
super.onHandshake(data);
}
/**
* Filters upgrades, returning only those matching client transports.
*
* @param {Array} upgrades - server upgrades
* @private
*/
_filterUpgrades(upgrades) {
const filteredUpgrades = [];
for (let i = 0; i < upgrades.length; i++) {
if (~this.transports.indexOf(upgrades[i]))
filteredUpgrades.push(upgrades[i]);
}
return filteredUpgrades;
}
}
/**
* This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
* with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
*
* This class comes with an upgrade mechanism, which means that once the connection is established with the first
* low-level transport, it will try to upgrade to a better transport.
*
* @example
* import { Socket } from "engine.io-client";
*
* const socket = new Socket();
*
* socket.on("open", () => {
* socket.send("hello");
* });
*
* @see SocketWithoutUpgrade
* @see SocketWithUpgrade
*/
export class Socket extends SocketWithUpgrade {
constructor(uri, opts = {}) {
const o = typeof uri === "object" ? uri : opts;
if (!o.transports ||
(o.transports && typeof o.transports[0] === "string")) {
o.transports = (o.transports || ["polling", "websocket", "webtransport"])
.map((transportName) => DEFAULT_TRANSPORTS[transportName])
.filter((t) => !!t);
}
super(uri, o);
}
}

View file

@ -0,0 +1,106 @@
import type { Packet, RawData } from "engine.io-parser";
import { Emitter } from "@socket.io/component-emitter";
import type { Socket, 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: Socket;
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,145 @@
import { decodePacket } from "engine.io-parser";
import { Emitter } from "@socket.io/component-emitter";
import { installTimerFunctions } from "./util.js";
import { encode } from "./contrib/parseqs.js";
import debugModule from "debug"; // debug()
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;
this.supportsBinary = !opts.forceBase64;
}
/**
* 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 { XHR } from "./polling-xhr.node.js";
import { WS } from "./websocket.node.js";
import { WT } from "./webtransport.js";
export declare const transports: {
websocket: typeof WS;
webtransport: typeof WT;
polling: typeof XHR;
};

View file

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

View file

@ -0,0 +1,15 @@
import { Polling } from "./polling.js";
/**
* HTTP long-polling based on the built-in `fetch()` method.
*
* Usage: browser, Node.js (since v18), Deno, Bun
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/fetch
* @see https://caniuse.com/fetch
* @see https://nodejs.org/api/globals.html#fetch
*/
export declare class Fetch extends Polling {
doPoll(): void;
doWrite(data: string, callback: () => void): void;
private _fetch;
}

View file

@ -0,0 +1,56 @@
import { Polling } from "./polling.js";
/**
* HTTP long-polling based on the built-in `fetch()` method.
*
* Usage: browser, Node.js (since v18), Deno, Bun
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/fetch
* @see https://caniuse.com/fetch
* @see https://nodejs.org/api/globals.html#fetch
*/
export class Fetch extends Polling {
doPoll() {
this._fetch()
.then((res) => {
if (!res.ok) {
return this.onError("fetch read error", res.status, res);
}
res.text().then((data) => this.onData(data));
})
.catch((err) => {
this.onError("fetch read error", err);
});
}
doWrite(data, callback) {
this._fetch(data)
.then((res) => {
if (!res.ok) {
return this.onError("fetch write error", res.status, res);
}
callback();
})
.catch((err) => {
this.onError("fetch write error", err);
});
}
_fetch(data) {
var _a;
const isPost = data !== undefined;
const headers = new Headers(this.opts.extraHeaders);
if (isPost) {
headers.set("content-type", "text/plain;charset=UTF-8");
}
(_a = this.socket._cookieJar) === null || _a === void 0 ? void 0 : _a.appendCookies(headers);
return fetch(this.uri(), {
method: isPost ? "POST" : "GET",
body: isPost ? data : null,
headers,
credentials: this.opts.withCredentials ? "include" : "omit",
}).then((res) => {
var _a;
// @ts-ignore getSetCookie() was added in Node.js v19.7.0
(_a = this.socket._cookieJar) === null || _a === void 0 ? void 0 : _a.parseCookies(res.headers.getSetCookie());
return res;
});
}
}

View file

@ -0,0 +1,108 @@
import { Polling } from "./polling.js";
import { Emitter } from "@socket.io/component-emitter";
import type { SocketOptions } from "../socket.js";
import type { CookieJar } from "../globals.node.js";
import type { RawData } from "engine.io-parser";
export declare abstract class BaseXHR extends Polling {
protected readonly xd: boolean;
private pollXhr;
/**
* XHR Polling constructor.
*
* @param {Object} opts
* @package
*/
constructor(opts: any);
/**
* Creates a request.
*
* @private
*/
abstract request(opts?: Record<string, any>): any;
/**
* Sends data.
*
* @param {String} data to send.
* @param {Function} called upon flush.
* @private
*/
doWrite(data: any, fn: any): void;
/**
* Starts a poll cycle.
*
* @private
*/
doPoll(): void;
}
interface RequestReservedEvents {
success: () => void;
data: (data: RawData) => void;
error: (err: number | Error, context: unknown) => void;
}
export type RequestOptions = SocketOptions & {
method?: string;
data?: RawData;
xd: boolean;
cookieJar: CookieJar;
};
export declare class Request extends Emitter<Record<never, never>, Record<never, never>, RequestReservedEvents> {
private readonly createRequest;
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(createRequest: (opts: RequestOptions) => XMLHttpRequest, uri: string, opts: RequestOptions);
/**
* 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;
}
/**
* HTTP long-polling based on the built-in `XMLHttpRequest` object.
*
* Usage: browser
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
*/
export declare class XHR extends BaseXHR {
constructor(opts: any);
request(opts?: Record<string, any>): Request;
}
export {};

View file

@ -0,0 +1,276 @@
import { Polling } from "./polling.js";
import { Emitter } from "@socket.io/component-emitter";
import { installTimerFunctions, pick } from "../util.js";
import { globalThisShim as globalThis } from "../globals.node.js";
import { hasCORS } from "../contrib/has-cors.js";
import debugModule from "debug"; // debug()
const debug = debugModule("engine.io-client:polling"); // debug()
function empty() { }
export class BaseXHR extends Polling {
/**
* XHR Polling constructor.
*
* @param {Object} opts
* @package
*/
constructor(opts) {
super(opts);
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;
}
}
/**
* 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(createRequest, uri, opts) {
super();
this.createRequest = createRequest;
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 = this.createRequest(opts));
try {
debug("xhr open %s: %s", this._method, this._uri);
xhr.open(this._method, this._uri, true);
try {
if (this._opts.extraHeaders) {
// @ts-ignore
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(
// @ts-ignore
xhr.getResponseHeader("set-cookie"));
}
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();
}
}
}
const hasXHR2 = (function () {
const xhr = newRequest({
xdomain: false,
});
return xhr && xhr.responseType !== null;
})();
/**
* HTTP long-polling based on the built-in `XMLHttpRequest` object.
*
* Usage: browser
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
*/
export class XHR extends BaseXHR {
constructor(opts) {
super(opts);
const forceBase64 = opts && opts.forceBase64;
this.supportsBinary = hasXHR2 && !forceBase64;
}
request(opts = {}) {
Object.assign(opts, { xd: this.xd }, this.opts);
return new Request(newRequest, this.uri(), opts);
}
}
function newRequest(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) { }
}
}

View file

@ -0,0 +1,11 @@
import { BaseXHR, Request } from "./polling-xhr.js";
/**
* HTTP long-polling based on the `XMLHttpRequest` object provided by the `xmlhttprequest-ssl` package.
*
* Usage: Node.js, Deno (compat), Bun (compat)
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
*/
export declare class XHR extends BaseXHR {
request(opts?: Record<string, any>): Request;
}

View file

@ -0,0 +1,17 @@
import * as XMLHttpRequestModule from "xmlhttprequest-ssl";
import { BaseXHR, Request } from "./polling-xhr.js";
const XMLHttpRequest = XMLHttpRequestModule.default || XMLHttpRequestModule;
/**
* HTTP long-polling based on the `XMLHttpRequest` object provided by the `xmlhttprequest-ssl` package.
*
* Usage: Node.js, Deno (compat), Bun (compat)
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
*/
export class XHR extends BaseXHR {
request(opts = {}) {
var _a;
Object.assign(opts, { xd: this.xd, cookieJar: (_a = this.socket) === null || _a === void 0 ? void 0 : _a._cookieJar }, this.opts);
return new Request((opts) => new XMLHttpRequest(opts), this.uri(), opts);
}
}

View file

@ -0,0 +1,52 @@
import { Transport } from "../transport.js";
export declare abstract class Polling extends Transport {
private _polling;
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
*/
private _poll;
/**
* 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
*/
protected uri(): string;
abstract doPoll(): any;
abstract doWrite(data: string, callback: () => void): any;
}

View file

@ -0,0 +1,158 @@
import { Transport } from "../transport.js";
import { randomString } from "../util.js";
import { encodePayload, decodePayload } from "engine.io-parser";
import debugModule from "debug"; // debug()
const debug = debugModule("engine.io-client:polling"); // debug()
export class Polling extends Transport {
constructor() {
super(...arguments);
this._polling = false;
}
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] = randomString();
}
if (!this.supportsBinary && !query.sid) {
query.b64 = 1;
}
return this.createUri(schema, query);
}
}

View file

@ -0,0 +1,36 @@
import { Transport } from "../transport.js";
import type { Packet, RawData } from "engine.io-parser";
export declare abstract class BaseWS extends Transport {
protected ws: any;
get name(): string;
doOpen(): this;
abstract createSocket(uri: string, protocols: string | string[] | undefined, opts: Record<string, any>): any;
/**
* Adds event listeners to the socket
*
* @private
*/
private addEventListeners;
write(packets: any): void;
abstract doWrite(packet: Packet, data: RawData): any;
doClose(): void;
/**
* Generates uri for connection.
*
* @private
*/
private uri;
}
/**
* WebSocket transport based on the built-in `WebSocket` object.
*
* Usage: browser, Node.js (since v21), Deno, Bun
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
* @see https://caniuse.com/mdn-api_websocket
* @see https://nodejs.org/api/globals.html#websocket
*/
export declare class WS extends BaseWS {
createSocket(uri: string, protocols: string | string[] | undefined, opts: Record<string, any>): any;
doWrite(_packet: Packet, data: RawData): void;
}

View file

@ -0,0 +1,128 @@
import { Transport } from "../transport.js";
import { pick, randomString } from "../util.js";
import { encodePacket } from "engine.io-parser";
import { globalThisShim as globalThis, nextTick } from "../globals.node.js";
import debugModule from "debug"; // debug()
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 BaseWS extends Transport {
get name() {
return "websocket";
}
doOpen() {
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 = this.createSocket(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) => {
// 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 {
this.doWrite(packet, data);
}
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.onerror = () => { };
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] = randomString();
}
// communicate binary support capabilities
if (!this.supportsBinary) {
query.b64 = 1;
}
return this.createUri(schema, query);
}
}
const WebSocketCtor = globalThis.WebSocket || globalThis.MozWebSocket;
/**
* WebSocket transport based on the built-in `WebSocket` object.
*
* Usage: browser, Node.js (since v21), Deno, Bun
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
* @see https://caniuse.com/mdn-api_websocket
* @see https://nodejs.org/api/globals.html#websocket
*/
export class WS extends BaseWS {
createSocket(uri, protocols, opts) {
return !isReactNative
? protocols
? new WebSocketCtor(uri, protocols)
: new WebSocketCtor(uri)
: new WebSocketCtor(uri, protocols, opts);
}
doWrite(_packet, data) {
this.ws.send(data);
}
}

View file

@ -0,0 +1,14 @@
import type { Packet, RawData } from "engine.io-parser";
import { BaseWS } from "./websocket.js";
/**
* WebSocket transport based on the `WebSocket` object provided by the `ws` package.
*
* Usage: Node.js, Deno (compat), Bun (compat)
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
* @see https://caniuse.com/mdn-api_websocket
*/
export declare class WS extends BaseWS {
createSocket(uri: string, protocols: string | string[] | undefined, opts: Record<string, any>): any;
doWrite(packet: Packet, data: RawData): void;
}

View file

@ -0,0 +1,41 @@
import { WebSocket } from "ws";
import { BaseWS } from "./websocket.js";
/**
* WebSocket transport based on the `WebSocket` object provided by the `ws` package.
*
* Usage: Node.js, Deno (compat), Bun (compat)
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
* @see https://caniuse.com/mdn-api_websocket
*/
export class WS extends BaseWS {
createSocket(uri, protocols, opts) {
var _a;
if ((_a = this.socket) === null || _a === void 0 ? void 0 : _a._cookieJar) {
opts.headers = opts.headers || {};
opts.headers.cookie =
typeof opts.headers.cookie === "string"
? [opts.headers.cookie]
: opts.headers.cookie || [];
for (const [name, cookie] of this.socket._cookieJar.cookies) {
opts.headers.cookie.push(`${name}=${cookie.value}`);
}
}
return new WebSocket(uri, protocols, opts);
}
doWrite(packet, data) {
const opts = {};
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;
}
}
this.ws.send(data, opts);
}
}

View file

@ -0,0 +1,18 @@
import { Transport } from "../transport.js";
import { Packet } from "engine.io-parser";
/**
* WebTransport transport based on the built-in `WebTransport` object.
*
* Usage: browser, Node.js (with the `@fails-components/webtransport` package)
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebTransport
* @see https://caniuse.com/webtransport
*/
export declare class WT extends Transport {
private _transport;
private _writer;
get name(): string;
protected doOpen(): this;
protected write(packets: Packet[]): void;
protected doClose(): void;
}

View file

@ -0,0 +1,87 @@
import { Transport } from "../transport.js";
import { nextTick } from "../globals.node.js";
import { createPacketDecoderStream, createPacketEncoderStream, } from "engine.io-parser";
import debugModule from "debug"; // debug()
const debug = debugModule("engine.io-client:webtransport"); // debug()
/**
* WebTransport transport based on the built-in `WebTransport` object.
*
* Usage: browser, Node.js (with the `@fails-components/webtransport` package)
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebTransport
* @see https://caniuse.com/webtransport
*/
export class WT extends Transport {
get name() {
return "webtransport";
}
doOpen() {
try {
// @ts-ignore
this._transport = new WebTransport(this.createUri("https"), this.opts.transportOptions[this.name]);
}
catch (err) {
return this.emitReserved("error", err);
}
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,7 @@
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;
/**
* Generates a random 8-characters string.
*/
export declare function randomString(): string;

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

@ -0,0 +1,59 @@
import { globalThisShim as globalThis } from "./globals.node.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;
}
/**
* Generates a random 8-characters string.
*/
export function randomString() {
return (Date.now().toString(36).substring(3) +
Math.random().toString(36).substring(2, 5));
}

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): {};

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