react-native-nitro-net 0.1.5 → 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.
Files changed (71) hide show
  1. package/README.md +122 -12
  2. package/android/libs/arm64-v8a/librust_c_net.so +0 -0
  3. package/android/libs/armeabi-v7a/librust_c_net.so +0 -0
  4. package/android/libs/x86/librust_c_net.so +0 -0
  5. package/android/libs/x86_64/librust_c_net.so +0 -0
  6. package/cpp/HybridHttpParser.hpp +67 -0
  7. package/cpp/HybridNetDriver.hpp +74 -0
  8. package/cpp/HybridNetServerDriver.hpp +16 -0
  9. package/cpp/HybridNetSocketDriver.hpp +176 -0
  10. package/cpp/NetBindings.hpp +67 -1
  11. package/ios/Frameworks/RustCNet.xcframework/ios-arm64/RustCNet.framework/RustCNet +0 -0
  12. package/ios/Frameworks/RustCNet.xcframework/ios-arm64_x86_64-simulator/RustCNet.framework/RustCNet +0 -0
  13. package/lib/Net.nitro.d.ts +46 -1
  14. package/lib/Net.nitro.js +3 -1
  15. package/lib/http.d.ts +203 -0
  16. package/lib/http.js +1138 -0
  17. package/lib/https.d.ts +24 -0
  18. package/lib/https.js +144 -0
  19. package/lib/index.d.ts +50 -11
  20. package/lib/index.js +179 -31
  21. package/lib/tls.d.ts +145 -0
  22. package/lib/tls.js +521 -0
  23. package/nitrogen/generated/android/RustCNet+autolinking.cmake +2 -0
  24. package/nitrogen/generated/android/RustCNetOnLoad.cpp +2 -0
  25. package/nitrogen/generated/android/c++/JHybridHttpParserSpec.cpp +54 -0
  26. package/nitrogen/generated/android/c++/JHybridHttpParserSpec.hpp +65 -0
  27. package/nitrogen/generated/android/c++/JHybridNetDriverSpec.cpp +47 -1
  28. package/nitrogen/generated/android/c++/JHybridNetDriverSpec.hpp +9 -0
  29. package/nitrogen/generated/android/c++/JHybridNetServerDriverSpec.cpp +8 -0
  30. package/nitrogen/generated/android/c++/JHybridNetServerDriverSpec.hpp +2 -0
  31. package/nitrogen/generated/android/c++/JHybridNetSocketDriverSpec.cpp +79 -0
  32. package/nitrogen/generated/android/c++/JHybridNetSocketDriverSpec.hpp +17 -0
  33. package/nitrogen/generated/android/c++/JNetConfig.hpp +7 -3
  34. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridHttpParserSpec.kt +58 -0
  35. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetDriverSpec.kt +37 -0
  36. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetServerDriverSpec.kt +8 -0
  37. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetSocketDriverSpec.kt +68 -0
  38. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/NetConfig.kt +6 -3
  39. package/nitrogen/generated/ios/RustCNet-Swift-Cxx-Bridge.cpp +17 -0
  40. package/nitrogen/generated/ios/RustCNet-Swift-Cxx-Bridge.hpp +118 -41
  41. package/nitrogen/generated/ios/RustCNet-Swift-Cxx-Umbrella.hpp +5 -0
  42. package/nitrogen/generated/ios/c++/HybridHttpParserSpecSwift.cpp +11 -0
  43. package/nitrogen/generated/ios/c++/HybridHttpParserSpecSwift.hpp +79 -0
  44. package/nitrogen/generated/ios/c++/HybridNetDriverSpecSwift.hpp +69 -0
  45. package/nitrogen/generated/ios/c++/HybridNetServerDriverSpecSwift.hpp +12 -0
  46. package/nitrogen/generated/ios/c++/HybridNetSocketDriverSpecSwift.hpp +123 -0
  47. package/nitrogen/generated/ios/swift/HybridHttpParserSpec.swift +56 -0
  48. package/nitrogen/generated/ios/swift/HybridHttpParserSpec_cxx.swift +131 -0
  49. package/nitrogen/generated/ios/swift/HybridNetDriverSpec.swift +9 -0
  50. package/nitrogen/generated/ios/swift/HybridNetDriverSpec_cxx.swift +133 -0
  51. package/nitrogen/generated/ios/swift/HybridNetServerDriverSpec.swift +2 -0
  52. package/nitrogen/generated/ios/swift/HybridNetServerDriverSpec_cxx.swift +36 -0
  53. package/nitrogen/generated/ios/swift/HybridNetSocketDriverSpec.swift +17 -0
  54. package/nitrogen/generated/ios/swift/HybridNetSocketDriverSpec_cxx.swift +314 -0
  55. package/nitrogen/generated/ios/swift/NetConfig.swift +19 -1
  56. package/nitrogen/generated/shared/c++/HybridHttpParserSpec.cpp +21 -0
  57. package/nitrogen/generated/shared/c++/HybridHttpParserSpec.hpp +63 -0
  58. package/nitrogen/generated/shared/c++/HybridNetDriverSpec.cpp +9 -0
  59. package/nitrogen/generated/shared/c++/HybridNetDriverSpec.hpp +13 -0
  60. package/nitrogen/generated/shared/c++/HybridNetServerDriverSpec.cpp +2 -0
  61. package/nitrogen/generated/shared/c++/HybridNetServerDriverSpec.hpp +2 -0
  62. package/nitrogen/generated/shared/c++/HybridNetSocketDriverSpec.cpp +17 -0
  63. package/nitrogen/generated/shared/c++/HybridNetSocketDriverSpec.hpp +18 -0
  64. package/nitrogen/generated/shared/c++/NetConfig.hpp +6 -2
  65. package/package.json +7 -5
  66. package/react-native-nitro-net.podspec +1 -3
  67. package/src/Net.nitro.ts +44 -1
  68. package/src/http.ts +1304 -0
  69. package/src/https.ts +127 -0
  70. package/src/index.ts +167 -27
  71. package/src/tls.ts +608 -0
