react-native-nitro-net 0.4.2 → 0.4.3

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 (80) hide show
  1. package/android/libs/arm64-v8a/librust_c_net.so +0 -0
  2. package/android/libs/armeabi-v7a/librust_c_net.so +0 -0
  3. package/android/libs/x86/librust_c_net.so +0 -0
  4. package/android/libs/x86_64/librust_c_net.so +0 -0
  5. package/cpp/HybridHttpParser.hpp +44 -16
  6. package/cpp/NetBindings.hpp +192 -96
  7. package/cpp/NetManager.hpp +16 -10
  8. package/ios/Frameworks/RustCNet.xcframework/Info.plist +5 -5
  9. package/ios/Frameworks/RustCNet.xcframework/ios-arm64/RustCNet.framework/RustCNet +0 -0
  10. package/ios/Frameworks/RustCNet.xcframework/ios-arm64_x86_64-simulator/RustCNet.framework/RustCNet +0 -0
  11. package/lib/Net.nitro.d.ts +6 -2
  12. package/lib/Net.nitro.d.ts.map +1 -1
  13. package/lib/http.d.ts.map +1 -1
  14. package/lib/http.js +34 -17
  15. package/lib/net.d.ts.map +1 -1
  16. package/lib/net.js +19 -10
  17. package/nitrogen/generated/android/RustCNet+autolinking.cmake +1 -1
  18. package/nitrogen/generated/android/RustCNet+autolinking.gradle +1 -1
  19. package/nitrogen/generated/android/RustCNetOnLoad.cpp +27 -22
  20. package/nitrogen/generated/android/RustCNetOnLoad.hpp +14 -5
  21. package/nitrogen/generated/android/c++/JFunc_void_double_std__shared_ptr_ArrayBuffer_.hpp +1 -1
  22. package/nitrogen/generated/android/c++/JHttpParsedMessage.hpp +64 -0
  23. package/nitrogen/generated/android/c++/JHybridHttpParserSpec.cpp +28 -23
  24. package/nitrogen/generated/android/c++/JHybridHttpParserSpec.hpp +21 -23
  25. package/nitrogen/generated/android/c++/JHybridNetDriverSpec.cpp +35 -34
  26. package/nitrogen/generated/android/c++/JHybridNetDriverSpec.hpp +20 -22
  27. package/nitrogen/generated/android/c++/JHybridNetServerDriverSpec.cpp +31 -30
  28. package/nitrogen/generated/android/c++/JHybridNetServerDriverSpec.hpp +20 -22
  29. package/nitrogen/generated/android/c++/JHybridNetSocketDriverSpec.cpp +53 -52
  30. package/nitrogen/generated/android/c++/JHybridNetSocketDriverSpec.hpp +20 -22
  31. package/nitrogen/generated/android/c++/JNetConfig.hpp +1 -1
  32. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/Func_void_double_std__shared_ptr_ArrayBuffer_.kt +1 -1
  33. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HttpParsedMessage.kt +41 -0
  34. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridHttpParserSpec.kt +15 -18
  35. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetDriverSpec.kt +16 -19
  36. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetServerDriverSpec.kt +16 -19
  37. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetSocketDriverSpec.kt +16 -19
  38. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/NetConfig.kt +1 -1
  39. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/RustCNetOnLoad.kt +1 -1
  40. package/nitrogen/generated/ios/RustCNet+autolinking.rb +1 -1
  41. package/nitrogen/generated/ios/RustCNet-Swift-Cxx-Bridge.cpp +1 -1
  42. package/nitrogen/generated/ios/RustCNet-Swift-Cxx-Bridge.hpp +17 -5
  43. package/nitrogen/generated/ios/RustCNet-Swift-Cxx-Umbrella.hpp +4 -1
  44. package/nitrogen/generated/ios/RustCNetAutolinking.mm +1 -1
  45. package/nitrogen/generated/ios/RustCNetAutolinking.swift +5 -1
  46. package/nitrogen/generated/ios/c++/HybridHttpParserSpecSwift.cpp +1 -1
  47. package/nitrogen/generated/ios/c++/HybridHttpParserSpecSwift.hpp +12 -2
  48. package/nitrogen/generated/ios/c++/HybridNetDriverSpecSwift.cpp +1 -1
  49. package/nitrogen/generated/ios/c++/HybridNetDriverSpecSwift.hpp +7 -1
  50. package/nitrogen/generated/ios/c++/HybridNetServerDriverSpecSwift.cpp +1 -1
  51. package/nitrogen/generated/ios/c++/HybridNetServerDriverSpecSwift.hpp +7 -1
  52. package/nitrogen/generated/ios/c++/HybridNetSocketDriverSpecSwift.cpp +1 -1
  53. package/nitrogen/generated/ios/c++/HybridNetSocketDriverSpecSwift.hpp +7 -1
  54. package/nitrogen/generated/ios/swift/Func_void_double_std__shared_ptr_ArrayBuffer_.swift +1 -2
  55. package/nitrogen/generated/ios/swift/HttpParsedMessage.swift +47 -0
  56. package/nitrogen/generated/ios/swift/HybridHttpParserSpec.swift +4 -5
  57. package/nitrogen/generated/ios/swift/HybridHttpParserSpec_cxx.swift +13 -6
  58. package/nitrogen/generated/ios/swift/HybridNetDriverSpec.swift +3 -4
  59. package/nitrogen/generated/ios/swift/HybridNetDriverSpec_cxx.swift +9 -2
  60. package/nitrogen/generated/ios/swift/HybridNetServerDriverSpec.swift +3 -4
  61. package/nitrogen/generated/ios/swift/HybridNetServerDriverSpec_cxx.swift +49 -7
  62. package/nitrogen/generated/ios/swift/HybridNetSocketDriverSpec.swift +3 -4
  63. package/nitrogen/generated/ios/swift/HybridNetSocketDriverSpec_cxx.swift +25 -4
  64. package/nitrogen/generated/ios/swift/NetConfig.swift +9 -3
  65. package/nitrogen/generated/shared/c++/HttpParsedMessage.hpp +89 -0
  66. package/nitrogen/generated/shared/c++/HybridHttpParserSpec.cpp +1 -1
  67. package/nitrogen/generated/shared/c++/HybridHttpParserSpec.hpp +5 -4
  68. package/nitrogen/generated/shared/c++/HybridNetDriverSpec.cpp +1 -1
  69. package/nitrogen/generated/shared/c++/HybridNetDriverSpec.hpp +1 -1
  70. package/nitrogen/generated/shared/c++/HybridNetServerDriverSpec.cpp +1 -1
  71. package/nitrogen/generated/shared/c++/HybridNetServerDriverSpec.hpp +1 -1
  72. package/nitrogen/generated/shared/c++/HybridNetSocketDriverSpec.cpp +1 -1
  73. package/nitrogen/generated/shared/c++/HybridNetSocketDriverSpec.hpp +1 -1
  74. package/nitrogen/generated/shared/c++/HybridNitroBufferSpec.cpp +1 -1
  75. package/nitrogen/generated/shared/c++/HybridNitroBufferSpec.hpp +1 -1
  76. package/nitrogen/generated/shared/c++/NetConfig.hpp +1 -1
  77. package/package.json +4 -5
  78. package/src/Net.nitro.ts +6 -2
  79. package/src/http.ts +37 -19
  80. package/src/net.ts +19 -10
