This commit is contained in:
2025-01-04 00:34:03 +01:00
parent 41829408dc
commit 0ca14bbc19
18111 changed files with 1871397 additions and 0 deletions

22
resources/app/node_modules/socket.io/LICENSE generated vendored Normal file
View File

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,437 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RemoteSocket = exports.BroadcastOperator = void 0;
const socket_1 = require("./socket");
const socket_io_parser_1 = require("socket.io-parser");
class BroadcastOperator {
constructor(adapter, rooms = new Set(), exceptRooms = new Set(), flags = {}) {
this.adapter = adapter;
this.rooms = rooms;
this.exceptRooms = exceptRooms;
this.flags = flags;
}
/**
* Targets a room when emitting.
*
* @example
* // the “foo” event will be broadcast to all connected clients in the “room-101” room
* io.to("room-101").emit("foo", "bar");
*
* // with an array of rooms (a client will be notified at most once)
* io.to(["room-101", "room-102"]).emit("foo", "bar");
*
* // with multiple chained calls
* io.to("room-101").to("room-102").emit("foo", "bar");
*
* @param room - a room, or an array of rooms
* @return a new {@link BroadcastOperator} instance for chaining
*/
to(room) {
const rooms = new Set(this.rooms);
if (Array.isArray(room)) {
room.forEach((r) => rooms.add(r));
}
else {
rooms.add(room);
}
return new BroadcastOperator(this.adapter, rooms, this.exceptRooms, this.flags);
}
/**
* Targets a room when emitting. Similar to `to()`, but might feel clearer in some cases:
*
* @example
* // disconnect all clients in the "room-101" room
* io.in("room-101").disconnectSockets();
*
* @param room - a room, or an array of rooms
* @return a new {@link BroadcastOperator} instance for chaining
*/
in(room) {
return this.to(room);
}
/**
* Excludes a room when emitting.
*
* @example
* // the "foo" event will be broadcast to all connected clients, except the ones that are in the "room-101" room
* io.except("room-101").emit("foo", "bar");
*
* // with an array of rooms
* io.except(["room-101", "room-102"]).emit("foo", "bar");
*
* // with multiple chained calls
* io.except("room-101").except("room-102").emit("foo", "bar");
*
* @param room - a room, or an array of rooms
* @return a new {@link BroadcastOperator} instance for chaining
*/
except(room) {
const exceptRooms = new Set(this.exceptRooms);
if (Array.isArray(room)) {
room.forEach((r) => exceptRooms.add(r));
}
else {
exceptRooms.add(room);
}
return new BroadcastOperator(this.adapter, this.rooms, exceptRooms, this.flags);
}
/**
* Sets the compress flag.
*
* @example
* io.compress(false).emit("hello");
*
* @param compress - if `true`, compresses the sending data
* @return a new BroadcastOperator instance
*/
compress(compress) {
const flags = Object.assign({}, this.flags, { compress });
return new BroadcastOperator(this.adapter, this.rooms, this.exceptRooms, flags);
}
/**
* Sets a modifier for a subsequent event emission that the event data may be lost if the client is not ready to
* receive messages (because of network slowness or other issues, or because theyre connected through long polling
* and is in the middle of a request-response cycle).
*
* @example
* io.volatile.emit("hello"); // the clients may or may not receive it
*
* @return a new BroadcastOperator instance
*/
get volatile() {
const flags = Object.assign({}, this.flags, { volatile: true });
return new BroadcastOperator(this.adapter, this.rooms, this.exceptRooms, flags);
}
/**
* Sets a modifier for a subsequent event emission that the event data will only be broadcast to the current node.
*
* @example
* // the “foo” event will be broadcast to all connected clients on this node
* io.local.emit("foo", "bar");
*
* @return a new {@link BroadcastOperator} instance for chaining
*/
get local() {
const flags = Object.assign({}, this.flags, { local: true });
return new BroadcastOperator(this.adapter, this.rooms, this.exceptRooms, flags);
}
/**
* Adds a timeout in milliseconds for the next operation
*
* @example
* io.timeout(1000).emit("some-event", (err, responses) => {
* if (err) {
* // some clients did not acknowledge the event in the given delay
* } else {
* console.log(responses); // one response per client
* }
* });
*
* @param timeout
*/
timeout(timeout) {
const flags = Object.assign({}, this.flags, { timeout });
return new BroadcastOperator(this.adapter, this.rooms, this.exceptRooms, flags);
}
/**
* Emits to all clients.
*
* @example
* // the “foo” event will be broadcast to all connected clients
* io.emit("foo", "bar");
*
* // the “foo” event will be broadcast to all connected clients in the “room-101” room
* io.to("room-101").emit("foo", "bar");
*
* // with an acknowledgement expected from all connected clients
* io.timeout(1000).emit("some-event", (err, responses) => {
* if (err) {
* // some clients did not acknowledge the event in the given delay
* } else {
* console.log(responses); // one response per client
* }
* });
*
* @return Always true
*/
emit(ev, ...args) {
if (socket_1.RESERVED_EVENTS.has(ev)) {
throw new Error(`"${String(ev)}" is a reserved event name`);
}
// set up packet object
const data = [ev, ...args];
const packet = {
type: socket_io_parser_1.PacketType.EVENT,
data: data,
};
const withAck = typeof data[data.length - 1] === "function";
if (!withAck) {
this.adapter.broadcast(packet, {
rooms: this.rooms,
except: this.exceptRooms,
flags: this.flags,
});
return true;
}
const ack = data.pop();
let timedOut = false;
let responses = [];
const timer = setTimeout(() => {
timedOut = true;
ack.apply(this, [
new Error("operation has timed out"),
this.flags.expectSingleResponse ? null : responses,
]);
}, this.flags.timeout);
let expectedServerCount = -1;
let actualServerCount = 0;
let expectedClientCount = 0;
const checkCompleteness = () => {
if (!timedOut &&
expectedServerCount === actualServerCount &&
responses.length === expectedClientCount) {
clearTimeout(timer);
ack.apply(this, [
null,
this.flags.expectSingleResponse ? responses[0] : responses,
]);
}
};
this.adapter.broadcastWithAck(packet, {
rooms: this.rooms,
except: this.exceptRooms,
flags: this.flags,
}, (clientCount) => {
// each Socket.IO server in the cluster sends the number of clients that were notified
expectedClientCount += clientCount;
actualServerCount++;
checkCompleteness();
}, (clientResponse) => {
// each client sends an acknowledgement
responses.push(clientResponse);
checkCompleteness();
});
this.adapter.serverCount().then((serverCount) => {
expectedServerCount = serverCount;
checkCompleteness();
});
return true;
}
/**
* Emits an event and waits for an acknowledgement from all clients.
*
* @example
* try {
* const responses = await io.timeout(1000).emitWithAck("some-event");
* console.log(responses); // one response per client
* } catch (e) {
* // some clients did not acknowledge the event in the given delay
* }
*
* @return a Promise that will be fulfilled when all clients have acknowledged the event
*/
emitWithAck(ev, ...args) {
return new Promise((resolve, reject) => {
args.push((err, responses) => {
if (err) {
err.responses = responses;
return reject(err);
}
else {
return resolve(responses);
}
});
this.emit(ev, ...args);
});
}
/**
* Gets a list of clients.
*
* @deprecated this method will be removed in the next major release, please use {@link Server#serverSideEmit} or
* {@link fetchSockets} instead.
*/
allSockets() {
if (!this.adapter) {
throw new Error("No adapter for this namespace, are you trying to get the list of clients of a dynamic namespace?");
}
return this.adapter.sockets(this.rooms);
}
/**
* Returns the matching socket instances. This method works across a cluster of several Socket.IO servers.
*
* Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
*
* @example
* // return all Socket instances
* const sockets = await io.fetchSockets();
*
* // return all Socket instances in the "room1" room
* const sockets = await io.in("room1").fetchSockets();
*
* for (const socket of sockets) {
* console.log(socket.id);
* console.log(socket.handshake);
* console.log(socket.rooms);
* console.log(socket.data);
*
* socket.emit("hello");
* socket.join("room1");
* socket.leave("room2");
* socket.disconnect();
* }
*/
fetchSockets() {
return this.adapter
.fetchSockets({
rooms: this.rooms,
except: this.exceptRooms,
flags: this.flags,
})
.then((sockets) => {
return sockets.map((socket) => {
if (socket instanceof socket_1.Socket) {
// FIXME the TypeScript compiler complains about missing private properties
return socket;
}
else {
return new RemoteSocket(this.adapter, socket);
}
});
});
}
/**
* Makes the matching socket instances join the specified rooms.
*
* Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
*
* @example
*
* // make all socket instances join the "room1" room
* io.socketsJoin("room1");
*
* // make all socket instances in the "room1" room join the "room2" and "room3" rooms
* io.in("room1").socketsJoin(["room2", "room3"]);
*
* @param room - a room, or an array of rooms
*/
socketsJoin(room) {
this.adapter.addSockets({
rooms: this.rooms,
except: this.exceptRooms,
flags: this.flags,
}, Array.isArray(room) ? room : [room]);
}
/**
* Makes the matching socket instances leave the specified rooms.
*
* Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
*
* @example
* // make all socket instances leave the "room1" room
* io.socketsLeave("room1");
*
* // make all socket instances in the "room1" room leave the "room2" and "room3" rooms
* io.in("room1").socketsLeave(["room2", "room3"]);
*
* @param room - a room, or an array of rooms
*/
socketsLeave(room) {
this.adapter.delSockets({
rooms: this.rooms,
except: this.exceptRooms,
flags: this.flags,
}, Array.isArray(room) ? room : [room]);
}
/**
* Makes the matching socket instances disconnect.
*
* Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
*
* @example
* // make all socket instances disconnect (the connections might be kept alive for other namespaces)
* io.disconnectSockets();
*
* // make all socket instances in the "room1" room disconnect and close the underlying connections
* io.in("room1").disconnectSockets(true);
*
* @param close - whether to close the underlying connection
*/
disconnectSockets(close = false) {
this.adapter.disconnectSockets({
rooms: this.rooms,
except: this.exceptRooms,
flags: this.flags,
}, close);
}
}
exports.BroadcastOperator = BroadcastOperator;
/**
* Expose of subset of the attributes and methods of the Socket class
*/
class RemoteSocket {
constructor(adapter, details) {
this.id = details.id;
this.handshake = details.handshake;
this.rooms = new Set(details.rooms);
this.data = details.data;
this.operator = new BroadcastOperator(adapter, new Set([this.id]), new Set(), {
expectSingleResponse: true, // so that remoteSocket.emit() with acknowledgement behaves like socket.emit()
});
}
/**
* Adds a timeout in milliseconds for the next operation.
*
* @example
* const sockets = await io.fetchSockets();
*
* for (const socket of sockets) {
* if (someCondition) {
* socket.timeout(1000).emit("some-event", (err) => {
* if (err) {
* // the client did not acknowledge the event in the given delay
* }
* });
* }
* }
*
* // note: if possible, using a room instead of looping over all sockets is preferable
* io.timeout(1000).to(someConditionRoom).emit("some-event", (err, responses) => {
* // ...
* });
*
* @param timeout
*/
timeout(timeout) {
return this.operator.timeout(timeout);
}
emit(ev, ...args) {
return this.operator.emit(ev, ...args);
}
/**
* Joins a room.
*
* @param {String|Array} room - room or array of rooms
*/
join(room) {
return this.operator.socketsJoin(room);
}
/**
* Leaves a room.
*
* @param {String} room
*/
leave(room) {
return this.operator.socketsLeave(room);
}
/**
* Disconnects this client.
*
* @param {Boolean} close - if `true`, closes the underlying connection
* @return {Socket} self
*/
disconnect(close = false) {
this.operator.disconnectSockets(close);
return this;
}
}
exports.RemoteSocket = RemoteSocket;

