@ac-kit/node 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +94 -0
- package/README.md +7 -2
- package/dist/error/process-exit-error.d.ts +16 -3
- package/dist/error/process-exit-error.d.ts.map +1 -1
- package/dist/error/process-exit-error.js +51 -7
- package/dist/error/process-exit-error.js.map +1 -1
- package/dist/fs/path-escape-error.d.ts +20 -0
- package/dist/fs/path-escape-error.d.ts.map +1 -0
- package/dist/fs/path-escape-error.js +23 -0
- package/dist/fs/path-escape-error.js.map +1 -0
- package/dist/fs/path-within.d.ts +121 -0
- package/dist/fs/path-within.d.ts.map +1 -0
- package/dist/fs/path-within.js +196 -0
- package/dist/fs/path-within.js.map +1 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/net/connection-closed-error.d.ts +12 -0
- package/dist/net/connection-closed-error.d.ts.map +1 -0
- package/dist/net/connection-closed-error.js +15 -0
- package/dist/net/connection-closed-error.js.map +1 -0
- package/dist/net/dgram-socket.d.ts +4 -3
- package/dist/net/dgram-socket.d.ts.map +1 -1
- package/dist/net/dgram-socket.js +38 -38
- package/dist/net/dgram-socket.js.map +1 -1
- package/dist/net/inet-address.d.ts +20 -0
- package/dist/net/inet-address.d.ts.map +1 -0
- package/dist/net/inet-address.js +42 -0
- package/dist/net/inet-address.js.map +1 -0
- package/dist/net/inet-endpoint.d.ts +7 -0
- package/dist/net/inet-endpoint.d.ts.map +1 -0
- package/dist/net/inet-endpoint.js +2 -0
- package/dist/net/inet-endpoint.js.map +1 -0
- package/dist/net/inet-socket.d.ts +65 -0
- package/dist/net/inet-socket.d.ts.map +1 -0
- package/dist/net/inet-socket.js +99 -0
- package/dist/net/inet-socket.js.map +1 -0
- package/dist/net/ipc-server.d.ts +63 -0
- package/dist/net/ipc-server.d.ts.map +1 -0
- package/dist/net/ipc-server.js +75 -0
- package/dist/net/ipc-server.js.map +1 -0
- package/dist/net/ipc-socket.d.ts +55 -22
- package/dist/net/ipc-socket.d.ts.map +1 -1
- package/dist/net/ipc-socket.js +50 -46
- package/dist/net/ipc-socket.js.map +1 -1
- package/dist/net/stream-server.d.ts +80 -0
- package/dist/net/stream-server.d.ts.map +1 -0
- package/dist/net/stream-server.js +129 -0
- package/dist/net/stream-server.js.map +1 -0
- package/dist/net/stream-socket.d.ts +37 -8
- package/dist/net/stream-socket.d.ts.map +1 -1
- package/dist/net/stream-socket.js +80 -27
- package/dist/net/stream-socket.js.map +1 -1
- package/dist/net/tcp-server.d.ts +31 -73
- package/dist/net/tcp-server.d.ts.map +1 -1
- package/dist/net/tcp-server.js +45 -150
- package/dist/net/tcp-server.js.map +1 -1
- package/dist/net/tcp-socket.d.ts +21 -61
- package/dist/net/tcp-socket.d.ts.map +1 -1
- package/dist/net/tcp-socket.js +23 -126
- package/dist/net/tcp-socket.js.map +1 -1
- package/dist/net/tls-server.d.ts +87 -0
- package/dist/net/tls-server.d.ts.map +1 -0
- package/dist/net/tls-server.js +103 -0
- package/dist/net/tls-server.js.map +1 -0
- package/dist/net/tls-socket.d.ts +235 -14
- package/dist/net/tls-socket.d.ts.map +1 -1
- package/dist/net/tls-socket.js +241 -91
- package/dist/net/tls-socket.js.map +1 -1
- package/package.json +4 -4
- package/dist/shell/escape-command-arg.d.ts +0 -9
- package/dist/shell/escape-command-arg.d.ts.map +0 -1
- package/dist/shell/escape-command-arg.js +0 -13
- package/dist/shell/escape-command-arg.js.map +0 -1
- package/dist/shell/escape-command.d.ts +0 -10
- package/dist/shell/escape-command.d.ts.map +0 -1
- package/dist/shell/escape-command.js +0 -12
- package/dist/shell/escape-command.js.map +0 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { toInetAddress } from "./inet-address.js";
|
|
2
|
+
import { StreamSocket } from "./stream-socket.js";
|
|
3
|
+
/**
|
|
4
|
+
* Base class for sockets whose transport is an IP connection.
|
|
5
|
+
*
|
|
6
|
+
* On top of {@link StreamSocket} it exposes the endpoint accessors and the
|
|
7
|
+
* socket options that only make sense over IP, plus the connection-attempt and
|
|
8
|
+
* name-resolution events Node.js emits while dialling.
|
|
9
|
+
*
|
|
10
|
+
* It is shared by {@link TcpSocket} and {@link TlsSocket}: both run over IP, but
|
|
11
|
+
* they establish their connection differently, so neither can be expressed as a
|
|
12
|
+
* subclass of the other.
|
|
13
|
+
*/
|
|
14
|
+
export class InetSocket extends StreamSocket {
|
|
15
|
+
/**
|
|
16
|
+
* Remote endpoint of the socket, or `null` while it is not connected.
|
|
17
|
+
*
|
|
18
|
+
* @throws {UnsupportedError} If the socket family is not IPv4 or IPv6.
|
|
19
|
+
*/
|
|
20
|
+
get remoteEndpoint() {
|
|
21
|
+
const address = this.socket.remoteAddress;
|
|
22
|
+
const port = this.socket.remotePort;
|
|
23
|
+
const family = this.socket.remoteFamily;
|
|
24
|
+
if (address === undefined || port === undefined || family === undefined) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
...toInetAddress(family, address),
|
|
29
|
+
port,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Local endpoint of the socket, or `null` while it is not connected.
|
|
34
|
+
*
|
|
35
|
+
* @throws {UnsupportedError} If the socket family is not IPv4 or IPv6.
|
|
36
|
+
*/
|
|
37
|
+
get localEndpoint() {
|
|
38
|
+
const address = this.socket.localAddress;
|
|
39
|
+
const port = this.socket.localPort;
|
|
40
|
+
const family = this.socket.localFamily;
|
|
41
|
+
if (address === undefined || port === undefined || family === undefined) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
...toInetAddress(family, address),
|
|
46
|
+
port,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Sets the keep-alive option for the socket.
|
|
51
|
+
*
|
|
52
|
+
* @param enable Whether to enable keep-alive.
|
|
53
|
+
* @param initialDelay The initial delay in milliseconds before the first
|
|
54
|
+
* keep-alive probe.
|
|
55
|
+
*/
|
|
56
|
+
setKeepAlive(enable, initialDelay) {
|
|
57
|
+
this.socket.setKeepAlive(enable, initialDelay);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Enables or disables the Nagle algorithm for the socket.
|
|
61
|
+
*
|
|
62
|
+
* @param noDelay Whether to disable the Nagle algorithm.
|
|
63
|
+
*/
|
|
64
|
+
setNoDelay(noDelay) {
|
|
65
|
+
this.socket.setNoDelay(noDelay);
|
|
66
|
+
}
|
|
67
|
+
setupEventForwarding() {
|
|
68
|
+
super.setupEventForwarding();
|
|
69
|
+
this.socket.on("connectionAttempt", (ip, port, family) => {
|
|
70
|
+
this.dispatch("connectionAttempt", [
|
|
71
|
+
{
|
|
72
|
+
...toInetAddress(family, ip),
|
|
73
|
+
port,
|
|
74
|
+
},
|
|
75
|
+
]);
|
|
76
|
+
});
|
|
77
|
+
this.socket.on("connectionAttemptFailed", (ip, port, family, error) => {
|
|
78
|
+
this.dispatch("connectionAttemptFailed", [
|
|
79
|
+
{
|
|
80
|
+
...toInetAddress(family, ip),
|
|
81
|
+
port,
|
|
82
|
+
},
|
|
83
|
+
error,
|
|
84
|
+
]);
|
|
85
|
+
});
|
|
86
|
+
this.socket.on("connectionAttemptTimeout", (ip, port, family) => {
|
|
87
|
+
this.dispatch("connectionAttemptTimeout", [
|
|
88
|
+
{
|
|
89
|
+
...toInetAddress(family, ip),
|
|
90
|
+
port,
|
|
91
|
+
},
|
|
92
|
+
]);
|
|
93
|
+
});
|
|
94
|
+
this.socket.on("lookup", (error, address, family, host) => {
|
|
95
|
+
this.dispatch("lookup", [error, toInetAddress(family, address), host]);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=inet-socket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inet-socket.js","sourceRoot":"","sources":["../../src/net/inet-socket.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as net from "node:net";
|
|
2
|
+
import type { Except } from "type-fest";
|
|
3
|
+
import { IpcSocket } from "./ipc-socket.js";
|
|
4
|
+
import { StreamServer, type StreamServerEvents } from "./stream-server.js";
|
|
5
|
+
/** Event map for {@link IpcServer}. */
|
|
6
|
+
export type IpcServerEvents = StreamServerEvents & {
|
|
7
|
+
/** Emitted when a new connection is accepted. */
|
|
8
|
+
connection: [socket: IpcSocket];
|
|
9
|
+
};
|
|
10
|
+
/** Options accepted by {@link IpcServer.from}. */
|
|
11
|
+
export type IpcServerOptions = net.ServerOpts;
|
|
12
|
+
/** Options accepted by {@link IpcServer.listen}. */
|
|
13
|
+
export type IpcServerListenOptions = Except<net.ListenOptions, "port" | "host" | "path" | "handle" | "ipv6Only" | "reusePort">;
|
|
14
|
+
/**
|
|
15
|
+
* Server accepting connections on a Unix domain socket or a Windows named pipe.
|
|
16
|
+
*
|
|
17
|
+
* Example usage:
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* const server = IpcServer.from();
|
|
21
|
+
* server.subscribe("connection", (socket) => {
|
|
22
|
+
* socket.stream.on("data", (data) => {
|
|
23
|
+
* console.log("Received:", data.toString());
|
|
24
|
+
* });
|
|
25
|
+
* });
|
|
26
|
+
* await server.listen("/var/run/app.sock");
|
|
27
|
+
* // ... later
|
|
28
|
+
* await server.close();
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* On Unix the socket file is removed when the server closes, but not when the
|
|
32
|
+
* process exits abnormally: a stale file makes the next bind fail with
|
|
33
|
+
* `EADDRINUSE`.
|
|
34
|
+
*/
|
|
35
|
+
export declare class IpcServer extends StreamServer<net.Server, IpcServerEvents> {
|
|
36
|
+
/**
|
|
37
|
+
* Creates a new {@link IpcServer} instance.
|
|
38
|
+
*
|
|
39
|
+
* @param options Options for creating the underlying Node.js server.
|
|
40
|
+
* @returns A new `IpcServer` instance.
|
|
41
|
+
*/
|
|
42
|
+
static from(options?: IpcServerOptions): IpcServer;
|
|
43
|
+
/**
|
|
44
|
+
* Binds the server to the given path and resolves once it is listening.
|
|
45
|
+
*
|
|
46
|
+
* @param path Filesystem path of the Unix domain socket, or the name of the
|
|
47
|
+
* Windows named pipe.
|
|
48
|
+
* @param options Additional listen options.
|
|
49
|
+
* @returns A promise that resolves once the server is listening.
|
|
50
|
+
* @throws When the path is already in use or cannot be bound.
|
|
51
|
+
*/
|
|
52
|
+
listen(path: string, options?: IpcServerListenOptions): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Returns the path the server is bound to.
|
|
55
|
+
*
|
|
56
|
+
* @returns The bound path, or `null` when the server is not listening.
|
|
57
|
+
* @throws {UnsupportedError} When the server is bound to an IP endpoint
|
|
58
|
+
* rather than a path. Use {@link TcpServer} for those.
|
|
59
|
+
*/
|
|
60
|
+
address(): string | null;
|
|
61
|
+
protected setupEventForwarding(): void;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=ipc-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipc-server.d.ts","sourceRoot":"","sources":["../../src/net/ipc-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAGhC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE3E,uCAAuC;AACvC,MAAM,MAAM,eAAe,GAAG,kBAAkB,GAAG;IAClD,iDAAiD;IACjD,UAAU,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CAChC,CAAC;AAEF,kDAAkD;AAClD,MAAM,MAAM,gBAAgB,GAAG,GAAG,CAAC,UAAU,CAAC;AAE9C,oDAAoD;AACpD,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAC1C,GAAG,CAAC,aAAa,EACjB,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,CAC9D,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,SAAU,SAAQ,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC;IACvE;;;;;OAKG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAEjD;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKpE;IAED;;;;;;OAMG;IACH,OAAO,IAAI,MAAM,GAAG,IAAI,CAcvB;IAED,UAAmB,oBAAoB,IAAI,IAAI,CAM9C;CACD"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as net from "node:net";
|
|
2
|
+
import { UnsupportedError } from "@ac-kit/core";
|
|
3
|
+
import { IpcSocket } from "./ipc-socket.js";
|
|
4
|
+
import { StreamServer } from "./stream-server.js";
|
|
5
|
+
/**
|
|
6
|
+
* Server accepting connections on a Unix domain socket or a Windows named pipe.
|
|
7
|
+
*
|
|
8
|
+
* Example usage:
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* const server = IpcServer.from();
|
|
12
|
+
* server.subscribe("connection", (socket) => {
|
|
13
|
+
* socket.stream.on("data", (data) => {
|
|
14
|
+
* console.log("Received:", data.toString());
|
|
15
|
+
* });
|
|
16
|
+
* });
|
|
17
|
+
* await server.listen("/var/run/app.sock");
|
|
18
|
+
* // ... later
|
|
19
|
+
* await server.close();
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* On Unix the socket file is removed when the server closes, but not when the
|
|
23
|
+
* process exits abnormally: a stale file makes the next bind fail with
|
|
24
|
+
* `EADDRINUSE`.
|
|
25
|
+
*/
|
|
26
|
+
export class IpcServer extends StreamServer {
|
|
27
|
+
/**
|
|
28
|
+
* Creates a new {@link IpcServer} instance.
|
|
29
|
+
*
|
|
30
|
+
* @param options Options for creating the underlying Node.js server.
|
|
31
|
+
* @returns A new `IpcServer` instance.
|
|
32
|
+
*/
|
|
33
|
+
static from(options) {
|
|
34
|
+
return new IpcServer(net.createServer(options));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Binds the server to the given path and resolves once it is listening.
|
|
38
|
+
*
|
|
39
|
+
* @param path Filesystem path of the Unix domain socket, or the name of the
|
|
40
|
+
* Windows named pipe.
|
|
41
|
+
* @param options Additional listen options.
|
|
42
|
+
* @returns A promise that resolves once the server is listening.
|
|
43
|
+
* @throws When the path is already in use or cannot be bound.
|
|
44
|
+
*/
|
|
45
|
+
listen(path, options) {
|
|
46
|
+
return this.listenOn({
|
|
47
|
+
...options,
|
|
48
|
+
path,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Returns the path the server is bound to.
|
|
53
|
+
*
|
|
54
|
+
* @returns The bound path, or `null` when the server is not listening.
|
|
55
|
+
* @throws {UnsupportedError} When the server is bound to an IP endpoint
|
|
56
|
+
* rather than a path. Use {@link TcpServer} for those.
|
|
57
|
+
*/
|
|
58
|
+
address() {
|
|
59
|
+
const address = this.server.address();
|
|
60
|
+
if (address === null) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
if (typeof address !== "string") {
|
|
64
|
+
throw new UnsupportedError(`Unsupported address type: AddressInfo. Expected a path string.`);
|
|
65
|
+
}
|
|
66
|
+
return address;
|
|
67
|
+
}
|
|
68
|
+
setupEventForwarding() {
|
|
69
|
+
super.setupEventForwarding();
|
|
70
|
+
this.server.on("connection", (socket) => {
|
|
71
|
+
this.dispatch("connection", [new IpcSocket(socket)]);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=ipc-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipc-server.js","sourceRoot":"","sources":["../../src/net/ipc-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAA2B,MAAM,oBAAoB,CAAC;AAiB3E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,SAAU,SAAQ,YAAyC;IACvE;;;;;OAKG;IACH,MAAM,CAAC,IAAI,CAAC,OAA0B;QACrC,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,IAAY,EAAE,OAAgC;QACpD,OAAO,IAAI,CAAC,QAAQ,CAAC;YACpB,GAAG,OAAO;YACV,IAAI;SACJ,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,OAAO;QACN,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAEtC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QACb,CAAC;QAED,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,IAAI,gBAAgB,CACzB,gEAAgE,CAChE,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IAChB,CAAC;IAEkB,oBAAoB;QACtC,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAE7B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE;YACvC,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACJ,CAAC;CACD"}
|
package/dist/net/ipc-socket.d.ts
CHANGED
|
@@ -1,34 +1,67 @@
|
|
|
1
1
|
import * as net from "node:net";
|
|
2
|
-
import { InetEndpoint } from "@ac-kit/core";
|
|
3
2
|
import type { Except } from "type-fest";
|
|
4
3
|
import { StreamSocket, type StreamSocketEvents } from "./stream-socket.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Event map for {@link IpcSocket}.
|
|
6
|
+
*
|
|
7
|
+
* A local endpoint has no name resolution and no connection-attempt fan-out, so
|
|
8
|
+
* it adds nothing to {@link StreamSocketEvents}.
|
|
9
|
+
*/
|
|
10
|
+
export type IpcSocketEvents = StreamSocketEvents;
|
|
11
|
+
/** Options accepted by {@link IpcSocket.from} and {@link IpcSocket.fromFd}. */
|
|
12
|
+
export type IpcSocketOptions = Except<net.SocketConstructorOpts, "fd">;
|
|
13
|
+
/** Options accepted by {@link IpcSocket.connect}. */
|
|
14
|
+
export type IpcSocketConnectOptions = Except<net.IpcSocketConnectOpts, "path"> & {
|
|
15
|
+
/** Aborts the connection attempt and destroys the socket. */
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Stream socket over a Unix domain socket or a Windows named pipe.
|
|
20
|
+
*
|
|
21
|
+
* Example usage:
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* const socket = IpcSocket.from();
|
|
25
|
+
* await socket.connect("/var/run/app.sock");
|
|
26
|
+
* await socket.write(Buffer.from("ping\n"));
|
|
27
|
+
* await socket.end({ waitForClose: true });
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* A pipe inherited from a parent process is already connected and is adopted
|
|
31
|
+
* through {@link IpcSocket.fromFd} instead.
|
|
32
|
+
*/
|
|
33
|
+
export declare class IpcSocket<TSocket extends net.Socket = net.Socket, TEvents extends IpcSocketEvents = IpcSocketEvents> extends StreamSocket<TSocket, TEvents> {
|
|
11
34
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
35
|
+
* Creates a new {@link IpcSocket} instance.
|
|
36
|
+
*
|
|
37
|
+
* @param options Options for creating the underlying Node.js socket.
|
|
38
|
+
* @returns A new `IpcSocket` instance.
|
|
14
39
|
*/
|
|
15
|
-
|
|
40
|
+
static from(options?: IpcSocketOptions): IpcSocket;
|
|
16
41
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
42
|
+
* Adopts an already-open file descriptor, such as a pipe inherited from a
|
|
43
|
+
* parent process. The returned socket is connected and needs no
|
|
44
|
+
* {@link IpcSocket.connect} call.
|
|
45
|
+
*
|
|
46
|
+
* The descriptor is adopted as bidirectional; pass `readable` or `writable`
|
|
47
|
+
* to adopt a one-way pipe, since Node.js disables both by default for a
|
|
48
|
+
* descriptor-backed socket.
|
|
49
|
+
*
|
|
50
|
+
* @param fd The open file descriptor to adopt.
|
|
51
|
+
* @param options Options for creating the underlying Node.js socket.
|
|
52
|
+
* @returns A new, already connected `IpcSocket` instance.
|
|
19
53
|
*/
|
|
20
|
-
|
|
21
|
-
};
|
|
22
|
-
export declare class IpcSocket<TSock extends net.Socket = net.Socket, TEvents extends IpcSocketEvents = IpcSocketEvents> extends StreamSocket<TSock, TEvents> {
|
|
54
|
+
static fromFd(fd: number, options?: IpcSocketOptions): IpcSocket;
|
|
23
55
|
/**
|
|
24
|
-
*
|
|
56
|
+
* Connects to the endpoint listening on the given path.
|
|
25
57
|
*
|
|
26
|
-
* @param
|
|
27
|
-
*
|
|
58
|
+
* @param path Filesystem path of the Unix domain socket, or the name of the
|
|
59
|
+
* Windows named pipe.
|
|
60
|
+
* @param options Connection options, including an optional abort signal.
|
|
61
|
+
* @returns A promise that resolves when the connection is established.
|
|
62
|
+
* @throws When the connection fails, when the socket closes before
|
|
63
|
+
* connecting, or when the signal is aborted.
|
|
28
64
|
*/
|
|
29
|
-
|
|
30
|
-
constructor(sock: TSock);
|
|
31
|
-
connect(path: string, options?: Except<net.IpcSocketConnectOpts, "path">): Promise<void>;
|
|
32
|
-
protected setupEventForwarding(): void;
|
|
65
|
+
connect(path: string, options?: IpcSocketConnectOptions): Promise<void>;
|
|
33
66
|
}
|
|
34
67
|
//# sourceMappingURL=ipc-socket.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ipc-socket.d.ts","sourceRoot":"","sources":["../../src/net/ipc-socket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,OAAO,
|
|
1
|
+
{"version":3,"file":"ipc-socket.d.ts","sourceRoot":"","sources":["../../src/net/ipc-socket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE3E;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAEjD,+EAA+E;AAC/E,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;AAEvE,qDAAqD;AACrD,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAC3C,GAAG,CAAC,oBAAoB,EACxB,MAAM,CACN,GAAG;IACH,6DAA6D;IAC7D,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,qBAAa,SAAS,CACrB,OAAO,SAAS,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,EACvC,OAAO,SAAS,eAAe,GAAG,eAAe,CAChD,SAAQ,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC;IACvC;;;;;OAKG;IACH,OAAgB,IAAI,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAE1D;IAED;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAI/D;IAED;;;;;;;;;OASG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAYtE;CACD"}
|
package/dist/net/ipc-socket.js
CHANGED
|
@@ -1,62 +1,66 @@
|
|
|
1
1
|
import * as net from "node:net";
|
|
2
|
-
import { composeInetAddress } from "@ac-kit/core";
|
|
3
2
|
import { StreamSocket } from "./stream-socket.js";
|
|
3
|
+
/**
|
|
4
|
+
* Stream socket over a Unix domain socket or a Windows named pipe.
|
|
5
|
+
*
|
|
6
|
+
* Example usage:
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* const socket = IpcSocket.from();
|
|
10
|
+
* await socket.connect("/var/run/app.sock");
|
|
11
|
+
* await socket.write(Buffer.from("ping\n"));
|
|
12
|
+
* await socket.end({ waitForClose: true });
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* A pipe inherited from a parent process is already connected and is adopted
|
|
16
|
+
* through {@link IpcSocket.fromFd} instead.
|
|
17
|
+
*/
|
|
4
18
|
export class IpcSocket extends StreamSocket {
|
|
5
19
|
/**
|
|
6
20
|
* Creates a new {@link IpcSocket} instance.
|
|
7
21
|
*
|
|
8
22
|
* @param options Options for creating the underlying Node.js socket.
|
|
9
|
-
* @returns A new `
|
|
23
|
+
* @returns A new `IpcSocket` instance.
|
|
10
24
|
*/
|
|
11
25
|
static from(options) {
|
|
12
26
|
return new IpcSocket(new net.Socket(options));
|
|
13
27
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Adopts an already-open file descriptor, such as a pipe inherited from a
|
|
30
|
+
* parent process. The returned socket is connected and needs no
|
|
31
|
+
* {@link IpcSocket.connect} call.
|
|
32
|
+
*
|
|
33
|
+
* The descriptor is adopted as bidirectional; pass `readable` or `writable`
|
|
34
|
+
* to adopt a one-way pipe, since Node.js disables both by default for a
|
|
35
|
+
* descriptor-backed socket.
|
|
36
|
+
*
|
|
37
|
+
* @param fd The open file descriptor to adopt.
|
|
38
|
+
* @param options Options for creating the underlying Node.js socket.
|
|
39
|
+
* @returns A new, already connected `IpcSocket` instance.
|
|
40
|
+
*/
|
|
41
|
+
static fromFd(fd, options) {
|
|
42
|
+
return new IpcSocket(new net.Socket({ readable: true, writable: true, ...options, fd }));
|
|
17
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Connects to the endpoint listening on the given path.
|
|
46
|
+
*
|
|
47
|
+
* @param path Filesystem path of the Unix domain socket, or the name of the
|
|
48
|
+
* Windows named pipe.
|
|
49
|
+
* @param options Connection options, including an optional abort signal.
|
|
50
|
+
* @returns A promise that resolves when the connection is established.
|
|
51
|
+
* @throws When the connection fails, when the socket closes before
|
|
52
|
+
* connecting, or when the signal is aborted.
|
|
53
|
+
*/
|
|
18
54
|
connect(path, options) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}, () => {
|
|
29
|
-
this.sock.removeListener("error", handleError);
|
|
30
|
-
resolve();
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
setupEventForwarding() {
|
|
35
|
-
super.setupEventForwarding();
|
|
36
|
-
this.sock.on("connectionAttempt", (ip, port, family) => {
|
|
37
|
-
this.dispatch("connectionAttempt", [
|
|
38
|
-
{
|
|
39
|
-
...composeInetAddress(family, ip),
|
|
40
|
-
port,
|
|
41
|
-
},
|
|
42
|
-
]);
|
|
43
|
-
});
|
|
44
|
-
this.sock.on("connectionAttemptFailed", (ip, port, family, error) => {
|
|
45
|
-
this.dispatch("connectionAttemptFailed", [
|
|
46
|
-
{
|
|
47
|
-
...composeInetAddress(family, ip),
|
|
48
|
-
port,
|
|
49
|
-
},
|
|
50
|
-
error,
|
|
51
|
-
]);
|
|
52
|
-
});
|
|
53
|
-
this.sock.on("connectionAttemptTimeout", (ip, port, family) => {
|
|
54
|
-
this.dispatch("connectionAttemptTimeout", [
|
|
55
|
-
{
|
|
56
|
-
...composeInetAddress(family, ip),
|
|
57
|
-
port,
|
|
58
|
-
},
|
|
59
|
-
]);
|
|
55
|
+
const { signal, ...connectOptions } = options ?? {};
|
|
56
|
+
return this.awaitReady("connect", {
|
|
57
|
+
signal,
|
|
58
|
+
start: () => {
|
|
59
|
+
this.socket.connect({
|
|
60
|
+
...connectOptions,
|
|
61
|
+
path,
|
|
62
|
+
});
|
|
63
|
+
},
|
|
60
64
|
});
|
|
61
65
|
}
|
|
62
66
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ipc-socket.js","sourceRoot":"","sources":["../../src/net/ipc-socket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"ipc-socket.js","sourceRoot":"","sources":["../../src/net/ipc-socket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAIhC,OAAO,EAAE,YAAY,EAA2B,MAAM,oBAAoB,CAAC;AAsB3E;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,SAGX,SAAQ,YAA8B;IACvC;;;;;OAKG;IACH,MAAM,CAAU,IAAI,CAAC,OAA0B;QAC9C,OAAO,IAAI,SAAS,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,MAAM,CAAC,EAAU,EAAE,OAA0B;QACnD,OAAO,IAAI,SAAS,CACnB,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,CAClE,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACH,OAAO,CAAC,IAAY,EAAE,OAAiC;QACtD,MAAM,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;QAEpD,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE;YACjC,MAAM;YACN,KAAK,EAAE,GAAG,EAAE;gBACX,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;oBACnB,GAAG,cAAc;oBACjB,IAAI;iBACJ,CAAC,CAAC;YACJ,CAAC;SACD,CAAC,CAAC;IACJ,CAAC;CACD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as net from "node:net";
|
|
2
|
+
import { EventDispatcherMapBase, IEventDispatcherMap } from "@ac-kit/async";
|
|
3
|
+
import { type IError } from "@ac-kit/core";
|
|
4
|
+
/** Event map for {@link StreamServer} lifecycle events. */
|
|
5
|
+
export type StreamServerEvents = {
|
|
6
|
+
/** Emitted once the server stopped listening and all connections ended. */
|
|
7
|
+
close: [];
|
|
8
|
+
/** Emitted when an error occurs on the server. */
|
|
9
|
+
error: [error: IError];
|
|
10
|
+
/** Emitted once the server is bound and accepting connections. */
|
|
11
|
+
listening: [];
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Base class for stream-oriented servers.
|
|
15
|
+
*
|
|
16
|
+
* This abstraction wraps a {@link net.Server} instance and exposes the lifecycle
|
|
17
|
+
* that is independent of the transport: binding state, connection accounting,
|
|
18
|
+
* event-loop referencing and closing.
|
|
19
|
+
*
|
|
20
|
+
* Binding and address reporting are transport-specific and are added by the
|
|
21
|
+
* concrete subclasses {@link TcpServer} and {@link IpcServer}, as is the
|
|
22
|
+
* "connection" event, whose payload is a socket of the matching type.
|
|
23
|
+
*/
|
|
24
|
+
export declare class StreamServer<TServer extends net.Server = net.Server, TEvents extends StreamServerEvents = StreamServerEvents> extends EventDispatcherMapBase<TEvents> implements IEventDispatcherMap<TEvents> {
|
|
25
|
+
protected readonly server: TServer;
|
|
26
|
+
protected readonly handledErrorEvents: Set<IError>;
|
|
27
|
+
/**
|
|
28
|
+
* Creates a new {@link StreamServer} instance.
|
|
29
|
+
*
|
|
30
|
+
* @param server The underlying Node.js server.
|
|
31
|
+
*/
|
|
32
|
+
constructor(server: TServer);
|
|
33
|
+
/** Whether the server is currently listening for connections. */
|
|
34
|
+
get listening(): boolean;
|
|
35
|
+
/** Maximum number of concurrent connections accepted by the server. */
|
|
36
|
+
get maxConnections(): number;
|
|
37
|
+
/**
|
|
38
|
+
* Updates the maximum number of concurrent connections.
|
|
39
|
+
*
|
|
40
|
+
* Connections accepted beyond this limit are dropped.
|
|
41
|
+
*/
|
|
42
|
+
set maxConnections(maxConnections: number);
|
|
43
|
+
/**
|
|
44
|
+
* Counts the connections currently handled by the server.
|
|
45
|
+
*
|
|
46
|
+
* @returns A promise that resolves with the connection count.
|
|
47
|
+
*/
|
|
48
|
+
getConnections(): Promise<number>;
|
|
49
|
+
/**
|
|
50
|
+
* Marks the server as referenced, preventing the Node.js process from exiting
|
|
51
|
+
* while it is listening.
|
|
52
|
+
*/
|
|
53
|
+
ref(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Marks the server as unreferenced, allowing the Node.js process to exit even
|
|
56
|
+
* while it is listening.
|
|
57
|
+
*/
|
|
58
|
+
unref(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Stops the server from accepting new connections. Established connections
|
|
61
|
+
* are not closed; the promise resolves once the last of them ends.
|
|
62
|
+
*
|
|
63
|
+
* @returns A promise that resolves when the server is fully closed.
|
|
64
|
+
* @throws When the server was not listening.
|
|
65
|
+
*/
|
|
66
|
+
close(): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Binds the server and resolves once it is listening.
|
|
69
|
+
*
|
|
70
|
+
* The bind error is consumed rather than dispatched, so that a rejected
|
|
71
|
+
* promise is not also reported as an unhandled "error" event.
|
|
72
|
+
*
|
|
73
|
+
* @param options The listen options to bind with. Without any, the server
|
|
74
|
+
* binds a system-assigned port on every interface.
|
|
75
|
+
* @returns A promise that resolves once the server is listening.
|
|
76
|
+
*/
|
|
77
|
+
protected listenOn(options?: net.ListenOptions): Promise<void>;
|
|
78
|
+
protected setupEventForwarding(): void;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=stream-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-server.d.ts","sourceRoot":"","sources":["../../src/net/stream-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,2DAA2D;AAC3D,MAAM,MAAM,kBAAkB,GAAG;IAChC,2EAA2E;IAC3E,KAAK,EAAE,EAAE,CAAC;IAEV,kDAAkD;IAClD,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAEvB,kEAAkE;IAClE,SAAS,EAAE,EAAE,CAAC;CACd,CAAC;AAEF;;;;;;;;;;GAUG;AACH,qBAAa,YAAY,CACxB,OAAO,SAAS,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,EACvC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB,CAEvD,SAAQ,sBAAsB,CAAC,OAAO,CACtC,YAAW,mBAAmB,CAAC,OAAO,CAAC;IAS3B,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO;IAP9C,SAAS,CAAC,QAAQ,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IAE/D;;;;OAIG;IACH,YAA+B,MAAM,EAAE,OAAO,EAG7C;IAED,iEAAiE;IACjE,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,uEAAuE;IACvE,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED;;;;OAIG;IACH,IAAI,cAAc,CAAC,cAAc,EAAE,MAAM,EAExC;IAED;;;;OAIG;IACH,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAUhC;IAED;;;OAGG;IACH,GAAG,IAAI,IAAI,CAEV;IAED;;;OAGG;IACH,KAAK,IAAI,IAAI,CAEZ;IAED;;;;;;OAMG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAUrB;IAED;;;;;;;;;OASG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAa7D;IAED,SAAS,CAAC,oBAAoB,IAAI,IAAI,CAgBrC;CACD"}
|