@hla4ts/transport 0.1.0 → 0.1.1

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.
@@ -1,154 +1,154 @@
1
- /**
2
- * TCP Transport Implementation
3
- *
4
- * Provides a plain TCP connection for the Federate Protocol.
5
- * Note: This is unencrypted and should only be used for local development/testing.
6
- */
7
-
8
- import { connect, type Socket, type SocketHandler } from "bun";
9
- import { FrameDecoder } from "./frame-decoder.ts";
10
- import { Ports, Protocol } from "./constants.ts";
11
- import type {
12
- Transport,
13
- TransportEvents,
14
- TransportOptions,
15
- ReceivedMessage,
16
- } from "./transport.ts";
17
-
18
- /**
19
- * Plain TCP Transport for Federate Protocol
20
- *
21
- * ⚠️ WARNING: This transport is unencrypted. Use TlsTransport for production.
22
- *
23
- * @example
24
- * ```ts
25
- * const transport = new TcpTransport({
26
- * host: 'localhost',
27
- * port: 15164,
28
- * });
29
- *
30
- * await transport.connect();
31
- * ```
32
- */
33
- export class TcpTransport implements Transport {
34
- private readonly options: Required<TransportOptions>;
35
- private socket: Socket<{ decoder: FrameDecoder }> | null = null;
36
- private events: TransportEvents = {};
37
- private decoder: FrameDecoder;
38
- private connected = false;
39
-
40
- constructor(options: TransportOptions) {
41
- this.options = {
42
- host: options.host,
43
- port: options.port ?? Ports.TCP,
44
- connectionTimeout: options.connectionTimeout ?? 10000,
45
- noDelay: options.noDelay ?? true,
46
- };
47
-
48
- this.decoder = new FrameDecoder();
49
- this.decoder.onMessage = (msg) => this.handleMessage(msg);
50
- this.decoder.onError = (err) => this.handleError(err);
51
- }
52
-
53
- async connect(): Promise<void> {
54
- if (this.socket) {
55
- throw new Error("Already connected");
56
- }
57
-
58
- const decoder = this.decoder;
59
- const transport = this;
60
-
61
- return new Promise((resolve, reject) => {
62
- const timeoutId = setTimeout(() => {
63
- reject(new Error(`Connection timeout after ${this.options.connectionTimeout}ms`));
64
- }, this.options.connectionTimeout);
65
-
66
- const socketHandler: SocketHandler<{ decoder: FrameDecoder }> = {
67
- data(_socket, data) {
68
- decoder.push(new Uint8Array(data));
69
- },
70
- open(_socket) {
71
- clearTimeout(timeoutId);
72
- transport.connected = true;
73
- resolve();
74
- },
75
- close(_socket) {
76
- transport.connected = false;
77
- transport.socket = null;
78
- transport.events.onClose?.(false);
79
- },
80
- error(_socket, error) {
81
- clearTimeout(timeoutId);
82
- transport.connected = false;
83
- const err = error instanceof Error ? error : new Error(String(error));
84
- transport.events.onError?.(err);
85
- reject(err);
86
- },
87
- connectError(_socket, error) {
88
- clearTimeout(timeoutId);
89
- const err = error instanceof Error ? error : new Error(String(error));
90
- reject(err);
91
- },
92
- };
93
-
94
- connect({
95
- hostname: this.options.host,
96
- port: this.options.port,
97
- socket: socketHandler,
98
- data: { decoder },
99
- })
100
- .then((socket) => {
101
- this.socket = socket;
102
- })
103
- .catch(reject);
104
- });
105
- }
106
-
107
- async disconnect(): Promise<void> {
108
- if (this.socket) {
109
- this.socket.end();
110
- this.socket = null;
111
- this.connected = false;
112
- this.decoder.reset();
113
- }
114
- }
115
-
116
- isConnected(): boolean {
117
- return this.connected && this.socket !== null;
118
- }
119
-
120
- async send(data: Uint8Array): Promise<void> {
121
- if (!this.socket || !this.connected) {
122
- throw new Error("Not connected");
123
- }
124
-
125
- const written = this.socket.write(data);
126
- if (written < data.length) {
127
- throw new Error(
128
- `Failed to write all data: wrote ${written} of ${data.length} bytes`
129
- );
130
- }
131
- }
132
-
133
- setEventHandlers(handlers: TransportEvents): void {
134
- this.events = handlers;
135
- }
136
-
137
- getProtocolName(): string {
138
- return Protocol.TCP;
139
- }
140
-
141
- getRemoteAddress(): string | null {
142
- return this.socket
143
- ? `${this.options.host}:${this.options.port}`
144
- : null;
145
- }
146
-
147
- private handleMessage(message: ReceivedMessage): void {
148
- this.events.onMessage?.(message);
149
- }
150
-
151
- private handleError(error: Error): void {
152
- this.events.onError?.(error);
153
- }
154
- }
1
+ /**
2
+ * TCP Transport Implementation
3
+ *
4
+ * Provides a plain TCP connection for the Federate Protocol.
5
+ * Note: This is unencrypted and should only be used for local development/testing.
6
+ */
7
+
8
+ import { connect, type Socket, type SocketHandler } from "bun";
9
+ import { FrameDecoder } from "./frame-decoder.ts";
10
+ import { Ports, Protocol } from "./constants.ts";
11
+ import type {
12
+ Transport,
13
+ TransportEvents,
14
+ TransportOptions,
15
+ ReceivedMessage,
16
+ } from "./transport.ts";
17
+
18
+ /**
19
+ * Plain TCP Transport for Federate Protocol
20
+ *
21
+ * ⚠️ WARNING: This transport is unencrypted. Use TlsTransport for production.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const transport = new TcpTransport({
26
+ * host: 'localhost',
27
+ * port: 15164,
28
+ * });
29
+ *
30
+ * await transport.connect();
31
+ * ```
32
+ */
33
+ export class TcpTransport implements Transport {
34
+ private readonly options: Required<TransportOptions>;
35
+ private socket: Socket<{ decoder: FrameDecoder }> | null = null;
36
+ private events: TransportEvents = {};
37
+ private decoder: FrameDecoder;
38
+ private connected = false;
39
+
40
+ constructor(options: TransportOptions) {
41
+ this.options = {
42
+ host: options.host,
43
+ port: options.port ?? Ports.TCP,
44
+ connectionTimeout: options.connectionTimeout ?? 10000,
45
+ noDelay: options.noDelay ?? true,
46
+ };
47
+
48
+ this.decoder = new FrameDecoder();
49
+ this.decoder.onMessage = (msg) => this.handleMessage(msg);
50
+ this.decoder.onError = (err) => this.handleError(err);
51
+ }
52
+
53
+ async connect(): Promise<void> {
54
+ if (this.socket) {
55
+ throw new Error("Already connected");
56
+ }
57
+
58
+ const decoder = this.decoder;
59
+ const transport = this;
60
+
61
+ return new Promise((resolve, reject) => {
62
+ const timeoutId = setTimeout(() => {
63
+ reject(new Error(`Connection timeout after ${this.options.connectionTimeout}ms`));
64
+ }, this.options.connectionTimeout);
65
+
66
+ const socketHandler: SocketHandler<{ decoder: FrameDecoder }> = {
67
+ data(_socket, data) {
68
+ decoder.push(new Uint8Array(data));
69
+ },
70
+ open(_socket) {
71
+ clearTimeout(timeoutId);
72
+ transport.connected = true;
73
+ resolve();
74
+ },
75
+ close(_socket) {
76
+ transport.connected = false;
77
+ transport.socket = null;
78
+ transport.events.onClose?.(false);
79
+ },
80
+ error(_socket, error) {
81
+ clearTimeout(timeoutId);
82
+ transport.connected = false;
83
+ const err = error instanceof Error ? error : new Error(String(error));
84
+ transport.events.onError?.(err);
85
+ reject(err);
86
+ },
87
+ connectError(_socket, error) {
88
+ clearTimeout(timeoutId);
89
+ const err = error instanceof Error ? error : new Error(String(error));
90
+ reject(err);
91
+ },
92
+ };
93
+
94
+ connect({
95
+ hostname: this.options.host,
96
+ port: this.options.port,
97
+ socket: socketHandler,
98
+ data: { decoder },
99
+ })
100
+ .then((socket) => {
101
+ this.socket = socket;
102
+ })
103
+ .catch(reject);
104
+ });
105
+ }
106
+
107
+ async disconnect(): Promise<void> {
108
+ if (this.socket) {
109
+ this.socket.end();
110
+ this.socket = null;
111
+ this.connected = false;
112
+ this.decoder.reset();
113
+ }
114
+ }
115
+
116
+ isConnected(): boolean {
117
+ return this.connected && this.socket !== null;
118
+ }
119
+
120
+ async send(data: Uint8Array): Promise<void> {
121
+ if (!this.socket || !this.connected) {
122
+ throw new Error("Not connected");
123
+ }
124
+
125
+ const written = this.socket.write(data);
126
+ if (written < data.length) {
127
+ throw new Error(
128
+ `Failed to write all data: wrote ${written} of ${data.length} bytes`
129
+ );
130
+ }
131
+ }
132
+
133
+ setEventHandlers(handlers: TransportEvents): void {
134
+ this.events = handlers;
135
+ }
136
+
137
+ getProtocolName(): string {
138
+ return Protocol.TCP;
139
+ }
140
+
141
+ getRemoteAddress(): string | null {
142
+ return this.socket
143
+ ? `${this.options.host}:${this.options.port}`
144
+ : null;
145
+ }
146
+
147
+ private handleMessage(message: ReceivedMessage): void {
148
+ this.events.onMessage?.(message);
149
+ }
150
+
151
+ private handleError(error: Error): void {
152
+ this.events.onError?.(error);
153
+ }
154
+ }