268
resources/app/node_modules/socket.io/dist/client.js generated vendored Normal file
View File

@@ -0,0 +1,268 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Client = void 0;
const socket_io_parser_1 = require("socket.io-parser");
const debugModule = require("debug");
const url = require("url");
const debug = debugModule("socket.io:client");
class Client {
/**
* Client constructor.
*
* @param server instance
* @param conn
* @package
*/
constructor(server, conn) {
this.sockets = new Map();
this.nsps = new Map();
this.server = server;
this.conn = conn;
this.encoder = server.encoder;
this.decoder = new server._parser.Decoder();
this.id = conn.id;
this.setup();
}
/**
* @return the reference to the request that originated the Engine.IO connection
*
* @public
*/
get request() {
return this.conn.request;
}
/**
* Sets up event listeners.
*
* @private
*/
setup() {
this.onclose = this.onclose.bind(this);
this.ondata = this.ondata.bind(this);
this.onerror = this.onerror.bind(this);
this.ondecoded = this.ondecoded.bind(this);
// @ts-ignore
this.decoder.on("decoded", this.ondecoded);
this.conn.on("data", this.ondata);
this.conn.on("error", this.onerror);
this.conn.on("close", this.onclose);
this.connectTimeout = setTimeout(() => {
if (this.nsps.size === 0) {
debug("no namespace joined yet, close the client");
this.close();
}
else {
debug("the client has already joined a namespace, nothing to do");
}
}, this.server._connectTimeout);
}
/**
* Connects a client to a namespace.
*
* @param {String} name - the namespace
* @param {Object} auth - the auth parameters
* @private
*/
connect(name, auth = {}) {
if (this.server._nsps.has(name)) {
debug("connecting to namespace %s", name);
return this.doConnect(name, auth);
}
this.server._checkNamespace(name, auth, (dynamicNspName) => {
if (dynamicNspName) {
this.doConnect(name, auth);
}
else {
debug("creation of namespace %s was denied", name);
this._packet({
type: socket_io_parser_1.PacketType.CONNECT_ERROR,
nsp: name,
data: {
message: "Invalid namespace",
},
});
}
});
}
/**
* Connects a client to a namespace.
*
* @param name - the namespace
* @param {Object} auth - the auth parameters
*
* @private
*/
doConnect(name, auth) {
const nsp = this.server.of(name);
nsp._add(this, auth, (socket) => {
this.sockets.set(socket.id, socket);
this.nsps.set(nsp.name, socket);
if (this.connectTimeout) {
clearTimeout(this.connectTimeout);
this.connectTimeout = undefined;
}
});
}
/**
* Disconnects from all namespaces and closes transport.
*
* @private
*/
_disconnect() {
for (const socket of this.sockets.values()) {
socket.disconnect();
}
this.sockets.clear();
this.close();
}
/**
* Removes a socket. Called by each `Socket`.
*
* @private
*/
_remove(socket) {
if (this.sockets.has(socket.id)) {
const nsp = this.sockets.get(socket.id).nsp.name;
this.sockets.delete(socket.id);
this.nsps.delete(nsp);
}
else {
debug("ignoring remove for %s", socket.id);
}
}
/**
* Closes the underlying connection.
*
* @private
*/
close() {
if ("open" === this.conn.readyState) {
debug("forcing transport close");
this.conn.close();
this.onclose("forced server close");
}
}
/**
* Writes a packet to the transport.
*
* @param {Object} packet object
* @param {Object} opts
* @private
*/
_packet(packet, opts = {}) {
if (this.conn.readyState !== "open") {
debug("ignoring packet write %j", packet);
return;
}
const encodedPackets = opts.preEncoded
? packet // previous versions of the adapter incorrectly used socket.packet() instead of writeToEngine()
: this.encoder.encode(packet);
this.writeToEngine(encodedPackets, opts);
}
writeToEngine(encodedPackets, opts) {
if (opts.volatile && !this.conn.transport.writable) {
debug("volatile packet is discarded since the transport is not currently writable");
return;
}
const packets = Array.isArray(encodedPackets)
? encodedPackets
: [encodedPackets];
for (const encodedPacket of packets) {
this.conn.write(encodedPacket, opts);
}
}
/**
* Called with incoming transport data.
*
* @private
*/
ondata(data) {
// try/catch is needed for protocol violations (GH-1880)
try {
this.decoder.add(data);
}
catch (e) {
debug("invalid packet format");
this.onerror(e);
}
}
/**
* Called when parser fully decodes a packet.
*
* @private
*/
ondecoded(packet) {
let namespace;
let authPayload;
if (this.conn.protocol === 3) {
const parsed = url.parse(packet.nsp, true);
namespace = parsed.pathname;
authPayload = parsed.query;
}
else {
namespace = packet.nsp;
authPayload = packet.data;
}
const socket = this.nsps.get(namespace);
if (!socket && packet.type === socket_io_parser_1.PacketType.CONNECT) {
this.connect(namespace, authPayload);
}
else if (socket &&
packet.type !== socket_io_parser_1.PacketType.CONNECT &&
packet.type !== socket_io_parser_1.PacketType.CONNECT_ERROR) {
process.nextTick(function () {
socket._onpacket(packet);
});
}
else {
debug("invalid state (packet type: %s)", packet.type);
this.close();
}
}
/**
* Handles an error.
*
* @param {Object} err object
* @private
*/
onerror(err) {
for (const socket of this.sockets.values()) {
socket._onerror(err);
}
this.conn.close();
}
/**
* Called upon transport close.
*
* @param reason
* @param description
* @private
*/
onclose(reason, description) {
debug("client close with reason %s", reason);
// ignore a potential subsequent `close` event
this.destroy();
// `nsps` and `sockets` are cleaned up seamlessly
for (const socket of this.sockets.values()) {
socket._onclose(reason, description);
}
this.sockets.clear();
this.decoder.destroy(); // clean up decoder
}
/**
* Cleans up event listeners.
* @private
*/
destroy() {
this.conn.removeListener("data", this.ondata);
this.conn.removeListener("error", this.onerror);
this.conn.removeListener("close", this.onclose);
// @ts-ignore
this.decoder.removeListener("decoded", this.ondecoded);
if (this.connectTimeout) {
clearTimeout(this.connectTimeout);
this.connectTimeout = undefined;
}
}
}
exports.Client = Client;