package/lib/https.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ import * as http from './http';
2
+ import * as tls from './tls';
3
+ import { IncomingMessage } from './http';
4
+ export declare class Server extends tls.Server {
5
+ private _httpConnections;
6
+ maxHeaderSize: number;
7
+ maxRequestsPerSocket: number;
8
+ headersTimeout: number;
9
+ requestTimeout: number;
10
+ keepAliveTimeout: number;
11
+ constructor(options?: any, requestListener?: (req: http.IncomingMessage, res: http.ServerResponse) => void);
12
+ setTimeout(ms: number, callback?: () => void): this;
13
+ }
14
+ export declare function createServer(options?: any, requestListener?: (req: http.IncomingMessage, res: http.ServerResponse) => void): Server;
15
+ export declare class ClientRequest extends http.ClientRequest {
16
+ constructor(options: any, callback?: (res: http.IncomingMessage) => void);
17
+ }
18
+ export declare function request(urlOrOptions: string | URL | http.RequestOptions, optionsOrCallback?: http.RequestOptions | ((res: http.IncomingMessage) => void), callback?: (res: http.IncomingMessage) => void): ClientRequest;
19
+ export declare function get(urlOrOptions: string | URL | http.RequestOptions, optionsOrCallback?: http.RequestOptions | ((res: http.IncomingMessage) => void), callback?: (res: http.IncomingMessage) => void): ClientRequest;
20
+ export declare class Agent extends http.Agent {
21
+ constructor(options?: any);
22
+ }
23
+ export declare const globalAgent: Agent;
24
+ export { IncomingMessage };
package/lib/https.js ADDED
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.IncomingMessage = exports.globalAgent = exports.Agent = exports.ClientRequest = exports.Server = void 0;
37
+ exports.createServer = createServer;
38
+ exports.request = request;
39
+ exports.get = get;
40
+ const http = __importStar(require("./http"));
41
+ const tls = __importStar(require("./tls"));
42
+ const http_1 = require("./http");
43
+ Object.defineProperty(exports, "IncomingMessage", { enumerable: true, get: function () { return http_1.IncomingMessage; } });
44
+ // ========== Server ==========
45
+ class Server extends tls.Server {
46
+ constructor(options, requestListener) {
47
+ if (typeof options === 'function') {
48
+ requestListener = options;
49
+ options = {};
50
+ }
51
+ super(options);
52
+ this._httpConnections = new Set();
53
+ this.maxHeaderSize = 16384;
54
+ this.maxRequestsPerSocket = 0;
55
+ this.headersTimeout = 60000;
56
+ this.requestTimeout = 300000;
57
+ this.keepAliveTimeout = 5000;
58
+ if (requestListener) {
59
+ this.on('request', requestListener);
60
+ }
61
+ // Initialize HTTP connection setup for secure connections
62
+ this.on('secureConnection', (socket) => {
63
+ // @ts-ignore - access internal http logic
64
+ http.Server.prototype._setupHttpConnection.call(this, socket);
65
+ });
66
+ }
67
+ setTimeout(ms, callback) {
68
+ // @ts-ignore - access netServer via super's internal or cast
69
+ this._netServer.setTimeout(ms, callback);
70
+ return this;
71
+ }
72
+ }
73
+ exports.Server = Server;
74
+ function createServer(options, requestListener) {
75
+ return new Server(options, requestListener);
76
+ }
77
+ // ========== ClientRequest ==========
78
+ class ClientRequest extends http.ClientRequest {
79
+ constructor(options, callback) {
80
+ if (typeof options === 'string') {
81
+ options = new URL(options);
82
+ }
83
+ if (options instanceof URL) {
84
+ options = {
85
+ protocol: options.protocol,
86
+ hostname: options.hostname,
87
+ path: options.pathname + options.search,
88
+ port: options.port ? parseInt(options.port) : 443
89
+ };
90
+ }
91
+ options.protocol = 'https:';
92
+ super(options, callback);
93
+ }
94
+ }
95
+ exports.ClientRequest = ClientRequest;
96
+ function request(urlOrOptions, optionsOrCallback, callback) {
97
+ let opts = {};
98
+ let cb = callback;
99
+ if (typeof urlOrOptions === 'string') {
100
+ const url = new URL(urlOrOptions);
101
+ opts = {
102
+ protocol: url.protocol,
103
+ hostname: url.hostname,
104
+ path: url.pathname + url.search,
105
+ port: url.port ? parseInt(url.port) : 443
106
+ };
107
+ }
108
+ else if (urlOrOptions instanceof URL) {
109
+ opts = {
110
+ protocol: urlOrOptions.protocol,
111
+ hostname: urlOrOptions.hostname,
112
+ path: urlOrOptions.pathname + urlOrOptions.search,
113
+ port: urlOrOptions.port ? parseInt(urlOrOptions.port) : 443
114
+ };
115
+ }
116
+ else {
117
+ opts = { ...urlOrOptions };
118
+ }
119
+ if (typeof optionsOrCallback === 'function') {
120
+ cb = optionsOrCallback;
121
+ }
122
+ else if (optionsOrCallback) {
123
+ opts = { ...opts, ...optionsOrCallback };
124
+ }
125
+ opts.protocol = 'https:';
126
+ return new ClientRequest(opts, cb);
127
+ }
128
+ function get(urlOrOptions, optionsOrCallback, callback) {
129
+ const req = request(urlOrOptions, optionsOrCallback, callback);
130
+ req.end();
131
+ return req;
132
+ }
133
+ // ========== Agent ==========
134
+ class Agent extends http.Agent {
135
+ constructor(options) {
136
+ super(options);
137
+ }
138
+ }
139
+ exports.Agent = Agent;
140
+ exports.globalAgent = new Agent({
141
+ keepAlive: true,
142
+ scheduling: 'lifo',
143
+ timeout: 5000,
144
+ });
package/lib/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import type { NetSocketDriver, NetConfig } from './Net.nitro';
4
4
  declare function isIP(input: string): number;