@@ -2,10 +2,9 @@
2
2
  /// HybridNetSocketDriverSpec_cxx.swift
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2026 Marc Rousavy @ Margelo
5
+ /// Copyright © Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
- import Foundation
9
8
  import NitroModules
10
9
 
11
10
  /**
@@ -96,6 +95,14 @@ open class HybridNetSocketDriverSpec_cxx {
96
95
  return MemoryHelper.getSizeOf(self.__implementation) + self.__implementation.memorySize
97
96
  }
98
97
 
98
+ /**
99
+ * Compares this object with the given [other] object for reference equality.
100
+ */
101
+ @inline(__always)
102
+ public func equals(other: HybridNetSocketDriverSpec_cxx) -> Bool {
103
+ return self.__implementation === other.__implementation
104
+ }
105
+
99
106
  /**
100
107
  * Call dispose() on the Swift class.
101
108
  * This _may_ be called manually from JS.
@@ -194,7 +201,14 @@ open class HybridNetSocketDriverSpec_cxx {
194
201
  } else {
195
202
  return nil
196
203
  }
197
- }(), secureContextId: secureContextId.value)
204
+ }(), secureContextId: { () -> Double? in
205
+ if bridge.has_value_std__optional_double_(secureContextId) {
206
+ let __unwrapped = bridge.get_std__optional_double_(secureContextId)
207
+ return __unwrapped
208
+ } else {
209
+ return nil
210
+ }
211
+ }())
198
212
  return bridge.create_Result_void_()
199
213
  } catch (let __error) {
200
214
  let __exceptionPtr = __error.toCpp()
@@ -422,7 +436,14 @@ open class HybridNetSocketDriverSpec_cxx {
422
436
  } else {
423
437
  return nil
424
438
  }
425
- }(), secureContextId: secureContextId.value)
439
+ }(), secureContextId: { () -> Double? in
440
+ if bridge.has_value_std__optional_double_(secureContextId) {
441
+ let __unwrapped = bridge.get_std__optional_double_(secureContextId)
442
+ return __unwrapped
443
+ } else {
444
+ return nil
445
+ }
446
+ }())
426
447
  return bridge.create_Result_void_()
427
448
  } catch (let __error) {
428
449
  let __exceptionPtr = __error.toCpp()
@@ -2,10 +2,9 @@
2
2
  /// NetConfig.swift
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2026 Marc Rousavy @ Margelo
5
+ /// Copyright © Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
- import Foundation
9
8
  import NitroModules
10
9
 
11
10
  /**
@@ -37,7 +36,14 @@ public extension NetConfig {
37
36
 
38
37
  @inline(__always)
39
38
  var workerThreads: Double? {
40
- return self.__workerThreads.value
39
+ return { () -> Double? in
40
+ if bridge.has_value_std__optional_double_(self.__workerThreads) {
41
+ let __unwrapped = bridge.get_std__optional_double_(self.__workerThreads)
42
+ return __unwrapped
43
+ } else {
44
+ return nil
45
+ }
46
+ }()
41
47
  }
42
48
 
43
49
  @inline(__always)
@@ -0,0 +1,89 @@
1
+ ///
2
+ /// HttpParsedMessage.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #if __has_include(<NitroModules/JSIConverter.hpp>)
11
+ #include <NitroModules/JSIConverter.hpp>
12
+ #else
13
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
14
+ #endif
15
+ #if __has_include(<NitroModules/NitroDefines.hpp>)
16
+ #include <NitroModules/NitroDefines.hpp>
17
+ #else
18
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
19
+ #endif
20
+ #if __has_include(<NitroModules/JSIHelpers.hpp>)
21
+ #include <NitroModules/JSIHelpers.hpp>
22
+ #else
23
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
24
+ #endif
25
+ #if __has_include(<NitroModules/PropNameIDCache.hpp>)
26
+ #include <NitroModules/PropNameIDCache.hpp>
27
+ #else
28
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
29
+ #endif
30
+
31
+
32
+
33
+ #include <string>
34
+ #include <NitroModules/ArrayBuffer.hpp>
35
+ #include <optional>
36
+
37
+ namespace margelo::nitro::net {
38
+
39
+ /**
40
+ * A struct which can be represented as a JavaScript object (HttpParsedMessage).
41
+ */
42
+ struct HttpParsedMessage final {
43
+ public:
44
+ std::string metadata SWIFT_PRIVATE;
45
+ std::optional<std::shared_ptr<ArrayBuffer>> body SWIFT_PRIVATE;
46
+
47
+ public:
48
+ HttpParsedMessage() = default;
49
+ explicit HttpParsedMessage(std::string metadata, std::optional<std::shared_ptr<ArrayBuffer>> body): metadata(metadata), body(body) {}
50
+
51
+ public:
52
+ friend bool operator==(const HttpParsedMessage& lhs, const HttpParsedMessage& rhs) = default;
53
+ };
54
+
55
+ } // namespace margelo::nitro::net
56
+
57
+ namespace margelo::nitro {
58
+
59
+ // C++ HttpParsedMessage <> JS HttpParsedMessage (object)
60
+ template <>
61
+ struct JSIConverter<margelo::nitro::net::HttpParsedMessage> final {
62
+ static inline margelo::nitro::net::HttpParsedMessage fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
63
+ jsi::Object obj = arg.asObject(runtime);
64
+ return margelo::nitro::net::HttpParsedMessage(
65
+ JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "metadata"))),
66
+ JSIConverter<std::optional<std::shared_ptr<ArrayBuffer>>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "body")))
67
+ );
68
+ }
69
+ static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::net::HttpParsedMessage& arg) {
70
+ jsi::Object obj(runtime);
71
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "metadata"), JSIConverter<std::string>::toJSI(runtime, arg.metadata));
72
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "body"), JSIConverter<std::optional<std::shared_ptr<ArrayBuffer>>>::toJSI(runtime, arg.body));
73
+ return obj;
74
+ }
75
+ static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
76
+ if (!value.isObject()) {
77
+ return false;
78
+ }
79
+ jsi::Object obj = value.getObject(runtime);
80
+ if (!nitro::isPlainObject(runtime, obj)) {
81
+ return false;
82
+ }
83
+ if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "metadata")))) return false;
84
+ if (!JSIConverter<std::optional<std::shared_ptr<ArrayBuffer>>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "body")))) return false;
85
+ return true;
86
+ }
87
+ };
88
+
89
+ } // namespace margelo::nitro
@@ -2,7 +2,7 @@
2
2
  /// HybridHttpParserSpec.cpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2026 Marc Rousavy @ Margelo