803
resources/app/node_modules/socket.io/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,803 @@
"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;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Namespace = exports.Socket = exports.Server = void 0;
const http = require("http");
const fs_1 = require("fs");
const zlib_1 = require("zlib");
const accepts = require("accepts");
const stream_1 = require("stream");
const path = require("path");
const engine_io_1 = require("engine.io");
const client_1 = require("./client");
const events_1 = require("events");
const namespace_1 = require("./namespace");
Object.defineProperty(exports, "Namespace", { enumerable: true, get: function () { return namespace_1.Namespace; } });
const parent_namespace_1 = require("./parent-namespace");
const socket_io_adapter_1 = require("socket.io-adapter");
const parser = __importStar(require("socket.io-parser"));
const debug_1 = __importDefault(require("debug"));
const socket_1 = require("./socket");
Object.defineProperty(exports, "Socket", { enumerable: true, get: function () { return socket_1.Socket; } });
const typed_events_1 = require("./typed-events");
const uws_1 = require("./uws");
const cors_1 = __importDefault(require("cors"));
const debug = (0, debug_1.default)("socket.io:server");
const clientVersion = require("../package.json").version;
const dotMapRegex = /\.map/;
/**
* Represents a Socket.IO server.
*
* @example
* import { Server } from "socket.io";
*
* const io = new Server();
*
* io.on("connection", (socket) => {
* console.log(`socket ${socket.id} connected`);
*
* // send an event to the client
* socket.emit("foo", "bar");
*
* socket.on("foobar", () => {
* // an event was received from the client
* });
*
* // upon disconnection
* socket.on("disconnect", (reason) => {
* console.log(`socket ${socket.id} disconnected due to ${reason}`);
* });
* });
*
* io.listen(3000);
*/
class Server extends typed_events_1.StrictEventEmitter {
constructor(srv, opts = {}) {
super();
/**
* @private
*/
this._nsps = new Map();
this.parentNsps = new Map();
/**
* A subset of the {@link parentNsps} map, only containing {@link ParentNamespace} which are based on a regular
* expression.
*
* @private
*/
this.parentNamespacesFromRegExp = new Map();
if ("object" === typeof srv &&
srv instanceof Object &&
!srv.listen) {
opts = srv;
srv = undefined;
}
this.path(opts.path || "/socket.io");
this.connectTimeout(opts.connectTimeout || 45000);
this.serveClient(false !== opts.serveClient);
this._parser = opts.parser || parser;
this.encoder = new this._parser.Encoder();
this.opts = opts;
if (opts.connectionStateRecovery) {
opts.connectionStateRecovery = Object.assign({
maxDisconnectionDuration: 2 * 60 * 1000,
skipMiddlewares: true,
}, opts.connectionStateRecovery);
this.adapter(opts.adapter || socket_io_adapter_1.SessionAwareAdapter);
}
else {
this.adapter(opts.adapter || socket_io_adapter_1.Adapter);
}
opts.cleanupEmptyChildNamespaces = !!opts.cleanupEmptyChildNamespaces;
this.sockets = this.of("/");
if (srv || typeof srv == "number")
this.attach(srv);
if (this.opts.cors) {
this._corsMiddleware = (0, cors_1.default)(this.opts.cors);
}
}
get _opts() {
return this.opts;
}
serveClient(v) {
if (!arguments.length)
return this._serveClient;
this._serveClient = v;
return this;
}
/**
* Executes the middleware for an incoming namespace not already created on the server.
*
* @param name - name of incoming namespace
* @param auth - the auth parameters
* @param fn - callback
*
* @private
*/
_checkNamespace(name, auth, fn) {
if (this.parentNsps.size === 0)
return fn(false);
const keysIterator = this.parentNsps.keys();
const run = () => {
const nextFn = keysIterator.next();
if (nextFn.done) {
return fn(false);
}
nextFn.value(name, auth, (err, allow) => {
if (err || !allow) {
return run();
}
if (this._nsps.has(name)) {
// the namespace was created in the meantime
debug("dynamic namespace %s already exists", name);
return fn(this._nsps.get(name));
}
const namespace = this.parentNsps.get(nextFn.value).createChild(name);
debug("dynamic namespace %s was created", name);
fn(namespace);
});
};
run();
}
path(v) {
if (!arguments.length)
return this._path;
this._path = v.replace(/\/$/, "");
const escapedPath = this._path.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
this.clientPathRegex = new RegExp("^" +
escapedPath +
"/socket\\.io(\\.msgpack|\\.esm)?(\\.min)?\\.js(\\.map)?(?:\\?|$)");
return this;
}
connectTimeout(v) {
if (v === undefined)
return this._connectTimeout;
this._connectTimeout = v;
return this;
}
adapter(v) {
if (!arguments.length)
return this._adapter;
this._adapter = v;
for (const nsp of this._nsps.values()) {
nsp._initAdapter();
}
return this;
}
/**
* Attaches socket.io to a server or port.
*
* @param srv - server or port
* @param opts - options passed to engine.io
* @return self
*/
listen(srv, opts = {}) {
return this.attach(srv, opts);
}
/**
* Attaches socket.io to a server or port.
*
* @param srv - server or port
* @param opts - options passed to engine.io
* @return self
*/
attach(srv, opts = {}) {
if ("function" == typeof srv) {
const msg = "You are trying to attach socket.io to an express " +
"request handler function. Please pass a http.Server instance.";
throw new Error(msg);
}
// handle a port as a string
if (Number(srv) == srv) {
srv = Number(srv);
}
if ("number" == typeof srv) {
debug("creating http server and binding to %d", srv);
const port = srv;
srv = http.createServer((req, res) => {
res.writeHead(404);
res.end();
});
srv.listen(port);
}
// merge the options passed to the Socket.IO server
Object.assign(opts, this.opts);
// set engine.io path to `/socket.io`
opts.path = opts.path || this._path;
this.initEngine(srv, opts);
return this;
}
attachApp(app /*: TemplatedApp */, opts = {}) {
// merge the options passed to the Socket.IO server
Object.assign(opts, this.opts);
// set engine.io path to `/socket.io`
opts.path = opts.path || this._path;
// initialize engine
debug("creating uWebSockets.js-based engine with opts %j", opts);
const engine = new engine_io_1.uServer(opts);
engine.attach(app, opts);
// bind to engine events
this.bind(engine);
if (this._serveClient) {
// attach static file serving
app.get(`${this._path}/*`, (res, req) => {
if (!this.clientPathRegex.test(req.getUrl())) {
req.setYield(true);
return;
}
const filename = req
.getUrl()
.replace(this._path, "")
.replace(/\?.*$/, "")
.replace(/^\//, "");
const isMap = dotMapRegex.test(filename);
const type = isMap ? "map" : "source";
// Per the standard, ETags must be quoted:
// https://tools.ietf.org/html/rfc7232#section-2.3
const expectedEtag = '"' + clientVersion + '"';
const weakEtag = "W/" + expectedEtag;
const etag = req.getHeader("if-none-match");
if (etag) {
if (expectedEtag === etag || weakEtag === etag) {
debug("serve client %s 304", type);
res.writeStatus("304 Not Modified");
res.end();
return;
}
}
debug("serve client %s", type);
res.writeHeader("cache-control", "public, max-age=0");
res.writeHeader("content-type", "application/" + (isMap ? "json" : "javascript") + "; charset=utf-8");
res.writeHeader("etag", expectedEtag);
const filepath = path.join(__dirname, "../client-dist/", filename);
(0, uws_1.serveFile)(res, filepath);
});
}
(0, uws_1.patchAdapter)(app);
}
/**
* Initialize engine
*
* @param srv - the server to attach to
* @param opts - options passed to engine.io
* @private
*/
initEngine(srv, opts) {
// initialize engine
debug("creating engine.io instance with opts %j", opts);
this.eio = (0, engine_io_1.attach)(srv, opts);
// attach static file serving
if (this._serveClient)
this.attachServe(srv);
// Export http server
this.httpServer = srv;
// bind to engine events
this.bind(this.eio);
}
/**
* Attaches the static file serving.
*
* @param srv http server
* @private
*/
attachServe(srv) {
debug("attaching client serving req handler");
const evs = srv.listeners("request").slice(0);
srv.removeAllListeners("request");
srv.on("request", (req, res) => {
if (this.clientPathRegex.test(req.url)) {
if (this._corsMiddleware) {
this._corsMiddleware(req, res, () => {
this.serve(req, res);
});
}
else {
this.serve(req, res);
}
}
else {
for (let i = 0; i < evs.length; i++) {
evs[i].call(srv, req, res);
}
}
});
}
/**
* Handles a request serving of client source and map
*
* @param req
* @param res
* @private
*/
serve(req, res) {
const filename = req.url.replace(this._path, "").replace(/\?.*$/, "");
const isMap = dotMapRegex.test(filename);
const type = isMap ? "map" : "source";
// Per the standard, ETags must be quoted:
// https://tools.ietf.org/html/rfc7232#section-2.3
const expectedEtag = '"' + clientVersion + '"';
const weakEtag = "W/" + expectedEtag;
const etag = req.headers["if-none-match"];
if (etag) {
if (expectedEtag === etag || weakEtag === etag) {
debug("serve client %s 304", type);
res.writeHead(304);
res.end();
return;
}
}
debug("serve client %s", type);
res.setHeader("Cache-Control", "public, max-age=0");
res.setHeader("Content-Type", "application/" + (isMap ? "json" : "javascript") + "; charset=utf-8");
res.setHeader("ETag", expectedEtag);
Server.sendFile(filename, req, res);
}
/**
* @param filename
* @param req
* @param res
* @private
*/
static sendFile(filename, req, res) {
const readStream = (0, fs_1.createReadStream)(path.join(__dirname, "../client-dist/", filename));
const encoding = accepts(req).encodings(["br", "gzip", "deflate"]);
const onError = (err) => {
if (err) {
res.end();
}
};
switch (encoding) {
case "br":
res.writeHead(200, { "content-encoding": "br" });
(0, stream_1.pipeline)(readStream, (0, zlib_1.createBrotliCompress)(), res, onError);
break;
case "gzip":
res.writeHead(200, { "content-encoding": "gzip" });
(0, stream_1.pipeline)(readStream, (0, zlib_1.createGzip)(), res, onError);
break;
case "deflate":
res.writeHead(200, { "content-encoding": "deflate" });
(0, stream_1.pipeline)(readStream, (0, zlib_1.createDeflate)(), res, onError);
break;
default:
res.writeHead(200);
(0, stream_1.pipeline)(readStream, res, onError);
}
}
/**
* Binds socket.io to an engine.io instance.
*
* @param engine engine.io (or compatible) server
* @return self
*/
bind(engine) {
this.engine = engine;
this.engine.on("connection", this.onconnection.bind(this));
return this;
}
/**
* Called with each incoming transport connection.
*
* @param {engine.Socket} conn
* @return self
* @private
*/
onconnection(conn) {
debug("incoming connection with id %s", conn.id);
const client = new client_1.Client(this, conn);
if (conn.protocol === 3) {
// @ts-ignore
client.connect("/");
}
return this;
}
/**
* Looks up a namespace.
*
* @example
* // with a simple string
* const myNamespace = io.of("/my-namespace");
*
* // with a regex
* const dynamicNsp = io.of(/^\/dynamic-\d+$/).on("connection", (socket) => {
* const namespace = socket.nsp; // newNamespace.name === "/dynamic-101"
*
* // broadcast to all clients in the given sub-namespace
* namespace.emit("hello");
* });
*
* @param name - nsp name
* @param fn optional, nsp `connection` ev handler
*/
of(name, fn) {
if (typeof name === "function" || name instanceof RegExp) {
const parentNsp = new parent_namespace_1.ParentNamespace(this);
debug("initializing parent namespace %s", parentNsp.name);
if (typeof name === "function") {
this.parentNsps.set(name, parentNsp);
}
else {
this.parentNsps.set((nsp, conn, next) => next(null, name.test(nsp)), parentNsp);
this.parentNamespacesFromRegExp.set(name, parentNsp);
}
if (fn) {
// @ts-ignore
parentNsp.on("connect", fn);
}
return parentNsp;
}
if (String(name)[0] !== "/")
name = "/" + name;
let nsp = this._nsps.get(name);
if (!nsp) {
for (const [regex, parentNamespace] of this.parentNamespacesFromRegExp) {
if (regex.test(name)) {
debug("attaching namespace %s to parent namespace %s", name, regex);
return parentNamespace.createChild(name);
}
}
debug("initializing namespace %s", name);
nsp = new namespace_1.Namespace(this, name);
this._nsps.set(name, nsp);
if (name !== "/") {
// @ts-ignore
this.sockets.emitReserved("new_namespace", nsp);
}
}
if (fn)
nsp.on("connect", fn);
return nsp;
}
/**
* Closes server connection
*
* @param [fn] optional, called as `fn([err])` on error OR all conns closed
*/
close(fn) {
this._nsps.forEach((nsp) => {
nsp.sockets.forEach((socket) => {
socket._onclose("server shutting down");
});
nsp.adapter.close();
});
this.engine.close();
// restore the Adapter prototype, when the Socket.IO server was attached to a uWebSockets.js server
(0, uws_1.restoreAdapter)();
if (this.httpServer) {
this.httpServer.close(fn);
}
else {
fn && fn();
}
}
/**
* Registers a middleware, which is a function that gets executed for every incoming {@link Socket}.
*
* @example
* io.use((socket, next) => {
* // ...
* next();
* });
*
* @param fn - the middleware function
*/
use(fn) {
this.sockets.use(fn);
return this;
}
/**
* Targets a room when emitting.
*
* @example
* // the “foo” event will be broadcast to all connected clients in the “room-101” room
* io.to("room-101").emit("foo", "bar");
*
* // with an array of rooms (a client will be notified at most once)
* io.to(["room-101", "room-102"]).emit("foo", "bar");
*
* // with multiple chained calls
* io.to("room-101").to("room-102").emit("foo", "bar");
*
* @param room - a room, or an array of rooms
* @return a new {@link BroadcastOperator} instance for chaining
*/
to(room) {
return this.sockets.to(room);
}
/**
* Targets a room when emitting. Similar to `to()`, but might feel clearer in some cases:
*
* @example
* // disconnect all clients in the "room-101" room
* io.in("room-101").disconnectSockets();
*
* @param room - a room, or an array of rooms
* @return a new {@link BroadcastOperator} instance for chaining
*/
in(room) {
return this.sockets.in(room);
}
/**
* Excludes a room when emitting.
*
* @example
* // the "foo" event will be broadcast to all connected clients, except the ones that are in the "room-101" room
* io.except("room-101").emit("foo", "bar");
*
* // with an array of rooms
* io.except(["room-101", "room-102"]).emit("foo", "bar");
*
* // with multiple chained calls
* io.except("room-101").except("room-102").emit("foo", "bar");
*
* @param room - a room, or an array of rooms
* @return a new {@link BroadcastOperator} instance for chaining
*/
except(room) {
return this.sockets.except(room);
}
/**
* Sends a `message` event to all clients.
*
* This method mimics the WebSocket.send() method.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
*
* @example
* io.send("hello");
*
* // this is equivalent to
* io.emit("message", "hello");
*
* @return self
*/
send(...args) {
// This type-cast is needed because EmitEvents likely doesn't have `message` as a key.
// if you specify the EmitEvents, the type of args will be never.
this.sockets.emit("message", ...args);
return this;
}
/**
* Sends a `message` event to all clients. Alias of {@link send}.
*
* @return self
*/
write(...args) {
// This type-cast is needed because EmitEvents likely doesn't have `message` as a key.
// if you specify the EmitEvents, the type of args will be never.
this.sockets.emit("message", ...args);
return this;
}
/**
* Sends a message to the other Socket.IO servers of the cluster.
*
* @example
* io.serverSideEmit("hello", "world");
*
* io.on("hello", (arg1) => {
* console.log(arg1); // prints "world"
* });
*
* // acknowledgements (without binary content) are supported too:
* io.serverSideEmit("ping", (err, responses) => {
* if (err) {
* // some servers did not acknowledge the event in the given delay
* } else {
* console.log(responses); // one response per server (except the current one)
* }
* });
*
* io.on("ping", (cb) => {
* cb("pong");
* });
*
* @param ev - the event name
* @param args - an array of arguments, which may include an acknowledgement callback at the end
*/
serverSideEmit(ev, ...args) {
return this.sockets.serverSideEmit(ev, ...args);
}
/**
* Sends a message and expect an acknowledgement from the other Socket.IO servers of the cluster.
*
* @example
* try {
* const responses = await io.serverSideEmitWithAck("ping");
* console.log(responses); // one response per server (except the current one)
* } catch (e) {
* // some servers did not acknowledge the event in the given delay
* }
*
* @param ev - the event name
* @param args - an array of arguments
*
* @return a Promise that will be fulfilled when all servers have acknowledged the event
*/
serverSideEmitWithAck(ev, ...args) {
return this.sockets.serverSideEmitWithAck(ev, ...args);
}
/**
* Gets a list of socket ids.
*
* @deprecated this method will be removed in the next major release, please use {@link Server#serverSideEmit} or
* {@link Server#fetchSockets} instead.
*/
allSockets() {
return this.sockets.allSockets();
}
/**
* Sets the compress flag.
*
* @example
* io.compress(false).emit("hello");
*
* @param compress - if `true`, compresses the sending data
* @return a new {@link BroadcastOperator} instance for chaining
*/
compress(compress) {
return this.sockets.compress(compress);
}
/**
* Sets a modifier for a subsequent event emission that the event data may be lost if the client is not ready to
* receive messages (because of network slowness or other issues, or because theyre connected through long polling
* and is in the middle of a request-response cycle).
*
* @example
* io.volatile.emit("hello"); // the clients may or may not receive it
*
* @return a new {@link BroadcastOperator} instance for chaining
*/
get volatile() {
return this.sockets.volatile;
}
/**
* Sets a modifier for a subsequent event emission that the event data will only be broadcast to the current node.
*
* @example
* // the “foo” event will be broadcast to all connected clients on this node
* io.local.emit("foo", "bar");
*
* @return a new {@link BroadcastOperator} instance for chaining
*/
get local() {
return this.sockets.local;
}
/**
* Adds a timeout in milliseconds for the next operation.
*
* @example
* io.timeout(1000).emit("some-event", (err, responses) => {
* if (err) {
* // some clients did not acknowledge the event in the given delay
* } else {
* console.log(responses); // one response per client
* }
* });
*
* @param timeout
*/
timeout(timeout) {
return this.sockets.timeout(timeout);
}
/**
* Returns the matching socket instances.
*
* Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
*
* @example
* // return all Socket instances
* const sockets = await io.fetchSockets();
*
* // return all Socket instances in the "room1" room
* const sockets = await io.in("room1").fetchSockets();
*
* for (const socket of sockets) {
* console.log(socket.id);
* console.log(socket.handshake);
* console.log(socket.rooms);
* console.log(socket.data);
*
* socket.emit("hello");
* socket.join("room1");
* socket.leave("room2");
* socket.disconnect();
* }
*/
fetchSockets() {
return this.sockets.fetchSockets();
}
/**
* Makes the matching socket instances join the specified rooms.
*
* Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
*
* @example
*
* // make all socket instances join the "room1" room
* io.socketsJoin("room1");
*
* // make all socket instances in the "room1" room join the "room2" and "room3" rooms
* io.in("room1").socketsJoin(["room2", "room3"]);
*
* @param room - a room, or an array of rooms
*/
socketsJoin(room) {
return this.sockets.socketsJoin(room);
}
/**
* Makes the matching socket instances leave the specified rooms.
*
* Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
*
* @example
* // make all socket instances leave the "room1" room
* io.socketsLeave("room1");
*
* // make all socket instances in the "room1" room leave the "room2" and "room3" rooms
* io.in("room1").socketsLeave(["room2", "room3"]);
*
* @param room - a room, or an array of rooms
*/
socketsLeave(room) {
return this.sockets.socketsLeave(room);
}
/**
* Makes the matching socket instances disconnect.
*
* Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
*
* @example
* // make all socket instances disconnect (the connections might be kept alive for other namespaces)
* io.disconnectSockets();
*
* // make all socket instances in the "room1" room disconnect and close the underlying connections
* io.in("room1").disconnectSockets(true);
*
* @param close - whether to close the underlying connection
*/
disconnectSockets(close = false) {
return this.sockets.disconnectSockets(close);
}
}
exports.Server = Server;
/**
* Expose main namespace (/).
*/
const emitterMethods = Object.keys(events_1.EventEmitter.prototype).filter(function (key) {
return typeof events_1.EventEmitter.prototype[key] === "function";
});
emitterMethods.forEach(function (fn) {
Server.prototype[fn] = function () {
return this.sockets[fn].apply(this.sockets, arguments);
};
});
module.exports = (srv, opts) => new Server(srv, opts);
module.exports.Server = Server;
module.exports.Namespace = namespace_1.Namespace;
module.exports.Socket = socket_1.Socket;
var socket_2 = require("./socket");

579
resources/app/node_modules/socket.io/dist/namespace.js generated vendored Normal file
View File

@@ -0,0 +1,579 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Namespace = exports.RESERVED_EVENTS = void 0;
const socket_1 = require("./socket");
const typed_events_1 = require("./typed-events");
const debug_1 = __importDefault(require("debug"));
const broadcast_operator_1 = require("./broadcast-operator");
const debug = (0, debug_1.default)("socket.io:namespace");
exports.RESERVED_EVENTS = new Set(["connect", "connection", "new_namespace"]);
/**
* A Namespace is a communication channel that allows you to split the logic of your application over a single shared
* connection.
*
* Each namespace has its own:
*
* - event handlers
*
* ```
* io.of("/orders").on("connection", (socket) => {
* socket.on("order:list", () => {});
* socket.on("order:create", () => {});
* });
*
* io.of("/users").on("connection", (socket) => {
* socket.on("user:list", () => {});
* });
* ```
*
* - rooms
*
* ```
* const orderNamespace = io.of("/orders");
*
* orderNamespace.on("connection", (socket) => {
* socket.join("room1");
* orderNamespace.to("room1").emit("hello");
* });
*
* const userNamespace = io.of("/users");
*
* userNamespace.on("connection", (socket) => {
* socket.join("room1"); // distinct from the room in the "orders" namespace
* userNamespace.to("room1").emit("holà");
* });
* ```
*
* - middlewares
*
* ```
* const orderNamespace = io.of("/orders");
*
* orderNamespace.use((socket, next) => {
* // ensure the socket has access to the "orders" namespace
* });
*
* const userNamespace = io.of("/users");
*
* userNamespace.use((socket, next) => {
* // ensure the socket has access to the "users" namespace
* });
* ```
*/
class Namespace extends typed_events_1.StrictEventEmitter {
/**
* Namespace constructor.
*
* @param server instance
* @param name
*/
constructor(server, name) {
super();
this.sockets = new Map();
/** @private */
this._fns = [];
/** @private */
this._ids = 0;
this.server = server;
this.name = name;
this._initAdapter();
}
/**
* Initializes the `Adapter` for this nsp.
* Run upon changing adapter by `Server#adapter`
* in addition to the constructor.
*
* @private
*/
_initAdapter() {
// @ts-ignore
this.adapter = new (this.server.adapter())(this);
}
/**
* Registers a middleware, which is a function that gets executed for every incoming {@link Socket}.
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* myNamespace.use((socket, next) => {
* // ...
* next();
* });
*
* @param fn - the middleware function
*/
use(fn) {
this._fns.push(fn);
return this;
}
/**
* Executes the middleware for an incoming client.
*
* @param socket - the socket that will get added
* @param fn - last fn call in the middleware
* @private
*/
run(socket, fn) {
const fns = this._fns.slice(0);
if (!fns.length)
return fn(null);
function run(i) {
fns[i](socket, function (err) {
// upon error, short-circuit
if (err)
return fn(err);
// if no middleware left, summon callback
if (!fns[i + 1])
return fn(null);
// go on to next
run(i + 1);
});
}
run(0);
}
/**
* Targets a room when emitting.
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* // the “foo” event will be broadcast to all connected clients in the “room-101” room
* myNamespace.to("room-101").emit("foo", "bar");
*
* // with an array of rooms (a client will be notified at most once)
* myNamespace.to(["room-101", "room-102"]).emit("foo", "bar");
*
* // with multiple chained calls
* myNamespace.to("room-101").to("room-102").emit("foo", "bar");
*
* @param room - a room, or an array of rooms
* @return a new {@link BroadcastOperator} instance for chaining
*/
to(room) {
return new broadcast_operator_1.BroadcastOperator(this.adapter).to(room);
}
/**
* Targets a room when emitting. Similar to `to()`, but might feel clearer in some cases:
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* // disconnect all clients in the "room-101" room
* myNamespace.in("room-101").disconnectSockets();
*
* @param room - a room, or an array of rooms
* @return a new {@link BroadcastOperator} instance for chaining
*/
in(room) {
return new broadcast_operator_1.BroadcastOperator(this.adapter).in(room);
}
/**
* Excludes a room when emitting.
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* // the "foo" event will be broadcast to all connected clients, except the ones that are in the "room-101" room
* myNamespace.except("room-101").emit("foo", "bar");
*
* // with an array of rooms
* myNamespace.except(["room-101", "room-102"]).emit("foo", "bar");
*
* // with multiple chained calls
* myNamespace.except("room-101").except("room-102").emit("foo", "bar");
*
* @param room - a room, or an array of rooms
* @return a new {@link BroadcastOperator} instance for chaining
*/
except(room) {
return new broadcast_operator_1.BroadcastOperator(this.adapter).except(room);
}
/**
* Adds a new client.
*
* @return {Socket}
* @private
*/
async _add(client, auth, fn) {
var _a;
debug("adding socket to nsp %s", this.name);
const socket = await this._createSocket(client, auth);
if (
// @ts-ignore
((_a = this.server.opts.connectionStateRecovery) === null || _a === void 0 ? void 0 : _a.skipMiddlewares) &&
socket.recovered &&
client.conn.readyState === "open") {
return this._doConnect(socket, fn);
}
this.run(socket, (err) => {
process.nextTick(() => {
if ("open" !== client.conn.readyState) {
debug("next called after client was closed - ignoring socket");
socket._cleanup();
return;
}
if (err) {
debug("middleware error, sending CONNECT_ERROR packet to the client");
socket._cleanup();
if (client.conn.protocol === 3) {
return socket._error(err.data || err.message);
}
else {
return socket._error({
message: err.message,
data: err.data,
});
}
}
this._doConnect(socket, fn);
});
});
}
async _createSocket(client, auth) {
const sessionId = auth.pid;
const offset = auth.offset;
if (
// @ts-ignore
this.server.opts.connectionStateRecovery &&
typeof sessionId === "string" &&
typeof offset === "string") {
let session;
try {
session = await this.adapter.restoreSession(sessionId, offset);
}
catch (e) {
debug("error while restoring session: %s", e);
}
if (session) {
debug("connection state recovered for sid %s", session.sid);
return new socket_1.Socket(this, client, auth, session);
}
}
return new socket_1.Socket(this, client, auth);
}
_doConnect(socket, fn) {
// track socket
this.sockets.set(socket.id, socket);
// it's paramount that the internal `onconnect` logic
// fires before user-set events to prevent state order
// violations (such as a disconnection before the connection
// logic is complete)
socket._onconnect();
if (fn)
fn(socket);
// fire user-set events
this.emitReserved("connect", socket);
this.emitReserved("connection", socket);
}
/**
* Removes a client. Called by each `Socket`.
*
* @private
*/
_remove(socket) {
if (this.sockets.has(socket.id)) {
this.sockets.delete(socket.id);
}
else {
debug("ignoring remove for %s", socket.id);
}
}
/**
* Emits to all connected clients.
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* myNamespace.emit("hello", "world");
*
* // all serializable datastructures are supported (no need to call JSON.stringify)
* myNamespace.emit("hello", 1, "2", { 3: ["4"], 5: Uint8Array.from([6]) });
*
* // with an acknowledgement from the clients
* myNamespace.timeout(1000).emit("some-event", (err, responses) => {
* if (err) {
* // some clients did not acknowledge the event in the given delay
* } else {
* console.log(responses); // one response per client
* }
* });
*
* @return Always true
*/
emit(ev, ...args) {
return new broadcast_operator_1.BroadcastOperator(this.adapter).emit(ev, ...args);
}
/**
* Sends a `message` event to all clients.
*
* This method mimics the WebSocket.send() method.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* myNamespace.send("hello");
*
* // this is equivalent to
* myNamespace.emit("message", "hello");
*
* @return self
*/
send(...args) {
// This type-cast is needed because EmitEvents likely doesn't have `message` as a key.
// if you specify the EmitEvents, the type of args will be never.
this.emit("message", ...args);
return this;
}
/**
* Sends a `message` event to all clients. Sends a `message` event. Alias of {@link send}.
*
* @return self
*/
write(...args) {
// This type-cast is needed because EmitEvents likely doesn't have `message` as a key.
// if you specify the EmitEvents, the type of args will be never.
this.emit("message", ...args);
return this;
}
/**
* Sends a message to the other Socket.IO servers of the cluster.
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* myNamespace.serverSideEmit("hello", "world");
*
* myNamespace.on("hello", (arg1) => {
* console.log(arg1); // prints "world"
* });
*
* // acknowledgements (without binary content) are supported too:
* myNamespace.serverSideEmit("ping", (err, responses) => {
* if (err) {
* // some servers did not acknowledge the event in the given delay
* } else {
* console.log(responses); // one response per server (except the current one)
* }
* });
*
* myNamespace.on("ping", (cb) => {
* cb("pong");
* });
*
* @param ev - the event name
* @param args - an array of arguments, which may include an acknowledgement callback at the end
*/
serverSideEmit(ev, ...args) {
if (exports.RESERVED_EVENTS.has(ev)) {
throw new Error(`"${String(ev)}" is a reserved event name`);
}
args.unshift(ev);
this.adapter.serverSideEmit(args);
return true;
}
/**
* Sends a message and expect an acknowledgement from the other Socket.IO servers of the cluster.
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* try {
* const responses = await myNamespace.serverSideEmitWithAck("ping");
* console.log(responses); // one response per server (except the current one)
* } catch (e) {
* // some servers did not acknowledge the event in the given delay
* }
*
* @param ev - the event name
* @param args - an array of arguments
*
* @return a Promise that will be fulfilled when all servers have acknowledged the event
*/
serverSideEmitWithAck(ev, ...args) {
return new Promise((resolve, reject) => {
args.push((err, responses) => {
if (err) {
err.responses = responses;
return reject(err);
}
else {
return resolve(responses);
}
});
this.serverSideEmit(ev, ...args);
});
}
/**
* Called when a packet is received from another Socket.IO server
*
* @param args - an array of arguments, which may include an acknowledgement callback at the end
*
* @private
*/
_onServerSideEmit(args) {
super.emitUntyped.apply(this, args);
}
/**
* Gets a list of clients.
*
* @deprecated this method will be removed in the next major release, please use {@link Namespace#serverSideEmit} or
* {@link Namespace#fetchSockets} instead.
*/
allSockets() {
return new broadcast_operator_1.BroadcastOperator(this.adapter).allSockets();
}
/**
* Sets the compress flag.
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* myNamespace.compress(false).emit("hello");
*
* @param compress - if `true`, compresses the sending data
* @return self
*/
compress(compress) {
return new broadcast_operator_1.BroadcastOperator(this.adapter).compress(compress);
}
/**
* Sets a modifier for a subsequent event emission that the event data may be lost if the client is not ready to
* receive messages (because of network slowness or other issues, or because theyre connected through long polling
* and is in the middle of a request-response cycle).
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* myNamespace.volatile.emit("hello"); // the clients may or may not receive it
*
* @return self
*/
get volatile() {
return new broadcast_operator_1.BroadcastOperator(this.adapter).volatile;
}
/**
* Sets a modifier for a subsequent event emission that the event data will only be broadcast to the current node.
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* // the “foo” event will be broadcast to all connected clients on this node
* myNamespace.local.emit("foo", "bar");
*
* @return a new {@link BroadcastOperator} instance for chaining
*/
get local() {
return new broadcast_operator_1.BroadcastOperator(this.adapter).local;
}
/**
* Adds a timeout in milliseconds for the next operation.
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* myNamespace.timeout(1000).emit("some-event", (err, responses) => {
* if (err) {
* // some clients did not acknowledge the event in the given delay
* } else {
* console.log(responses); // one response per client
* }
* });
*
* @param timeout
*/
timeout(timeout) {
return new broadcast_operator_1.BroadcastOperator(this.adapter).timeout(timeout);
}
/**
* Returns the matching socket instances.
*
* Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* // return all Socket instances
* const sockets = await myNamespace.fetchSockets();
*
* // return all Socket instances in the "room1" room
* const sockets = await myNamespace.in("room1").fetchSockets();
*
* for (const socket of sockets) {
* console.log(socket.id);
* console.log(socket.handshake);
* console.log(socket.rooms);
* console.log(socket.data);
*
* socket.emit("hello");
* socket.join("room1");
* socket.leave("room2");
* socket.disconnect();
* }
*/
fetchSockets() {
return new broadcast_operator_1.BroadcastOperator(this.adapter).fetchSockets();
}
/**
* Makes the matching socket instances join the specified rooms.
*
* Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* // make all socket instances join the "room1" room
* myNamespace.socketsJoin("room1");
*
* // make all socket instances in the "room1" room join the "room2" and "room3" rooms
* myNamespace.in("room1").socketsJoin(["room2", "room3"]);
*
* @param room - a room, or an array of rooms
*/
socketsJoin(room) {
return new broadcast_operator_1.BroadcastOperator(this.adapter).socketsJoin(room);
}
/**
* Makes the matching socket instances leave the specified rooms.
*
* Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* // make all socket instances leave the "room1" room
* myNamespace.socketsLeave("room1");
*
* // make all socket instances in the "room1" room leave the "room2" and "room3" rooms
* myNamespace.in("room1").socketsLeave(["room2", "room3"]);
*
* @param room - a room, or an array of rooms
*/
socketsLeave(room) {
return new broadcast_operator_1.BroadcastOperator(this.adapter).socketsLeave(room);
}
/**
* Makes the matching socket instances disconnect.
*
* Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
*
* @example
* const myNamespace = io.of("/my-namespace");
*
* // make all socket instances disconnect (the connections might be kept alive for other namespaces)
* myNamespace.disconnectSockets();
*
* // make all socket instances in the "room1" room disconnect and close the underlying connections
* myNamespace.in("room1").disconnectSockets(true);
*
* @param close - whether to close the underlying connection
*/
disconnectSockets(close = false) {
return new broadcast_operator_1.BroadcastOperator(this.adapter).disconnectSockets(close);
}
}
exports.Namespace = Namespace;

View File

@@ -0,0 +1,92 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParentNamespace = void 0;
const namespace_1 = require("./namespace");
const socket_io_adapter_1 = require("socket.io-adapter");
const debug_1 = __importDefault(require("debug"));
const debug = (0, debug_1.default)("socket.io:parent-namespace");
/**
* A parent namespace is a special {@link Namespace} that holds a list of child namespaces which were created either
* with a regular expression or with a function.
*
* @example
* const parentNamespace = io.of(/\/dynamic-\d+/);
*
* parentNamespace.on("connection", (socket) => {
* const childNamespace = socket.nsp;
* }
*
* // will reach all the clients that are in one of the child namespaces, like "/dynamic-101"
* parentNamespace.emit("hello", "world");
*
*/
class ParentNamespace extends namespace_1.Namespace {
constructor(server) {
super(server, "/_" + ParentNamespace.count++);
this.children = new Set();
}
/**
* @private
*/
_initAdapter() {
this.adapter = new ParentBroadcastAdapter(this, this.children);
}
emit(ev, ...args) {
this.children.forEach((nsp) => {
nsp.emit(ev, ...args);
});
return true;
}
createChild(name) {
debug("creating child namespace %s", name);
const namespace = new namespace_1.Namespace(this.server, name);
namespace._fns = this._fns.slice(0);
this.listeners("connect").forEach((listener) => namespace.on("connect", listener));
this.listeners("connection").forEach((listener) => namespace.on("connection", listener));
this.children.add(namespace);
if (this.server._opts.cleanupEmptyChildNamespaces) {
const remove = namespace._remove;
namespace._remove = (socket) => {
remove.call(namespace, socket);
if (namespace.sockets.size === 0) {
debug("closing child namespace %s", name);
namespace.adapter.close();
this.server._nsps.delete(namespace.name);
this.children.delete(namespace);
}
};
}
this.server._nsps.set(name, namespace);
// @ts-ignore
this.server.sockets.emitReserved("new_namespace", namespace);
return namespace;
}
fetchSockets() {
// note: we could make the fetchSockets() method work for dynamic namespaces created with a regex (by sending the
// regex to the other Socket.IO servers, and returning the sockets of each matching namespace for example), but
// the behavior for namespaces created with a function is less clear
// note²: we cannot loop over each children namespace, because with multiple Socket.IO servers, a given namespace
// may exist on one node but not exist on another (since it is created upon client connection)
throw new Error("fetchSockets() is not supported on parent namespaces");
}
}
exports.ParentNamespace = ParentNamespace;
ParentNamespace.count = 0;
/**
* A dummy adapter that only supports broadcasting to child (concrete) namespaces.
* @private file
*/
class ParentBroadcastAdapter extends socket_io_adapter_1.Adapter {
constructor(parentNsp, children) {
super(parentNsp);
this.children = children;
}
broadcast(packet, opts) {
this.children.forEach((nsp) => {
nsp.adapter.broadcast(packet, opts);
});
}
}

984
resources/app/node_modules/socket.io/dist/socket.js generated vendored Normal file
View File

@@ -0,0 +1,984 @@
"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.RESERVED_EVENTS = void 0;
const socket_io_parser_1 = require("socket.io-parser");
const debug_1 = __importDefault(require("debug"));
const typed_events_1 = require("./typed-events");
const base64id_1 = __importDefault(require("base64id"));
const broadcast_operator_1 = require("./broadcast-operator");
const debug = (0, debug_1.default)("socket.io:socket");
const RECOVERABLE_DISCONNECT_REASONS = new Set([
"transport error",
"transport close",
"forced close",
"ping timeout",
"server shutting down",
"forced server close",
]);
exports.RESERVED_EVENTS = new Set([
"connect",
"connect_error",
"disconnect",
"disconnecting",
"newListener",
"removeListener",
]);
function noop() { }
/**
* This is the main object for interacting with a client.
*
* A Socket belongs to a given {@link Namespace} and uses an underlying {@link Client} to communicate.
*
* Within each {@link Namespace}, you can also define arbitrary channels (called "rooms") that the {@link Socket} can
* join and leave. That provides a convenient way to broadcast to a group of socket instances.
*
* @example
* io.on("connection", (socket) => {
* console.log(`socket ${socket.id} connected`);
*
* // send an event to the client
* socket.emit("foo", "bar");
*
* socket.on("foobar", () => {
* // an event was received from the client
* });
*
* // join the room named "room1"
* socket.join("room1");
*
* // broadcast to everyone in the room named "room1"
* io.to("room1").emit("hello");
*
* // upon disconnection
* socket.on("disconnect", (reason) => {
* console.log(`socket ${socket.id} disconnected due to ${reason}`);
* });
* });
*/
class Socket extends typed_events_1.StrictEventEmitter {
/**
* Interface to a `Client` for a given `Namespace`.
*
* @param {Namespace} nsp
* @param {Client} client
* @param {Object} auth
* @package
*/
constructor(nsp, client, auth, previousSession) {
super();
this.nsp = nsp;
this.client = client;
/**
* Whether the connection state was recovered after a temporary disconnection. In that case, any missed packets will
* be transmitted to the client, the data attribute and the rooms will be restored.
*/
this.recovered = false;
/**
* Additional information that can be attached to the Socket instance and which will be used in the
* {@link Server.fetchSockets()} method.
*/
this.data = {};
/**
* Whether the socket is currently connected or not.
*
* @example
* io.use((socket, next) => {
* console.log(socket.connected); // false
* next();
* });
*
* io.on("connection", (socket) => {
* console.log(socket.connected); // true
* });
*/
this.connected = false;
this.acks = new Map();
this.fns = [];
this.flags = {};
this.server = nsp.server;
this.adapter = this.nsp.adapter;
if (previousSession) {
this.id = previousSession.sid;
this.pid = previousSession.pid;
previousSession.rooms.forEach((room) => this.join(room));
this.data = previousSession.data;
previousSession.missedPackets.forEach((packet) => {
this.packet({
type: socket_io_parser_1.PacketType.EVENT,
data: packet,
});
});
this.recovered = true;
}
else {
if (client.conn.protocol === 3) {
// @ts-ignore
this.id = nsp.name !== "/" ? nsp.name + "#" + client.id : client.id;
}
else {
this.id = base64id_1.default.generateId(); // don't reuse the Engine.IO id because it's sensitive information
}
if (this.server._opts.connectionStateRecovery) {
this.pid = base64id_1.default.generateId();
}
}
this.handshake = this.buildHandshake(auth);
// prevents crash when the socket receives an "error" event without listener
this.on("error", noop);
}
/**
* Builds the `handshake` BC object
*
* @private
*/
buildHandshake(auth) {
var _a, _b, _c, _d;
return {
headers: ((_a = this.request) === null || _a === void 0 ? void 0 : _a.headers) || {},
time: new Date() + "",
address: this.conn.remoteAddress,
xdomain: !!((_b = this.request) === null || _b === void 0 ? void 0 : _b.headers.origin),
// @ts-ignore
secure: !this.request || !!this.request.connection.encrypted,
issued: +new Date(),
url: (_c = this.request) === null || _c === void 0 ? void 0 : _c.url,
// @ts-ignore
query: ((_d = this.request) === null || _d === void 0 ? void 0 : _d._query) || {},
auth,
};
}
/**
* Emits to this client.
*
* @example
* io.on("connection", (socket) => {
* socket.emit("hello", "world");
*
* // all serializable datastructures are supported (no need to call JSON.stringify)
* socket.emit("hello", 1, "2", { 3: ["4"], 5: Buffer.from([6]) });
*
* // with an acknowledgement from the client
* socket.emit("hello", "world", (val) => {
* // ...
* });
* });
*
* @return Always returns `true`.
*/
emit(ev, ...args) {
if (exports.RESERVED_EVENTS.has(ev)) {
throw new Error(`"${String(ev)}" is a reserved event name`);
}
const data = [ev, ...args];
const packet = {
type: socket_io_parser_1.PacketType.EVENT,
data: data,
};
// access last argument to see if it's an ACK callback
if (typeof data[data.length - 1] === "function") {
const id = this.nsp._ids++;
debug("emitting packet with ack id %d", id);
this.registerAckCallback(id, data.pop());
packet.id = id;
}
const flags = Object.assign({}, this.flags);
this.flags = {};
// @ts-ignore
if (this.nsp.server.opts.connectionStateRecovery) {
// this ensures the packet is stored and can be transmitted upon reconnection
this.adapter.broadcast(packet, {
rooms: new Set([this.id]),
except: new Set(),
flags,
});
}
else {
this.notifyOutgoingListeners(packet);
this.packet(packet, flags);
}
return true;
}
/**
* Emits an event and waits for an acknowledgement
*
* @example
* io.on("connection", async (socket) => {
* // without timeout
* const response = await socket.emitWithAck("hello", "world");
*
* // with a specific timeout
* try {
* const response = await socket.timeout(1000).emitWithAck("hello", "world");
* } catch (err) {
* // the client did not acknowledge the event in the given delay
* }
* });
*
* @return a Promise that will be fulfilled when the client acknowledges the event
*/
emitWithAck(ev, ...args) {
// the timeout flag is optional
const withErr = this.flags.timeout !== undefined;
return new Promise((resolve, reject) => {
args.push((arg1, arg2) => {
if (withErr) {
return arg1 ? reject(arg1) : resolve(arg2);
}
else {
return resolve(arg1);
}
});
this.emit(ev, ...args);
});
}
/**
* @private
*/
registerAckCallback(id, ack) {
const timeout = this.flags.timeout;
if (timeout === undefined) {
this.acks.set(id, ack);
return;
}
const timer = setTimeout(() => {
debug("event with ack id %d has timed out after %d ms", id, timeout);
this.acks.delete(id);
ack.call(this, new Error("operation has timed out"));
}, timeout);
this.acks.set(id, (...args) => {
clearTimeout(timer);
ack.apply(this, [null, ...args]);
});
}
/**
* Targets a room when broadcasting.
*
* @example
* io.on("connection", (socket) => {
* // the “foo” event will be broadcast to all connected clients in the “room-101” room, except this socket
* socket.to("room-101").emit("foo", "bar");
*
* // the code above is equivalent to:
* io.to("room-101").except(socket.id).emit("foo", "bar");
*
* // with an array of rooms (a client will be notified at most once)
* socket.to(["room-101", "room-102"]).emit("foo", "bar");
*
* // with multiple chained calls
* socket.to("room-101").to("room-102").emit("foo", "bar");
* });
*
* @param room - a room, or an array of rooms
* @return a new {@link BroadcastOperator} instance for chaining
*/
to(room) {
return this.newBroadcastOperator().to(room);
}
/**
* Targets a room when broadcasting. Similar to `to()`, but might feel clearer in some cases:
*
* @example
* io.on("connection", (socket) => {
* // disconnect all clients in the "room-101" room, except this socket
* socket.in("room-101").disconnectSockets();
* });
*
* @param room - a room, or an array of rooms
* @return a new {@link BroadcastOperator} instance for chaining
*/
in(room) {
return this.newBroadcastOperator().in(room);
}
/**
* Excludes a room when broadcasting.
*
* @example
* io.on("connection", (socket) => {
* // the "foo" event will be broadcast to all connected clients, except the ones that are in the "room-101" room
* // and this socket
* socket.except("room-101").emit("foo", "bar");
*
* // with an array of rooms
* socket.except(["room-101", "room-102"]).emit("foo", "bar");
*
* // with multiple chained calls
* socket.except("room-101").except("room-102").emit("foo", "bar");
* });
*
* @param room - a room, or an array of rooms
* @return a new {@link BroadcastOperator} instance for chaining
*/
except(room) {
return this.newBroadcastOperator().except(room);
}
/**
* Sends a `message` event.
*
* This method mimics the WebSocket.send() method.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
*
* @example
* io.on("connection", (socket) => {
* socket.send("hello");
*
* // this is equivalent to
* socket.emit("message", "hello");
* });
*
* @return self
*/
send(...args) {
this.emit("message", ...args);
return this;
}
/**
* Sends a `message` event. Alias of {@link send}.
*
* @return self
*/
write(...args) {
this.emit("message", ...args);
return this;
}
/**
* Writes a packet.
*
* @param {Object} packet - packet object
* @param {Object} opts - options
* @private
*/
packet(packet, opts = {}) {
packet.nsp = this.nsp.name;
opts.compress = false !== opts.compress;
this.client._packet(packet, opts);
}
/**
* Joins a room.
*
* @example
* io.on("connection", (socket) => {
* // join a single room
* socket.join("room1");
*
* // join multiple rooms
* socket.join(["room1", "room2"]);
* });
*
* @param {String|Array} rooms - room or array of rooms
* @return a Promise or nothing, depending on the adapter
*/
join(rooms) {
debug("join room %s", rooms);
return this.adapter.addAll(this.id, new Set(Array.isArray(rooms) ? rooms : [rooms]));
}
/**
* Leaves a room.
*
* @example
* io.on("connection", (socket) => {
* // leave a single room
* socket.leave("room1");
*
* // leave multiple rooms
* socket.leave("room1").leave("room2");
* });
*
* @param {String} room
* @return a Promise or nothing, depending on the adapter
*/
leave(room) {
debug("leave room %s", room);
return this.adapter.del(this.id, room);
}
/**
* Leave all rooms.
*
* @private
*/
leaveAll() {
this.adapter.delAll(this.id);
}
/**
* Called by `Namespace` upon successful
* middleware execution (ie: authorization).
* Socket is added to namespace array before
* call to join, so adapters can access it.
*
* @private
*/
_onconnect() {
debug("socket connected - writing packet");
this.connected = true;
this.join(this.id);
if (this.conn.protocol === 3) {
this.packet({ type: socket_io_parser_1.PacketType.CONNECT });
}
else {
this.packet({
type: socket_io_parser_1.PacketType.CONNECT,
data: { sid: this.id, pid: this.pid },
});
}
}
/**
* Called with each packet. Called by `Client`.
*
* @param {Object} packet
* @private
*/
_onpacket(packet) {
debug("got packet %j", packet);
switch (packet.type) {
case socket_io_parser_1.PacketType.EVENT:
this.onevent(packet);
break;
case socket_io_parser_1.PacketType.BINARY_EVENT:
this.onevent(packet);
break;
case socket_io_parser_1.PacketType.ACK:
this.onack(packet);
break;
case socket_io_parser_1.PacketType.BINARY_ACK:
this.onack(packet);
break;
case socket_io_parser_1.PacketType.DISCONNECT:
this.ondisconnect();
break;
}
}
/**
* Called upon event packet.
*
* @param {Packet} packet - packet object
* @private
*/
onevent(packet) {
const args = packet.data || [];
debug("emitting event %j", args);
if (null != packet.id) {
debug("attaching ack callback to event");
args.push(this.ack(packet.id));
}
if (this._anyListeners && this._anyListeners.length) {
const listeners = this._anyListeners.slice();
for (const listener of listeners) {
listener.apply(this, args);
}
}
this.dispatch(args);
}
/**
* Produces an ack callback to emit with an event.
*
* @param {Number} id - packet id
* @private
*/
ack(id) {
const self = this;
let sent = false;
return function () {
// prevent double callbacks
if (sent)
return;
const args = Array.prototype.slice.call(arguments);
debug("sending ack %j", args);
self.packet({
id: id,
type: socket_io_parser_1.PacketType.ACK,
data: args,
});
sent = true;
};
}
/**
* Called upon ack packet.
*
* @private
*/
onack(packet) {
const ack = this.acks.get(packet.id);
if ("function" == typeof ack) {
debug("calling ack %s with %j", packet.id, packet.data);
ack.apply(this, packet.data);
this.acks.delete(packet.id);
}
else {
debug("bad ack %s", packet.id);
}
}
/**
* Called upon client disconnect packet.
*
* @private
*/
ondisconnect() {
debug("got disconnect packet");
this._onclose("client namespace disconnect");
}
/**
* Handles a client error.
*
* @private
*/
_onerror(err) {
// FIXME the meaning of the "error" event is overloaded:
// - it can be sent by the client (`socket.emit("error")`)
// - it can be emitted when the connection encounters an error (an invalid packet for example)
// - it can be emitted when a packet is rejected in a middleware (`socket.use()`)
this.emitReserved("error", err);
}
/**
* Called upon closing. Called by `Client`.
*
* @param {String} reason
* @param description
* @throw {Error} optional error object
*
* @private
*/
_onclose(reason, description) {
if (!this.connected)
return this;
debug("closing socket - reason %s", reason);
this.emitReserved("disconnecting", reason, description);
if (this.server._opts.connectionStateRecovery &&
RECOVERABLE_DISCONNECT_REASONS.has(reason)) {
debug("connection state recovery is enabled for sid %s", this.id);
this.adapter.persistSession({
sid: this.id,
pid: this.pid,
rooms: [...this.rooms],
data: this.data,
});
}
this._cleanup();
this.client._remove(this);
this.connected = false;
this.emitReserved("disconnect", reason, description);
return;
}
/**
* Makes the socket leave all the rooms it was part of and prevents it from joining any other room
*
* @private
*/
_cleanup() {
this.leaveAll();
this.nsp._remove(this);
this.join = noop;
}
/**
* Produces an `error` packet.
*
* @param {Object} err - error object
*
* @private
*/
_error(err) {
this.packet({ type: socket_io_parser_1.PacketType.CONNECT_ERROR, data: err });
}
/**
* Disconnects this client.
*
* @example
* io.on("connection", (socket) => {
* // disconnect this socket (the connection might be kept alive for other namespaces)
* socket.disconnect();
*
* // disconnect this socket and close the underlying connection
* socket.disconnect(true);
* })
*
* @param {Boolean} close - if `true`, closes the underlying connection
* @return self
*/
disconnect(close = false) {
if (!this.connected)
return this;
if (close) {
this.client._disconnect();
}
else {
this.packet({ type: socket_io_parser_1.PacketType.DISCONNECT });
this._onclose("server namespace disconnect");
}
return this;
}
/**
* Sets the compress flag.
*
* @example
* io.on("connection", (socket) => {
* socket.compress(false).emit("hello");
* });
*
* @param {Boolean} compress - if `true`, compresses the sending data
* @return {Socket} self
*/
compress(compress) {
this.flags.compress = compress;
return this;
}
/**
* Sets a modifier for a subsequent event emission that the event data may be lost if the client is not ready to
* receive messages (because of network slowness or other issues, or because theyre connected through long polling
* and is in the middle of a request-response cycle).
*
* @example
* io.on("connection", (socket) => {
* socket.volatile.emit("hello"); // the client may or may not receive it
* });
*
* @return {Socket} self
*/
get volatile() {
this.flags.volatile = true;
return this;
}
/**
* Sets a modifier for a subsequent event emission that the event data will only be broadcast to every sockets but the
* sender.
*
* @example
* io.on("connection", (socket) => {
* // the “foo” event will be broadcast to all connected clients, except this socket
* socket.broadcast.emit("foo", "bar");
* });
*
* @return a new {@link BroadcastOperator} instance for chaining
*/
get broadcast() {
return this.newBroadcastOperator();
}
/**
* Sets a modifier for a subsequent event emission that the event data will only be broadcast to the current node.
*
* @example
* io.on("connection", (socket) => {
* // the “foo” event will be broadcast to all connected clients on this node, except this socket
* socket.local.emit("foo", "bar");
* });
*
* @return a new {@link BroadcastOperator} instance for chaining
*/
get local() {
return this.newBroadcastOperator().local;
}
/**
* Sets a modifier for a subsequent event emission that the callback will be called with an error when the
* given number of milliseconds have elapsed without an acknowledgement from the client:
*
* @example
* io.on("connection", (socket) => {
* socket.timeout(5000).emit("my-event", (err) => {
* if (err) {
* // the client did not acknowledge the event in the given delay
* }
* });
* });
*
* @returns self
*/
timeout(timeout) {
this.flags.timeout = timeout;
return this;
}
/**
* Dispatch incoming event to socket listeners.
*
* @param {Array} event - event that will get emitted
* @private
*/
dispatch(event) {
debug("dispatching an event %j", event);
this.run(event, (err) => {
process.nextTick(() => {
if (err) {
return this._onerror(err);
}
if (this.connected) {
super.emitUntyped.apply(this, event);
}
else {
debug("ignore packet received after disconnection");
}
});
});
}
/**
* Sets up socket middleware.
*
* @example
* io.on("connection", (socket) => {
* socket.use(([event, ...args], next) => {
* if (isUnauthorized(event)) {
* return next(new Error("unauthorized event"));
* }
* // do not forget to call next
* next();
* });
*
* socket.on("error", (err) => {
* if (err && err.message === "unauthorized event") {
* socket.disconnect();
* }
* });
* });
*
* @param {Function} fn - middleware function (event, next)
* @return {Socket} self
*/
use(fn) {
this.fns.push(fn);
return this;
}
/**
* Executes the middleware for an incoming event.
*
* @param {Array} event - event that will get emitted
* @param {Function} fn - last fn call in the middleware
* @private
*/
run(event, fn) {
const fns = this.fns.slice(0);
if (!fns.length)
return fn(null);
function run(i) {
fns[i](event, function (err) {
// upon error, short-circuit
if (err)
return fn(err);
// if no middleware left, summon callback
if (!fns[i + 1])
return fn(null);
// go on to next
run(i + 1);
});
}
run(0);
}
/**
* Whether the socket is currently disconnected
*/
get disconnected() {
return !this.connected;
}
/**
* A reference to the request that originated the underlying Engine.IO Socket.
*/
get request() {
return this.client.request;
}
/**
* A reference to the underlying Client transport connection (Engine.IO Socket object).
*
* @example
* io.on("connection", (socket) => {
* console.log(socket.conn.transport.name); // prints "polling" or "websocket"
*
* socket.conn.once("upgrade", () => {
* console.log(socket.conn.transport.name); // prints "websocket"
* });
* });
*/
get conn() {
return this.client.conn;
}
/**
* Returns the rooms the socket is currently in.
*
* @example
* io.on("connection", (socket) => {
* console.log(socket.rooms); // Set { <socket.id> }
*
* socket.join("room1");
*
* console.log(socket.rooms); // Set { <socket.id>, "room1" }
* });
*/
get rooms() {
return this.adapter.socketRooms(this.id) || new Set();
}
/**
* Adds a listener that will be fired when any event is received. The event name is passed as the first argument to
* the callback.
*
* @example
* io.on("connection", (socket) => {
* socket.onAny((event, ...args) => {
* console.log(`got event ${event}`);
* });
* });
*
* @param listener
*/
onAny(listener) {
this._anyListeners = this._anyListeners || [];
this._anyListeners.push(listener);
return this;
}
/**
* Adds a listener that will be fired when any event is received. The event name is passed as the first argument to
* the callback. The listener is added to the beginning of the listeners array.
*
* @param listener
*/
prependAny(listener) {
this._anyListeners = this._anyListeners || [];
this._anyListeners.unshift(listener);
return this;
}
/**
* Removes the listener that will be fired when any event is received.
*
* @example
* io.on("connection", (socket) => {
* const catchAllListener = (event, ...args) => {
* console.log(`got event ${event}`);
* }
*
* socket.onAny(catchAllListener);
*
* // remove a specific listener
* socket.offAny(catchAllListener);
*
* // or remove all listeners
* socket.offAny();
* });
*
* @param listener
*/
offAny(listener) {
if (!this._anyListeners) {
return this;
}
if (listener) {
const listeners = this._anyListeners;
for (let i = 0; i < listeners.length; i++) {
if (listener === listeners[i]) {
listeners.splice(i, 1);
return this;
}
}
}
else {
this._anyListeners = [];
}
return this;
}
/**
* Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,
* e.g. to remove listeners.
*/
listenersAny() {
return this._anyListeners || [];
}
/**
* Adds a listener that will be fired when any event is sent. The event name is passed as the first argument to
* the callback.
*
* Note: acknowledgements sent to the client are not included.
*
* @example
* io.on("connection", (socket) => {
* socket.onAnyOutgoing((event, ...args) => {
* console.log(`sent event ${event}`);
* });
* });
*
* @param listener
*/
onAnyOutgoing(listener) {
this._anyOutgoingListeners = this._anyOutgoingListeners || [];
this._anyOutgoingListeners.push(listener);
return this;
}
/**
* Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
* callback. The listener is added to the beginning of the listeners array.
*
* @example
* io.on("connection", (socket) => {
* socket.prependAnyOutgoing((event, ...args) => {
* console.log(`sent event ${event}`);
* });
* });
*
* @param listener
*/
prependAnyOutgoing(listener) {
this._anyOutgoingListeners = this._anyOutgoingListeners || [];
this._anyOutgoingListeners.unshift(listener);
return this;
}
/**
* Removes the listener that will be fired when any event is sent.
*
* @example
* io.on("connection", (socket) => {
* const catchAllListener = (event, ...args) => {
* console.log(`sent event ${event}`);
* }
*
* socket.onAnyOutgoing(catchAllListener);
*
* // remove a specific listener
* socket.offAnyOutgoing(catchAllListener);
*
* // or remove all listeners
* socket.offAnyOutgoing();
* });
*
* @param listener - the catch-all listener
*/
offAnyOutgoing(listener) {
if (!this._anyOutgoingListeners) {
return this;
}
if (listener) {
const listeners = this._anyOutgoingListeners;
for (let i = 0; i < listeners.length; i++) {
if (listener === listeners[i]) {
listeners.splice(i, 1);
return this;
}
}
}
else {
this._anyOutgoingListeners = [];
}
return this;
}
/**
* Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,
* e.g. to remove listeners.
*/
listenersAnyOutgoing() {
return this._anyOutgoingListeners || [];
}
/**
* Notify the listeners for each packet sent (emit or broadcast)
*
* @param packet
*
* @private
*/
notifyOutgoingListeners(packet) {
if (this._anyOutgoingListeners && this._anyOutgoingListeners.length) {
const listeners = this._anyOutgoingListeners.slice();
for (const listener of listeners) {
listener.apply(this, packet.data);
}
}
}
newBroadcastOperator() {
const flags = Object.assign({}, this.flags);
this.flags = {};
return new broadcast_operator_1.BroadcastOperator(this.adapter, new Set(), new Set([this.id]), flags);
}
}
exports.Socket = Socket;

View File

@@ -0,0 +1,81 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StrictEventEmitter = void 0;
const events_1 = require("events");
/**
* 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`.
*/
class StrictEventEmitter extends events_1.EventEmitter {
/**
* Adds the `listener` function as an event listener for `ev`.
*
* @param ev Name of the event
* @param listener Callback function
*/
on(ev, listener) {
return super.on(ev, listener);
}
/**
* Adds a one-time `listener` function as an event listener for `ev`.
*
* @param ev Name of the event
* @param listener Callback function
*/
once(ev, listener) {
return super.once(ev, listener);
}
/**
* Emits an event.
*
* @param ev Name of the event
* @param args Values to send to listeners of this event
*/
emit(ev, ...args) {
return super.emit(ev, ...args);
}
/**
* 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
*/
emitReserved(ev, ...args) {
return super.emit(ev, ...args);
}
/**
* Emits an event.
*
* This method is `protected`, so that only a class extending
* `StrictEventEmitter` can get around the strict typing. This is useful for
* calling `emit.apply`, which can be called as `emitUntyped.apply`.
*
* @param ev Event name
* @param args Arguments to emit along with the event
*/
emitUntyped(ev, ...args) {
return super.emit(ev, ...args);
}
/**
* Returns the listeners listening to an event.
*
* @param event Event name
* @returns Array of listeners subscribed to `event`
*/
listeners(event) {
return super.listeners(event);
}
}
exports.StrictEventEmitter = StrictEventEmitter;

135
resources/app/node_modules/socket.io/dist/uws.js generated vendored Normal file
View File

@@ -0,0 +1,135 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.serveFile = exports.restoreAdapter = exports.patchAdapter = void 0;
const socket_io_adapter_1 = require("socket.io-adapter");
const fs_1 = require("fs");
const debug_1 = __importDefault(require("debug"));
const debug = (0, debug_1.default)("socket.io:adapter-uws");
const SEPARATOR = "\x1f"; // see https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_text
const { addAll, del, broadcast } = socket_io_adapter_1.Adapter.prototype;
function patchAdapter(app /* : TemplatedApp */) {
socket_io_adapter_1.Adapter.prototype.addAll = function (id, rooms) {
const isNew = !this.sids.has(id);
addAll.call(this, id, rooms);
const socket = this.nsp.sockets.get(id);
if (!socket) {
return;
}
if (socket.conn.transport.name === "websocket") {
subscribe(this.nsp.name, socket, isNew, rooms);
return;
}
if (isNew) {
socket.conn.on("upgrade", () => {
const rooms = this.sids.get(id);
if (rooms) {
subscribe(this.nsp.name, socket, isNew, rooms);
}
});
}
};
socket_io_adapter_1.Adapter.prototype.del = function (id, room) {
del.call(this, id, room);
const socket = this.nsp.sockets.get(id);
if (socket && socket.conn.transport.name === "websocket") {
// @ts-ignore
const sessionId = socket.conn.id;
// @ts-ignore
const websocket = socket.conn.transport.socket;
const topic = `${this.nsp.name}${SEPARATOR}${room}`;
debug("unsubscribe connection %s from topic %s", sessionId, topic);
websocket.unsubscribe(topic);
}
};
socket_io_adapter_1.Adapter.prototype.broadcast = function (packet, opts) {
const useFastPublish = opts.rooms.size <= 1 && opts.except.size === 0;
if (!useFastPublish) {
broadcast.call(this, packet, opts);
return;
}
const flags = opts.flags || {};
const basePacketOpts = {
preEncoded: true,
volatile: flags.volatile,
compress: flags.compress,
};
packet.nsp = this.nsp.name;
const encodedPackets = this.encoder.encode(packet);
const topic = opts.rooms.size === 0
? this.nsp.name
: `${this.nsp.name}${SEPARATOR}${opts.rooms.keys().next().value}`;
debug("fast publish to %s", topic);
// fast publish for clients connected with WebSocket
encodedPackets.forEach((encodedPacket) => {
const isBinary = typeof encodedPacket !== "string";
// "4" being the message type in the Engine.IO protocol, see https://github.com/socketio/engine.io-protocol
app.publish(topic, isBinary ? encodedPacket : "4" + encodedPacket, isBinary);
});
this.apply(opts, (socket) => {
if (socket.conn.transport.name !== "websocket") {
// classic publish for clients connected with HTTP long-polling
socket.client.writeToEngine(encodedPackets, basePacketOpts);
}
});
};
}
exports.patchAdapter = patchAdapter;
function subscribe(namespaceName, socket, isNew, rooms) {
// @ts-ignore
const sessionId = socket.conn.id;
// @ts-ignore
const websocket = socket.conn.transport.socket;
if (isNew) {
debug("subscribe connection %s to topic %s", sessionId, namespaceName);
websocket.subscribe(namespaceName);
}
rooms.forEach((room) => {
const topic = `${namespaceName}${SEPARATOR}${room}`; // '#' can be used as wildcard
debug("subscribe connection %s to topic %s", sessionId, topic);
websocket.subscribe(topic);
});
}
function restoreAdapter() {
socket_io_adapter_1.Adapter.prototype.addAll = addAll;
socket_io_adapter_1.Adapter.prototype.del = del;
socket_io_adapter_1.Adapter.prototype.broadcast = broadcast;
}
exports.restoreAdapter = restoreAdapter;
const toArrayBuffer = (buffer) => {
const { buffer: arrayBuffer, byteOffset, byteLength } = buffer;
return arrayBuffer.slice(byteOffset, byteOffset + byteLength);
};
// imported from https://github.com/kolodziejczak-sz/uwebsocket-serve
function serveFile(res /* : HttpResponse */, filepath) {
const { size } = (0, fs_1.statSync)(filepath);
const readStream = (0, fs_1.createReadStream)(filepath);
const destroyReadStream = () => !readStream.destroyed && readStream.destroy();
const onError = (error) => {
destroyReadStream();
throw error;
};
const onDataChunk = (chunk) => {
const arrayBufferChunk = toArrayBuffer(chunk);
const lastOffset = res.getWriteOffset();
const [ok, done] = res.tryEnd(arrayBufferChunk, size);
if (!done && !ok) {
readStream.pause();
res.onWritable((offset) => {
const [ok, done] = res.tryEnd(arrayBufferChunk.slice(offset - lastOffset), size);
if (!done && ok) {
readStream.resume();
}
return ok;
});
}
};
res.onAborted(destroyReadStream);
readStream
.on("data", onDataChunk)
.on("error", onError)
.on("end", destroyReadStream);
}
exports.serveFile = serveFile;

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.

View File

@@ -0,0 +1,42 @@
{
"name": "debug",
"version": "4.3.4",
"repository": {
"type": "git",
"url": "git://github.com/debug-js/debug.git"
},
"description": "Lightweight debugging utility for Node.js and the browser",
"files": [
"src",
"LICENSE",
"README.md"
],
"author": "Josh Junon <josh.junon@protonmail.com>",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"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",
"xo": "^0.23.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
},
"main": "./src/index.js",
"browser": "./src/browser.js",
"engines": {
"node": ">=6.0"
}
}