5
5
  declare function isIPv4(input: string): boolean;
6
6
  declare function isIPv6(input: string): boolean;
7
+ declare function isVerbose(): boolean;
7
8
  declare function setVerbose(enabled: boolean): void;
8
9
  declare function getDefaultAutoSelectFamily(): number;
9
10
  declare function setDefaultAutoSelectFamily(family: number): void;
@@ -23,24 +24,56 @@ declare function setDefaultAutoSelectFamily(family: number): void;
23
24
  * ```
24
25
  */
25
26
  declare function initWithConfig(config: NetConfig): void;
27
+ export interface SocketAddressOptions {
28
+ address?: string;
29
+ family?: 'ipv4' | 'ipv6';
30
+ port?: number;
31
+ flowlabel?: number;
32
+ }
26
33
  export declare class SocketAddress {
27
34
  readonly address: string;
28
35
  readonly family: 'ipv4' | 'ipv6';
29
36
  readonly port: number;
30
37
  readonly flowlabel: number;
31
- constructor(options: {
32
- address: string;
33
- family?: 'ipv4' | 'ipv6';
34
- port: number;
35
- flowlabel?: number;
36
- });
38
+ constructor(options?: SocketAddressOptions);
39
+ /**
40
+ * Attempts to parse a string containing a socket address.
41
+ * Returns a SocketAddress if successful, or undefined if not.
42
+ *
43
+ * Supported formats:
44
+ * - `ip:port` (e.g., `127.0.0.1:8080`, `[::1]:8080`)
45
+ * - `ip` only (port defaults to 0)
46
+ */
47
+ static parse(input: string): SocketAddress | undefined;
48
+ }
49
+ export interface BlockListRule {
50
+ type: 'address' | 'range' | 'subnet';
51
+ address?: string;
52
+ start?: string;
53
+ end?: string;
54
+ prefix?: number;
55
+ family: 'ipv4' | 'ipv6';
37
56
  }
38
57
  export declare class BlockList {
39
58
  private _rules;
59
+ /** Returns an array of rules added to the blocklist. */
60
+ get rules(): BlockListRule[];
40
61
  addAddress(address: string, family?: 'ipv4' | 'ipv6'): void;
41
62
  addRange(start: string, end: string, family?: 'ipv4' | 'ipv6'): void;
42
63
  addSubnet(net: string, prefix: number, family?: 'ipv4' | 'ipv6'): void;
43
64
  check(address: string, family?: 'ipv4' | 'ipv6'): boolean;
65
+ /**
66
+ * Serializes the BlockList to a JSON-compatible format.
67
+ */
68
+ toJSON(): BlockListRule[];
69
+ /**
70
+ * Creates a BlockList from a JSON array of rules.
71
+ */
72
+ static fromJSON(json: BlockListRule[]): BlockList;
73
+ /**
74
+ * Checks if a given value is a BlockList instance.
75
+ */
76
+ static isBlockList(value: unknown): value is BlockList;
44
77
  }
45
78
  export interface SocketOptions extends DuplexOptions {
46
79
  fd?: any;
@@ -52,10 +85,10 @@ export interface SocketOptions extends DuplexOptions {
52
85
  remoteFamily?: string;
53
86
  }
54
87
  export declare class Socket extends Duplex {
55
- private _driver;
88
+ protected _driver: NetSocketDriver | undefined;
56
89
  connecting: boolean;
57
- private _connected;
58
- private _hadError;
90
+ protected _connected: boolean;
91
+ protected _hadError: boolean;
59
92
  remoteAddress?: string;
60
93
  remotePort?: number;
61
94
  remoteFamily?: string;
@@ -65,6 +98,7 @@ export declare class Socket extends Duplex {
65
98
  bytesWritten: number;
66
99
  autoSelectFamilyAttemptedAddresses: string[];
67
100
  private _autoSelectFamily;
101
+ private _timeout;
68
102
  get localFamily(): string;
69
103
  get readyState(): string;
70
104
  get pending(): boolean;
@@ -110,7 +144,7 @@ export declare class Socket extends Duplex {
110
144
  * Use 'utf8', 'hex', etc.
111
145
  */
112
146
  setEncoding(encoding: BufferEncoding): this;
113
- get timeout(): number | undefined;
147
+ get timeout(): number;
114
148
  get bufferSize(): number;
115
149
  resetAndDestroy(): this;
116
150
  }
@@ -141,7 +175,10 @@ export declare class Server extends EventEmitter {
141
175
  export declare function createConnection(options: any, connectionListener?: () => void): Socket;
142
176
  export declare const connect: typeof createConnection;
143
177
  export declare function createServer(options?: any, connectionListener?: (socket: Socket) => void): Server;
144
- export { isIP, isIPv4, isIPv6, getDefaultAutoSelectFamily, setDefaultAutoSelectFamily, setVerbose, initWithConfig, };
178
+ export * as tls from './tls';
179
+ export * as http from './http';
180
+ export * as https from './https';
181
+ export { isIP, isIPv4, isIPv6, getDefaultAutoSelectFamily, setDefaultAutoSelectFamily, isVerbose, setVerbose, initWithConfig, };
145
182
  export type { NetConfig };
146
183
  declare const _default: {
147
184
  Socket: typeof Socket;
@@ -158,5 +195,7 @@ declare const _default: {
158
195
  setDefaultAutoSelectFamily: typeof setDefaultAutoSelectFamily;
159
196
  setVerbose: typeof setVerbose;
160
197
  initWithConfig: typeof initWithConfig;
198
+ http: any;
199
+ https: any;
161
200
  };
162
201
  export default _default;
package/lib/index.js CHANGED
@@ -1,6 +1,39 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.connect = exports.Server = exports.Socket = exports.BlockList = exports.SocketAddress = void 0;
36
+ exports.https = exports.http = exports.tls = exports.connect = exports.Server = exports.Socket = exports.BlockList = exports.SocketAddress = void 0;
4
37
  exports.createConnection = createConnection;
5
38
  exports.createServer = createServer;
6
39
  exports.isIP = isIP;
@@ -8,6 +41,7 @@ exports.isIPv4 = isIPv4;
8
41
  exports.isIPv6 = isIPv6;
9
42
  exports.getDefaultAutoSelectFamily = getDefaultAutoSelectFamily;
10
43
  exports.setDefaultAutoSelectFamily = setDefaultAutoSelectFamily;
44
+ exports.isVerbose = isVerbose;
11
45
  exports.setVerbose = setVerbose;
12
46
  exports.initWithConfig = initWithConfig;
13
47
  const readable_stream_1 = require("readable-stream");
@@ -41,14 +75,18 @@ function isIPv6(input) {
41
75
  let _autoSelectFamilyDefault = 4; // Node default is usually 4/6 independent, but we mock it.
42
76
  let _isVerbose = false;
43
77
  let _isInitialized = false;
44
- function debugLog(message) {
45
- if (_isVerbose) {
46
- console.log(`[NET DEBUG] ${message}`);
47
- }
78
+ function isVerbose() {
79
+ return _isVerbose;
48
80
  }
49
81
  function setVerbose(enabled) {
50
82
  _isVerbose = enabled;
51
83
  }
84
+ function debugLog(message) {
85
+ if (_isVerbose) {
86
+ const timestamp = new Date().toISOString().split('T')[1].split('Z')[0];
87
+ console.log(`[NET DEBUG ${timestamp}] ${message}`);
88
+ }
89
+ }
52
90
  function getDefaultAutoSelectFamily() {
53
91
  return _autoSelectFamilyDefault;
54
92
  }
@@ -83,29 +121,84 @@ function ensureInitialized() {
83
121
  */
84
122
  function initWithConfig(config) {
85
123
  _isInitialized = true;
124
+ if (config.debug !== undefined) {
125
+ setVerbose(config.debug);
126
+ }
86
127
  Driver_1.Driver.initWithConfig(config);
87
128
  }
88
- // -----------------------------------------------------------------------------
89
- // SocketAddress
90
- // -----------------------------------------------------------------------------
91
- // SocketAddress
92
- // -----------------------------------------------------------------------------
93
129
  class SocketAddress {
94
- constructor(options) {
95
- this.address = options.address;
96
- this.family = options.family || (isIPv6(options.address) ? 'ipv6' : 'ipv4');
97
- this.port = options.port;
98
- this.flowlabel = options.flowlabel || 0;
130
+ constructor(options = {}) {
131
+ this.address = options.address ?? (options.family === 'ipv6' ? '::' : '127.0.0.1');
132
+ this.family = options.family || (isIPv6(this.address) ? 'ipv6' : 'ipv4');
133
+ this.port = options.port ?? 0;
134
+ this.flowlabel = options.flowlabel ?? 0;
135
+ }
136
+ /**
137
+ * Attempts to parse a string containing a socket address.
138
+ * Returns a SocketAddress if successful, or undefined if not.
139
+ *
140
+ * Supported formats:
141
+ * - `ip:port` (e.g., `127.0.0.1:8080`, `[::1]:8080`)
142
+ * - `ip` only (port defaults to 0)
143
+ */
144
+ static parse(input) {
145
+ if (!input || typeof input !== 'string')
146
+ return undefined;
147
+ let address;
148
+ let port = 0;
149
+ // Handle IPv6 bracket notation: [::1]:port
150
+ const ipv6Match = input.match(/^\[([^\]]+)\]:?(\d*)$/);
151
+ if (ipv6Match) {
152
+ address = ipv6Match[1];
153
+ port = ipv6Match[2] ? parseInt(ipv6Match[2], 10) : 0;
154
+ if (!isIPv6(address))
155
+ return undefined;
156
+ return new SocketAddress({ address, port, family: 'ipv6' });
157
+ }
158
+ // Handle IPv4 or IPv6 without brackets
159
+ const lastColon = input.lastIndexOf(':');
160
+ if (lastColon === -1) {
161
+ // No port, just IP
162
+ address = input;
163
+ }
164
+ else {
165
+ // Determine if the colon is a port separator or part of IPv6
166
+ const potentialPort = input.slice(lastColon + 1);
167
+ const potentialAddr = input.slice(0, lastColon);
168
+ if (/^\d+$/.test(potentialPort) && (isIPv4(potentialAddr) || isIPv6(potentialAddr))) {
169
+ address = potentialAddr;
170
+ port = parseInt(potentialPort, 10);
171
+ }
172
+ else {
173
+ // It's an IPv6 address without port
174
+ address = input;
175
+ }
176
+ }
177
+ const family = isIPv6(address) ? 'ipv6' : (isIPv4(address) ? 'ipv4' : undefined);
178
+ if (!family)
179
+ return undefined;
180
+ return new SocketAddress({ address, port, family });
99
181
  }
100
182
  }
101
183
  exports.SocketAddress = SocketAddress;
102
- // -----------------------------------------------------------------------------
103
- // BlockList
104
- // -----------------------------------------------------------------------------
105
184
  class BlockList {
106
185
  constructor() {
107
186
  this._rules = [];
108
187
  }
188
+ /** Returns an array of rules added to the blocklist. */
189
+ get rules() {
190
+ return this._rules.map(r => {
191
+ if (r.type === 'address') {
192
+ return { type: 'address', address: r.data.address, family: r.data.family };
193
+ }
194
+ else if (r.type === 'range') {
195
+ return { type: 'range', start: r.data.start, end: r.data.end, family: r.data.family };
196
+ }
197
+ else {
198
+ return { type: 'subnet', address: r.data.net, prefix: r.data.prefix, family: r.data.family };
199
+ }
200
+ });
201
+ }
109
202
  addAddress(address, family) {
110
203
  this._rules.push({ type: 'address', data: { address, family: family || (isIPv6(address) ? 'ipv6' : 'ipv4') } });
111
204
  }
@@ -140,6 +233,36 @@ class BlockList {
140
233
  }
141
234
  return false;
142
235
  }
236
+ /**
237
+ * Serializes the BlockList to a JSON-compatible format.
238
+ */
239
+ toJSON() {
240
+ return this.rules;
241
+ }
242
+ /**
243
+ * Creates a BlockList from a JSON array of rules.
244
+ */
245
+ static fromJSON(json) {
246
+ const list = new BlockList();
247
+ for (const rule of json) {
248
+ if (rule.type === 'address' && rule.address) {
249
+ list.addAddress(rule.address, rule.family);
250
+ }
251
+ else if (rule.type === 'range' && rule.start && rule.end) {
252
+ list.addRange(rule.start, rule.end, rule.family);
253
+ }
254
+ else if (rule.type === 'subnet' && rule.address && rule.prefix !== undefined) {
255
+ list.addSubnet(rule.address, rule.prefix, rule.family);
256
+ }
257
+ }
258
+ return list;
259
+ }
260
+ /**
261
+ * Checks if a given value is a BlockList instance.
262
+ */
263
+ static isBlockList(value) {
264
+ return value instanceof BlockList;
265
+ }
143
266
  }
144
267
  exports.BlockList = BlockList;
145
268
  function ipv4ToLong(ip) {
@@ -172,7 +295,9 @@ class Socket extends readable_stream_1.Duplex {
172
295
  super({
173
296
  allowHalfOpen: options?.allowHalfOpen ?? false,
174
297
  readable: options?.readable ?? true,
175
- writable: options?.writable ?? true
298
+ writable: options?.writable ?? true,
299
+ // @ts-ignore
300
+ autoDestroy: false
176
301
  });
177
302
  this.connecting = false; // Changed from private _connecting
178
303
  this._connected = false;
@@ -181,11 +306,14 @@ class Socket extends readable_stream_1.Duplex {
181
306
  this.bytesWritten = 0;
182
307
  this.autoSelectFamilyAttemptedAddresses = [];
183
308
  this._autoSelectFamily = false;
309
+ this._timeout = 0;
184
310
  if (options?.socketDriver) {
185
311
  // Wrapping existing socket (from Server)
186
312
  this._driver = options.socketDriver;
187
313
  this._connected = true;
188
314
  this._setupEvents();
315
+ // Enable noDelay by default
316
+ this._driver.setNoDelay(true);
189
317
  // Resume the socket since it starts paused on server-accept
190
318
  this.resume();
191
319
  // Emit connect for server-side socket? No, it's already connected.
@@ -195,8 +323,10 @@ class Socket extends readable_stream_1.Duplex {
195
323
  ensureInitialized();
196
324
  this._driver = Driver_1.Driver.createSocket();
197
325
  this._setupEvents();
198
- // Also resume client socket initially so it's ready to receive
199
- this.resume();
326
+ // Enable noDelay by default to match Node.js and reduce latency for small writes
327
+ this._driver.setNoDelay(true);
328
+ // Do NOT resume here - socket is not connected yet!
329
+ // resume() will be called after 'connect' event in _connect()
200
330
  }
201
331
  this.on('finish', () => {
202
332
  // Writable side finished
@@ -219,13 +349,14 @@ class Socket extends readable_stream_1.Duplex {
219
349
  return;
220
350
  const id = this._driver.id ?? this._driver._id;
221
351
  this._driver.onEvent = (eventType, data) => {
352
+ this.emit('event', eventType, data);
222
353
  if (eventType === 3) { // ERROR
223
354
  const msg = new TextDecoder().decode(data);
224
355
  debugLog(`Socket (id: ${id}) NATIVE ERROR: ${msg}`);
225
356
  }
226
- if (eventType === 9) { // DEBUG
227
- const msg = new TextDecoder().decode(data);
228
- debugLog(`Socket (id: ${id}) NATIVE DEBUG: ${msg}`);
357
+ if (eventType === 9) { // SESSION/DEBUG
358
+ debugLog(`Socket (id: ${id}) NATIVE SESSION EVENT RECEIVED`);
359
+ this.emit('session', data);
229
360
  return;
230
361
  }
231
362
  debugLog(`Socket (id: ${id}, localPort: ${this.localPort}) Event TYPE: ${eventType}, data len: ${data?.byteLength}`);
@@ -234,6 +365,8 @@ class Socket extends readable_stream_1.Duplex {
234
365
  this.connecting = false;
235
366
  this._connected = true;
236
367
  this._updateAddresses();
368
+ // Now that we're connected, start receiving data
369
+ this.resume();
237
370
  this.emit('connect');
238
371
  this.emit('ready');
239
372
  break;
@@ -373,6 +506,7 @@ class Socket extends readable_stream_1.Duplex {
373
506
  else {
374
507
  this._autoSelectFamily = true;
375
508
  }
509
+ debugLog(`Socket.connect: target=${host}:${port}, autoSelectFamily=${this._autoSelectFamily}`);
376
510
  return this._connect(port, host, connectionListener, options.signal);
377
511
  }
378
512
  _connect(port, host, listener, signal) {
@@ -394,6 +528,7 @@ class Socket extends readable_stream_1.Duplex {
394
528
  this.once('connect', () => signal.removeEventListener('abort', abortHandler));
395
529
  this.once('close', () => signal.removeEventListener('abort', abortHandler));
396
530
  }
531
+ debugLog(`Socket._connect: Calling driver.connect(${host}, ${port})`);
397
532
  this._driver?.connect(host, port);
398
533
  return this;
399
534
  }
@@ -465,6 +600,7 @@ class Socket extends readable_stream_1.Duplex {
465
600
  }
466
601
  // Standard net.Socket methods
467
602
  setTimeout(msecs, callback) {
603
+ this._timeout = msecs;
468
604
  if (this._driver) {
469
605
  this._driver.setTimeout(msecs);
470
606
  }
@@ -487,12 +623,13 @@ class Socket extends readable_stream_1.Duplex {
487
623
  * Resume reading after a call to pause().
488
624
  */
489
625
  resume() {
490
- const id = this._driver?.id;
491
- debugLog(`Socket.resume() called, id: ${id}`);
626
+ const driver = this._driver;
627
+ const id = driver?.id;
628
+ debugLog(`Socket.resume() called, id: ${id === undefined ? 'none' : id}, destroyed: ${this.destroyed}`);
492
629
  super.resume();
493
- if (this._driver) {
630
+ if (driver) {
494
631
  debugLog(`Socket.resume() calling driver.resume(), id: ${id}`);
495
- this._driver.resume();
632
+ driver.resume();
496
633
  }
497
634
  return this;
498
635
  }
@@ -518,7 +655,7 @@ class Socket extends readable_stream_1.Duplex {
518
655
  return this;
519
656
  }
520
657
  get timeout() {
521
- return undefined; // Not tracked strictly as a property yet
658
+ return this._timeout;
522
659
  }
523
660
  get bufferSize() {
524
661
  return 0; // Deprecated but often accessed
@@ -635,8 +772,8 @@ class Server extends eventemitter3_1.EventEmitter {
635
772
  this.emit('error', new Error(data ? react_native_nitro_buffer_1.Buffer.from(data).toString() : 'Unknown server error'));
636
773
  break;
637
774
  case Net_nitro_1.NetServerEvent.DEBUG: {
638
- const msg = data ? react_native_nitro_buffer_1.Buffer.from(data).toString() : 'Unknown debug message';
639
- debugLog(`Server NATIVE DEBUG: ${msg}`);
775
+ debugLog(`Server NATIVE SESSION/DEBUG EVENT RECEIVED`);
776
+ this.emit('session', data);
640
777
  break;
641
778
  }
642
779
  case Net_nitro_1.NetServerEvent.CLOSE:
@@ -724,6 +861,12 @@ class Server extends eventemitter3_1.EventEmitter {
724
861
  return this;
725
862
  }
726
863
  close(callback) {
864
+ // Destroy all active connections first
865
+ for (const socket of this._sockets) {
866
+ socket.destroy();
867
+ }
868
+ this._sockets.clear();
869
+ this._connections = 0;
727
870
  this._driver.close();
728
871
  if (callback)
729
872
  this.once('close', callback);
@@ -763,6 +906,9 @@ exports.connect = createConnection;
763
906
  function createServer(options, connectionListener) {
764
907
  return new Server(options, connectionListener);
765
908
  }
909
+ exports.tls = __importStar(require("./tls"));
910
+ exports.http = __importStar(require("./http"));
911
+ exports.https = __importStar(require("./https"));
766
912
  exports.default = {
767
913
  Socket,
768
914
  Server,
@@ -778,4 +924,6 @@ exports.default = {
778
924
  setDefaultAutoSelectFamily,
779
925
  setVerbose,
780
926
  initWithConfig,
927
+ http: require('./http'),
928
+ https: require('./https'),
781
929
  };