Skip to content

Commit ad4810c

Browse files
committed
feat(core): add "remoteAddr" key to core state
1 parent bbbb5f3 commit ad4810c

File tree

4 files changed

+47
-30
lines changed

4 files changed

+47
-30
lines changed

client_test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ describe("client", (test) => {
2222
},
2323
resolveInvalidNames: true,
2424
verbose: true,
25+
reconnect: true,
2526
};
2627

2728
const { client, server } = mockAll(options);
@@ -68,6 +69,7 @@ describe("client", (test) => {
6869

6970
test("have state initialized", () => {
7071
assertEquals(client.state, {
72+
remoteAddr: { hostname: "", port: 0 },
7173
nick: "me",
7274
username: "user",
7375
realname: "real name",
@@ -79,9 +81,13 @@ describe("client", (test) => {
7981
});
8082

8183
test("connect to server", async () => {
82-
const conn = await client.connect("");
84+
const conn = await client.connect("host");
8385

8486
assertExists(conn);
87+
assertEquals(client.state.remoteAddr, {
88+
hostname: "host",
89+
port: 6667,
90+
});
8591
});
8692

8793
test("register on connect", () => {

core/client.ts

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,20 @@ export interface CoreParams {
1717
"raw": Raw;
1818
"error": FatalError;
1919
};
20+
21+
state: {
22+
remoteAddr: RemoteAddr;
23+
};
2024
}
2125

2226
const BUFFER_SIZE = 4096;
2327
const PORT = 6667;
2428

29+
export interface RemoteAddr {
30+
hostname: string;
31+
port: number;
32+
}
33+
2534
export class FatalError extends Error {
2635
constructor(
2736
public type: "connect" | "read" | "write" | "close",
@@ -41,9 +50,10 @@ export type ExtendedClient<T extends PluginParams = {}> =
4150
& { readonly state: T["state"] }
4251
& T["commands"];
4352

44-
export type ExtendedOptions<T extends PluginParams = {}> =
53+
export type ExtendedOptions<T extends PluginParams = {}> = Readonly<
4554
& CoreParams["options"]
46-
& T["options"];
55+
& T["options"]
56+
>;
4757

4858
export type Plugin<T extends PluginParams = {}> = (
4959
client: ExtendedClient<T>,
@@ -61,15 +71,17 @@ export class CoreClient<
6171
private decoder = new TextDecoder();
6272
private encoder = new TextEncoder();
6373
private parser = new Parser();
64-
65-
readonly state: Readonly<{}> = {};
74+
readonly state: CoreParams["state"];
6675

6776
constructor(
6877
plugins: Plugin<any>[],
6978
options: Readonly<CoreParams["options"]>,
7079
) {
7180
super(options);
81+
7282
this.bufferSize = options.bufferSize ?? BUFFER_SIZE;
83+
this.state = { remoteAddr: { hostname: "", port: 0 } };
84+
7385
new Set(plugins).forEach((plugin) => plugin(this, options));
7486
this.resetErrorThrowingBehavior();
7587
}
@@ -80,20 +92,25 @@ export class CoreClient<
8092
*
8193
* Resolves when connected. */
8294
async connect(hostname: string, port = PORT): Promise<Deno.Conn | null> {
95+
this.state.remoteAddr = { hostname, port };
96+
8397
if (this.conn !== null) {
8498
this.close();
8599
}
86100

101+
const { remoteAddr } = this.state;
102+
this.emit("connecting", remoteAddr);
103+
87104
try {
88-
this.emit("connecting", { hostname, port });
89105
this.conn = await this.connectImpl({ hostname, port });
90-
this.emit("connected", getRemoteAddr(this.conn));
106+
this.emit("connected", remoteAddr);
91107
} catch (error) {
92108
this.emit("error", new FatalError("connect", error.message));
93109
return null;
94110
}
95111

96112
this.read(this.conn);
113+
97114
return this.conn;
98115
}
99116

@@ -130,7 +147,7 @@ export class CoreClient<
130147

131148
try {
132149
this.conn.close();
133-
this.emit("disconnected", getRemoteAddr(this.conn));
150+
this.emit("disconnected", this.state.remoteAddr);
134151
} catch (error) {
135152
this.emit("error", new FatalError("close", error.message));
136153
} finally {
@@ -174,14 +191,3 @@ export class CoreClient<
174191
this.close();
175192
}
176193
}
177-
178-
export interface RemoteAddr {
179-
hostname: string;
180-
port: number;
181-
}
182-
183-
function getRemoteAddr(conn: Deno.Conn): RemoteAddr {
184-
const addr = conn.remoteAddr as Deno.NetAddr;
185-
const { hostname, port } = addr;
186-
return { hostname, port };
187-
}

plugins/myinfo_test.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,16 @@ describe("plugins/myinfo", (test) => {
2626
server.send(":serverhost 004 me serverhost IRC-version iorsw ilmop");
2727
await client.once("myinfo");
2828

29-
assertEquals(client.state, {
30-
serverHost: "serverhost",
31-
serverVersion: "IRC-version",
32-
availableUserModes: ["i", "o", "r", "s", "w"],
33-
availableChannelModes: ["i", "l", "m", "o", "p"],
34-
});
29+
const {
30+
serverHost,
31+
serverVersion,
32+
availableUserModes,
33+
availableChannelModes,
34+
} = client.state;
35+
36+
assertEquals(serverHost, "serverhost");
37+
assertEquals(serverVersion, "IRC-version");
38+
assertEquals(availableUserModes, ["i", "o", "r", "s", "w"]);
39+
assertEquals(availableChannelModes, ["i", "l", "m", "o", "p"]);
3540
});
3641
});

plugins/register_on_connect_test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ describe("plugins/register_on_connect", (test) => {
5454
test("initialize user state", async () => {
5555
const { client } = await mock(plugins, options);
5656

57-
assertEquals(client.state, {
58-
nick: "me",
59-
username: "user",
60-
realname: "real name",
61-
});
57+
const { nick, username, realname } = client.state;
58+
59+
assertEquals(nick, "me");
60+
assertEquals(username, "user");
61+
assertEquals(realname, "real name");
6262
});
6363

6464
test("update nick on RPL_WELCOME", async () => {

0 commit comments

Comments
 (0)