View File

@@ -0,0 +1,269 @@
/* 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;
}
// 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 && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$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;
}
};

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;

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');
}

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.format()` with the specified arguments and writes to stderr.
*/
function log(...args) {
return process.stderr.write(util.format(...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);
};

View File

@@ -0,0 +1,162 @@
/**
* Helpers.
*/
var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var w = d * 7;
var y = d * 365.25;
/**
* Parse or format the given `val`.
*
* Options:
*
* - `long` verbose formatting [false]
*
* @param {String|Number} val
* @param {Object} [options]
* @throws {Error} throw an error if val is not a non-empty string or a number
* @return {String|Number}
* @api public
*/
module.exports = function(val, options) {
options = options || {};
var type = typeof val;
if (type === 'string' && val.length > 0) {
return parse(val);
} else if (type === 'number' && isFinite(val)) {
return options.long ? fmtLong(val) : fmtShort(val);
}
throw new Error(
'val is not a non-empty string or a valid number. val=' +
JSON.stringify(val)
);
};
/**
* Parse the given `str` and return milliseconds.
*
* @param {String} str
* @return {Number}
* @api private
*/
function parse(str) {
str = String(str);
if (str.length > 100) {
return;
}
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
str
);
if (!match) {
return;
}
var n = parseFloat(match[1]);
var type = (match[2] || 'ms').toLowerCase();
switch (type) {
case 'years':
case 'year':
case 'yrs':
case 'yr':
case 'y':
return n * y;
case 'weeks':
case 'week':
case 'w':
return n * w;
case 'days':
case 'day':
case 'd':
return n * d;
case 'hours':
case 'hour':
case 'hrs':
case 'hr':
case 'h':
return n * h;
case 'minutes':
case 'minute':
case 'mins':
case 'min':
case 'm':
return n * m;
case 'seconds':
case 'second':
case 'secs':
case 'sec':
case 's':
return n * s;
case 'milliseconds':
case 'millisecond':
case 'msecs':
case 'msec':
case 'ms':
return n;
default:
return undefined;
}
}
/**
* Short format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtShort(ms) {
var msAbs = Math.abs(ms);
if (msAbs >= d) {
return Math.round(ms / d) + 'd';
}
if (msAbs >= h) {
return Math.round(ms / h) + 'h';
}
if (msAbs >= m) {
return Math.round(ms / m) + 'm';
}
if (msAbs >= s) {
return Math.round(ms / s) + 's';
}
return ms + 'ms';
}
/**
* Long format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtLong(ms) {
var msAbs = Math.abs(ms);
if (msAbs >= d) {
return plural(ms, msAbs, d, 'day');
}
if (msAbs >= h) {
return plural(ms, msAbs, h, 'hour');
}
if (msAbs >= m) {
return plural(ms, msAbs, m, 'minute');
}
if (msAbs >= s) {
return plural(ms, msAbs, s, 'second');
}
return ms + ' ms';
}
/**
* Pluralization helper.
*/
function plural(ms, msAbs, n, name) {
var isPlural = msAbs >= n * 1.5;
return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
}

