Skip to content

Commit

Permalink
refactor(sio): break circular dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
darrachequesne committed Sep 19, 2024
1 parent 2da6cf6 commit 43ed7a9
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 106 deletions.
7 changes: 3 additions & 4 deletions packages/socket.io/lib/broadcast-operator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { BroadcastFlags, Room, SocketId } from "socket.io-adapter";
import { Handshake, RESERVED_EVENTS, Socket } from "./socket";
import { Handshake, RESERVED_EVENTS } from "./socket-types";
import { PacketType } from "socket.io-parser";
import type { Adapter } from "socket.io-adapter";
import type {
Expand Down Expand Up @@ -365,9 +365,8 @@ export class BroadcastOperator<EmitEvents extends EventsMap, SocketData>
})
.then((sockets) => {
return sockets.map((socket) => {
if (socket instanceof Socket) {
// FIXME the TypeScript compiler complains about missing private properties
return socket as unknown as RemoteSocket<EmitEvents, SocketData>;
if (socket.server) {
return socket as RemoteSocket<EmitEvents, SocketData>; // local instance
} else {
return new RemoteSocket(
this.adapter,
Expand Down
3 changes: 2 additions & 1 deletion packages/socket.io/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import {
import * as parser from "socket.io-parser";
import type { Encoder } from "socket.io-parser";
import debugModule from "debug";
import { Socket, DisconnectReason } from "./socket";
import { Socket } from "./socket";
import { DisconnectReason } from "./socket-types";
import type { BroadcastOperator, RemoteSocket } from "./broadcast-operator";
import {
EventsMap,
Expand Down
101 changes: 101 additions & 0 deletions packages/socket.io/lib/socket-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import type { NamespaceReservedEventsMap } from "./namespace";
import type { IncomingHttpHeaders } from "http";
import type { ParsedUrlQuery } from "querystring";

type ClientReservedEvents = "connect_error";

// TODO for next major release: cleanup disconnect reasons
export type DisconnectReason =
// Engine.IO close reasons
| "transport error"
| "transport close"
| "forced close"
| "ping timeout"
| "parse error"
// Socket.IO disconnect reasons
| "server shutting down"
| "forced server close"
| "client namespace disconnect"
| "server namespace disconnect";

export interface SocketReservedEventsMap {
disconnect: (reason: DisconnectReason, description?: any) => void;
disconnecting: (reason: DisconnectReason, description?: any) => void;
error: (err: Error) => void;
}

// EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener
export interface EventEmitterReservedEventsMap {
newListener: (
eventName: string | Symbol,
listener: (...args: any[]) => void,
) => void;
removeListener: (
eventName: string | Symbol,
listener: (...args: any[]) => void,
) => void;
}

export const RESERVED_EVENTS: ReadonlySet<string | Symbol> = new Set<
| ClientReservedEvents
| keyof NamespaceReservedEventsMap<never, never, never, never>
| keyof SocketReservedEventsMap
| keyof EventEmitterReservedEventsMap
>(<const>[
"connect",
"connect_error",
"disconnect",
"disconnecting",
"newListener",
"removeListener",
]);

/**
* The handshake details
*/
export interface Handshake {
/**
* The headers sent as part of the handshake
*/
headers: IncomingHttpHeaders;

/**
* The date of creation (as string)
*/
time: string;

/**
* The ip of the client
*/
address: string;

/**
* Whether the connection is cross-domain
*/
xdomain: boolean;

/**
* Whether the connection is secure
*/
secure: boolean;

/**
* The date of creation (as unix timestamp)
*/
issued: number;

/**
* The request URL string
*/
url: string;

/**
* The query object
*/
query: ParsedUrlQuery;

/**
* The auth object
*/
auth: { [key: string]: any };
}
109 changes: 8 additions & 101 deletions packages/socket.io/lib/socket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {
StrictEventEmitter,
} from "./typed-events";
import type { Client } from "./client";
import type { Namespace, NamespaceReservedEventsMap } from "./namespace";
import type { IncomingHttpHeaders, IncomingMessage } from "http";
import type { Namespace } from "./namespace";
import type { IncomingMessage } from "http";
import type {
Adapter,
BroadcastFlags,
Expand All @@ -26,27 +26,16 @@ import type {
SocketId,
} from "socket.io-adapter";
import base64id from "base64id";
import type { ParsedUrlQuery } from "querystring";
import { BroadcastOperator } from "./broadcast-operator";
import {
DisconnectReason,
Handshake,
RESERVED_EVENTS,
SocketReservedEventsMap,
} from "./socket-types";

const debug = debugModule("socket.io:socket");

type ClientReservedEvents = "connect_error";

// TODO for next major release: cleanup disconnect reasons
export type DisconnectReason =
// Engine.IO close reasons
| "transport error"
| "transport close"
| "forced close"
| "ping timeout"
| "parse error"
// Socket.IO disconnect reasons
| "server shutting down"
| "forced server close"
| "client namespace disconnect"
| "server namespace disconnect";

const RECOVERABLE_DISCONNECT_REASONS: ReadonlySet<DisconnectReason> = new Set([
"transport error",
"transport close",
Expand All @@ -56,88 +45,6 @@ const RECOVERABLE_DISCONNECT_REASONS: ReadonlySet<DisconnectReason> = new Set([
"forced server close",
]);

export interface SocketReservedEventsMap {
disconnect: (reason: DisconnectReason, description?: any) => void;
disconnecting: (reason: DisconnectReason, description?: any) => void;
error: (err: Error) => void;
}

// EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener
export interface EventEmitterReservedEventsMap {
newListener: (
eventName: string | Symbol,
listener: (...args: any[]) => void,
) => void;
removeListener: (
eventName: string | Symbol,
listener: (...args: any[]) => void,
) => void;
}

export const RESERVED_EVENTS: ReadonlySet<string | Symbol> = new Set<
| ClientReservedEvents
| keyof NamespaceReservedEventsMap<never, never, never, never>
| keyof SocketReservedEventsMap
| keyof EventEmitterReservedEventsMap
>(<const>[
"connect",
"connect_error",
"disconnect",
"disconnecting",
"newListener",
"removeListener",
]);

/**
* The handshake details
*/
export interface Handshake {
/**
* The headers sent as part of the handshake
*/
headers: IncomingHttpHeaders;

/**
* The date of creation (as string)
*/
time: string;

/**
* The ip of the client
*/
address: string;

/**
* Whether the connection is cross-domain
*/
xdomain: boolean;

/**
* Whether the connection is secure
*/
secure: boolean;

/**
* The date of creation (as unix timestamp)
*/
issued: number;

/**
* The request URL string
*/
url: string;

/**
* The query object
*/
query: ParsedUrlQuery;

/**
* The auth object
*/
auth: { [key: string]: any };
}

/**
* `[eventName, ...args]`
*/
Expand Down

0 comments on commit 43ed7a9

Please sign in to comment.