5
+ /// Copyright © Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #include "HybridHttpParserSpec.hpp"
@@ -2,7 +2,7 @@
2
2
  /// HybridHttpParserSpec.hpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2026 Marc Rousavy @ Margelo
5
+ /// Copyright © Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #pragma once
@@ -13,9 +13,10 @@
13
13
  #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
14
14
  #endif
15
15
 
16
+ // Forward declaration of `HttpParsedMessage` to properly resolve imports.
17
+ namespace margelo::nitro::net { struct HttpParsedMessage; }
16
18
 
17
-
18
- #include <string>
19
+ #include "HttpParsedMessage.hpp"
19
20
  #include <NitroModules/ArrayBuffer.hpp>
20
21
 
21
22
  namespace margelo::nitro::net {
@@ -49,7 +50,7 @@ namespace margelo::nitro::net {
49
50
 
50
51
  public:
51
52
  // Methods
52
- virtual std::string feed(const std::shared_ptr<ArrayBuffer>& data) = 0;
53
+ virtual HttpParsedMessage feed(const std::shared_ptr<ArrayBuffer>& data) = 0;
53
54
 
54
55
  protected:
55
56
  // Hybrid Setup
@@ -2,7 +2,7 @@
2
2
  /// HybridNetDriverSpec.cpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2026 Marc Rousavy @ Margelo
5
+ /// Copyright © Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #include "HybridNetDriverSpec.hpp"
@@ -2,7 +2,7 @@
2
2
  /// HybridNetDriverSpec.hpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2026 Marc Rousavy @ Margelo
5
+ /// Copyright © Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #pragma once
@@ -2,7 +2,7 @@
2
2
  /// HybridNetServerDriverSpec.cpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2026 Marc Rousavy @ Margelo
5
+ /// Copyright © Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #include "HybridNetServerDriverSpec.hpp"
@@ -2,7 +2,7 @@
2
2
  /// HybridNetServerDriverSpec.hpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2026 Marc Rousavy @ Margelo
5
+ /// Copyright © Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #pragma once
@@ -2,7 +2,7 @@
2
2
  /// HybridNetSocketDriverSpec.cpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2026 Marc Rousavy @ Margelo
5
+ /// Copyright © Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #include "HybridNetSocketDriverSpec.hpp"
@@ -2,7 +2,7 @@
2
2
  /// HybridNetSocketDriverSpec.hpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2026 Marc Rousavy @ Margelo
5
+ /// Copyright © Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #pragma once
@@ -2,7 +2,7 @@
2
2
  /// HybridNitroBufferSpec.cpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2026 Marc Rousavy @ Margelo
5
+ /// Copyright © Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #include "HybridNitroBufferSpec.hpp"
@@ -2,7 +2,7 @@
2
2
  /// HybridNitroBufferSpec.hpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2026 Marc Rousavy @ Margelo
5
+ /// Copyright © Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #pragma once
@@ -2,7 +2,7 @@
2
2
  /// NetConfig.hpp
3
3
  /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2026 Marc Rousavy @ Margelo
5
+ /// Copyright © Marc Rousavy @ Margelo
6
6
  ///
7
7
 
8
8
  #pragma once
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-nitro-net",
3
3
  "description": "Ultra-high-performance networking to React Native by combining a memory-safe Rust core with the zero-overhead Nitro Modules JSI bridge. Provides Node.js-compatible net, tls, http(s) API.",
4
- "version": "0.4.2",
4
+ "version": "0.4.3",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
7
7
  "module": "./lib/index.js",
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "scripts": {
29
29
  "one": "yarn copy-clib && yarn build && yarn pack",
30
- "build": "npx nitrogen@0.32.0 && tsc",
30
+ "build": "npx nitrogen@0.35.0 && tsc",
31
31
  "prepare": "npm run build",
32
32
  "copy-clib": "npm run copy-clib-android && npm run copy-clib-ios && npm run copy-clib-mac",
33
33
  "copy-clib-android": "mkdir -p android/libs/arm64-v8a android/libs/armeabi-v7a android/libs/x86 android/libs/x86_64 && cp ../rust_c_net/target/aarch64-linux-android/release/librust_c_net.so android/libs/arm64-v8a/ && cp ../rust_c_net/target/armv7-linux-androideabi/release/librust_c_net.so android/libs/armeabi-v7a/ && cp ../rust_c_net/target/i686-linux-android/release/librust_c_net.so android/libs/x86/ && cp ../rust_c_net/target/x86_64-linux-android/release/librust_c_net.so android/libs/x86_64/ && cp ../rust_c_net/include/NetBindings.hpp cpp/",
@@ -42,13 +42,12 @@
42
42
  "devDependencies": {
43
43
  "@types/node": "*",
44
44
  "@types/readable-stream": "^4.0.23",
45
- "nitrogen": "^0.32.0",
46
- "react-native-nitro-modules": "^0.32.0",
45
+ "react-native-nitro-modules": "0.35.0",
47
46
  "typescript": "^5.3.3"
48
47
  },
49
48
  "peerDependencies": {
50
49
  "react-native": "*",
51
- "react-native-nitro-modules": "^0.32.0"
50
+ "react-native-nitro-modules": "0.35.0"
52
51
  },
53
52
  "packageManager": "yarn@4.12.0",
54
53
  "files": [
package/src/Net.nitro.ts CHANGED
@@ -82,14 +82,18 @@ export interface NetServerDriver extends HybridObject<{ ios: 'swift', android: '
82
82
  maxConnections: number
83
83
  close(): void
84
84
  }
85
+ export interface HttpParsedMessage {
86
+ metadata: string
87
+ body?: ArrayBuffer
88
+ }
85
89
 
86
90
  export interface HttpParser extends HybridObject<{ ios: 'swift', android: 'kotlin' }> {
87
91
  /**
88
92
  * Feed data to the parser
89
93
  * @param data Raw byte data from the network
90
- * @returns JSON string of the parsed message if complete, empty string if partial, or error message starting with 'ERROR:'
94
+ * @returns HttpParsedMessage containing the JSON metadata and optional binary body
91
95
  */
92
- feed(data: ArrayBuffer): string
96
+ feed(data: ArrayBuffer): HttpParsedMessage
93
97
  }
94
98
 
95
99
  /**
package/src/http.ts CHANGED
@@ -145,9 +145,6 @@ export class OutgoingMessage extends Writable {
145
145
  constructor() {
146
146
  // @ts-ignore - disable autoDestroy to prevent socket from being destroyed when stream ends
147
147
  super({ autoDestroy: false });
148
- this.once('finish', () => {
149
- this.emit('close');
150
- });
151
148
  }
152
149
 
153
150
  public destroy(error?: Error): this {
@@ -319,6 +316,16 @@ export class ServerResponse extends OutgoingMessage {
319
316
  constructor(socket: Socket) {
320
317
  super();
321
318
  this.socket = socket;
319
+
320
+ const onClose = () => {
321
+ if (this.socket) {
322
+ this.socket.removeListener('close', onClose);
323
+ }
324
+ this.removeListener('finish', onClose);
325
+ this.emit('close');
326
+ };
327
+ this.once('finish', onClose);
328
+ this.socket.once('close', onClose);
322
329
  }
323
330
 
324
331
  writeHead(statusCode: number, statusMessage?: string | Record<string, any>, headers?: Record<string, any>): this {
@@ -468,14 +475,18 @@ export class Server extends EventEmitter {
468
475
  }
469
476
 
470
477
  const onData = (data: Buffer) => {
471
- const handleParsedResult = (result: string) => {
472
- if (result.startsWith('ERROR:')) {
478
+ const handleParsedResult = (result: any) => {
479
+ const metadata = result.metadata;
480
+ if (metadata.startsWith('ERROR:')) {
473
481
  if (headersTimer) clearTimeout(headersTimer);
474
- this.emit('error', new Error(result));
482
+ this.emit('error', new Error(metadata));
475
483
  socket.destroy();
476
484
  return;
477
485
  }
478
- const parsed = JSON.parse(result);
486
+ const parsed = JSON.parse(metadata);
487
+ if (result.body) {
488
+ parsed.body = Buffer.from(result.body);
489
+ }
479
490
 
480
491
  if (parsed.is_headers) {
481
492
  if (headersTimer) {
@@ -567,14 +578,15 @@ export class Server extends EventEmitter {
567
578
 
568
579
  let input: ArrayBuffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
569
580
  let iterations = 0;
570
- const maxIterations = 100; // Safety limit
581
+ const maxIterations = 2000; // Safety limit
571
582
  while (iterations < maxIterations) {
572
583
  iterations++;
573
584
  const result = parser.feed(input);
574
- if (!result || result === '' || result.startsWith('ERROR:')) {
585
+ const metadata = result.metadata;
586
+ if (!metadata || metadata === '' || metadata.startsWith('ERROR:')) {
575
587
  // Empty result (partial) or error - exit loop
576
- if (result && result.startsWith('ERROR:')) {
577
- debugLog(`[HTTP] Server: Parser error: ${result}`);
588
+ if (metadata && metadata.startsWith('ERROR:')) {
589
+ debugLog(`[HTTP] Server: Parser error: ${metadata}`);
578
590
  }
579
591
  break;
580
592
  }
@@ -1025,13 +1037,17 @@ export class ClientRequest extends OutgoingMessage {
1025
1037
  const parser = Driver.createHttpParser(1); // 1 = Response mode
1026
1038
 
1027
1039
  const onData = (data: Buffer) => {
1028
- const handleParsedResult = (result: string) => {
1029
- if (result.startsWith('ERROR:')) {
1030
- this.emit('error', new Error(result));
1040
+ const handleParsedResult = (result: any) => {
1041
+ const metadata = result.metadata;
1042
+ if (metadata.startsWith('ERROR:')) {
1043
+ this.emit('error', new Error(metadata));
1031
1044
  this.socket!.destroy();
1032
1045
  return;
1033
1046
  }
1034
- const parsed = JSON.parse(result);
1047
+ const parsed = JSON.parse(metadata);
1048
+ if (result.body) {
1049
+ parsed.body = Buffer.from(result.body);
1050
+ }
1035
1051
  debugLog(`[HTTP] _connect: Parser result: ${parsed.is_headers ? 'HEADERS' : 'DATA'}${parsed.complete ? ' (COMPLETE)' : ''}`);
1036
1052
 
1037
1053
  if (parsed.is_headers) {
@@ -1097,14 +1113,15 @@ export class ClientRequest extends OutgoingMessage {
1097
1113
 
1098
1114
  let input: ArrayBuffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
1099
1115
  let iterations = 0;
1100
- const maxIterations = 100; // Safety limit
1116
+ const maxIterations = 2000; // Safety limit
1101
1117
  while (iterations < maxIterations) {
1102
1118
  iterations++;
1103
1119
  const result = parser.feed(input);
1104
- if (!result || result === '' || result.startsWith('ERROR:')) {
1120
+ const metadata = result.metadata;
1121
+ if (!metadata || metadata === '' || metadata.startsWith('ERROR:')) {
1105
1122
  // Empty result (partial) or error - exit loop
1106
- if (result && result.startsWith('ERROR:')) {
1107
- debugLog(`[HTTP] ClientRequest: Parser error: ${result}`);
1123
+ if (metadata && metadata.startsWith('ERROR:')) {
1124
+ debugLog(`[HTTP] ClientRequest: Parser error: ${metadata}`);
1108
1125
  }
1109
1126
  break;
1110
1127
  }
@@ -1151,6 +1168,7 @@ export class ClientRequest extends OutgoingMessage {
1151
1168
  const socket = this.socket;
1152
1169
  this._cleanupSocket();
1153
1170
  if (socket) agent.releaseSocket(socket, this._options);
1171
+ this.emit('close');
1154
1172
  }
1155
1173
 
1156
1174
  private _flushPendingWrites() {
package/src/net.ts CHANGED
@@ -27,6 +27,18 @@ function isIPv4(input: string): boolean {
27
27
  function isIPv6(input: string): boolean {
28
28
  return isIP(input) === 6;
29
29
  }
30
+
31
+ /**
32
+ * Decodes an ArrayBuffer to a string.
33
+ * Prioritizes TextDecoder if available, otherwise falls back to Buffer.
34
+ */
35
+ function decodeArrayBuffer(data: ArrayBuffer | undefined): string {
36
+ if (!data || data.byteLength === 0) return '';
37
+ if (typeof TextDecoder !== 'undefined') {
38
+ return new TextDecoder().decode(data);
39
+ }
40
+ return Buffer.from(data).toString();
41
+ }
30
42
  // -----------------------------------------------------------------------------
31
43
  // Global Configuration
32
44
  // -----------------------------------------------------------------------------
@@ -335,9 +347,6 @@ export class Socket extends Duplex {
335
347
  // resume() will be called after 'connect' event in _connect()
336
348
  }
337
349
 
338
- this.on('finish', () => {
339
- // Writable side finished
340
- });
341
350
  }
342
351
 
343
352
  on(event: string | symbol, listener: (...args: any[]) => void): this {
@@ -358,11 +367,11 @@ export class Socket extends Duplex {
358
367
  const id = (this._driver as any).id ?? (this._driver as any)._id;
359
368
  this._driver.onEvent = (eventType: number, data: ArrayBuffer) => {
360
369
  this.emit('event', eventType, data);
361
- if (eventType === 3) { // ERROR
362
- const msg = new TextDecoder().decode(data);
370
+ if (eventType === NetSocketEvent.ERROR) {
371
+ const msg = decodeArrayBuffer(data) || 'Unknown error';
363
372
  debugLog(`Socket (id: ${id}) NATIVE ERROR: ${msg}`);
364
373
  }
365
- if (eventType === 9) { // SESSION/DEBUG
374
+ if (eventType === NetSocketEvent.SESSION) { // SESSION/DEBUG
366
375
  debugLog(`Socket (id: ${id}) NATIVE SESSION EVENT RECEIVED`);
367
376
  this.emit('session', data);
368
377
  return;
@@ -390,7 +399,7 @@ export class Socket extends Duplex {
390
399
  break;
391
400
  case NetSocketEvent.ERROR: {
392
401
  this._hadError = true;
393
- const errorMsg = data ? Buffer.from(data).toString() : 'Unknown socket error';
402
+ const errorMsg = decodeArrayBuffer(data) || 'Unknown socket error';
394
403
  const error = new Error(errorMsg);
395
404
 
396
405
  if (this.connecting && this._autoSelectFamily) {
@@ -431,7 +440,7 @@ export class Socket extends Duplex {
431
440
  break;
432
441
  case NetSocketEvent.LOOKUP: {
433
442
  if (data) {
434
- const lookupStr = Buffer.from(data).toString();
443
+ const lookupStr = decodeArrayBuffer(data);
435
444
  const parts = lookupStr.split(',');
436
445
  if (parts.length >= 2) {
437
446
  const [ip, family] = parts;
@@ -770,7 +779,7 @@ export class Server extends EventEmitter {
770
779
  this._driver.onEvent = (eventType: number, data: ArrayBuffer) => {
771
780
  switch (eventType) {
772
781
  case NetServerEvent.CONNECTION: {
773
- const payload = data ? Buffer.from(data).toString() : '';
782
+ const payload = decodeArrayBuffer(data);
774
783
  if (payload === 'success') {
775
784
  this.emit('listening');
776
785
  } else {
@@ -828,7 +837,7 @@ export class Server extends EventEmitter {
828
837
  break;
829
838
  }
830
839
  case NetServerEvent.ERROR:
831
- this.emit('error', new Error(data ? Buffer.from(data).toString() : 'Unknown server error'));
840
+ this.emit('error', new Error(decodeArrayBuffer(data) || 'Unknown server error'));
832
841
  break;
833
842
  case NetServerEvent.DEBUG: {
834
843
  debugLog(`Server NATIVE SESSION/DEBUG EVENT RECEIVED`);