View File

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

View File

@@ -0,0 +1,25 @@
{
"name": "ms",
"version": "2.1.2",
"description": "Tiny millisecond conversion utility",
"repository": "zeit/ms",
"main": "./index",
"files": [
"index.js"
],
"lint-staged": {
"*.js": [
"npm run lint",
"prettier --single-quote --write",
"git add"
]
},
"license": "MIT",
"devDependencies": {
"eslint": "4.12.1",
"expect.js": "0.3.1",
"husky": "0.14.3",
"lint-staged": "5.0.0",
"mocha": "4.0.1"
}
}

61
resources/app/node_modules/socket.io/package.json generated vendored Normal file
View File

@@ -0,0 +1,61 @@
{
"name": "socket.io",
"version": "4.7.5",
"description": "node.js realtime framework server",
"files": [
"dist/",
"client-dist/",
"wrapper.mjs",
"!**/*.tsbuildinfo"
],
"directories": {
"doc": "docs/",
"example": "example/",
"lib": "lib/",
"test": "test/"
},
"type": "commonjs",
"main": "./dist/index.js",
"exports": {
"types": "./dist/index.d.ts",
"import": "./wrapper.mjs",
"require": "./dist/index.js"
},
"types": "./dist/index.d.ts",
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/socketio/socket.io"
},
"dependencies": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"cors": "~2.8.5",
"debug": "~4.3.2",
"engine.io": "~6.5.2",
"socket.io-adapter": "~2.5.2",
"socket.io-parser": "~4.2.4"
},
"devDependencies": {
"@types/mocha": "^9.0.0",
"expect.js": "0.3.1",
"mocha": "^10.0.0",
"nyc": "^15.1.0",
"prettier": "^2.3.2",
"rimraf": "^3.0.2",
"socket.io-client": "4.7.5",
"socket.io-client-v2": "npm:socket.io-client@^2.4.0",
"superagent": "^8.0.0",
"supertest": "^6.1.6",
"ts-node": "^10.2.1",
"tsd": "^0.27.0",
"typescript": "^4.4.2",
"uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.30.0"
},
"engines": {
"node": ">=10.2.0"
},
"tsd": {
"directory": "test"
}
}

3
resources/app/node_modules/socket.io/wrapper.mjs generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import io from "./dist/index.js";
export const {Server, Namespace, Socket} = io;