react-native-nitro-fetch 0.3.0-beta.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/NitroFetch.podspec +8 -0
- package/android/build.gradle +3 -0
- package/android/src/main/java/com/margelo/nitro/nitrofetch/NitroFetchClient.kt +46 -2
- package/android/src/main/java/com/margelo/nitro/nitrofetch/NitroFetchPackage.kt +2 -2
- package/ios/NitroFetchClient.swift +36 -1
- package/lib/module/CurlGenerator.js +28 -0
- package/lib/module/CurlGenerator.js.map +1 -0
- package/lib/module/Headers.js +95 -0
- package/lib/module/Headers.js.map +1 -0
- package/lib/module/HermesProfiler.js +28 -0
- package/lib/module/HermesProfiler.js.map +1 -0
- package/lib/module/NetworkInspector.js +184 -0
- package/lib/module/NetworkInspector.js.map +1 -0
- package/lib/module/Request.js +120 -0
- package/lib/module/Request.js.map +1 -0
- package/lib/module/Response.js +236 -0
- package/lib/module/Response.js.map +1 -0
- package/lib/module/fetch.js +143 -56
- package/lib/module/fetch.js.map +1 -1
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/utf8.js +29 -0
- package/lib/module/utf8.js.map +1 -0
- package/lib/typescript/src/CurlGenerator.d.ts +13 -0
- package/lib/typescript/src/CurlGenerator.d.ts.map +1 -0
- package/lib/typescript/src/Headers.d.ts +19 -0
- package/lib/typescript/src/Headers.d.ts.map +1 -0
- package/lib/typescript/src/HermesProfiler.d.ts +6 -0
- package/lib/typescript/src/HermesProfiler.d.ts.map +1 -0
- package/lib/typescript/src/NetworkInspector.d.ts +96 -0
- package/lib/typescript/src/NetworkInspector.d.ts.map +1 -0
- package/lib/typescript/src/Request.d.ts +48 -0
- package/lib/typescript/src/Request.d.ts.map +1 -0
- package/lib/typescript/src/Response.d.ts +56 -0
- package/lib/typescript/src/Response.d.ts.map +1 -0
- package/lib/typescript/src/fetch.d.ts +11 -3
- package/lib/typescript/src/fetch.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +13 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/utf8.d.ts +3 -0
- package/lib/typescript/src/utf8.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/CurlGenerator.ts +44 -0
- package/src/Headers.ts +127 -0
- package/src/HermesProfiler.ts +37 -0
- package/src/NetworkInspector.ts +278 -0
- package/src/Request.ts +187 -0
- package/src/Response.ts +335 -0
- package/src/fetch.ts +186 -75
- package/src/index.tsx +22 -1
- package/src/utf8.ts +40 -0
package/NitroFetch.podspec
CHANGED
|
@@ -26,5 +26,13 @@ Pod::Spec.new do |s|
|
|
|
26
26
|
load 'nitrogen/generated/ios/NitroFetch+autolinking.rb'
|
|
27
27
|
add_nitrogen_files(s)
|
|
28
28
|
|
|
29
|
+
if ENV['NITROFETCH_TRACING'] == '1'
|
|
30
|
+
current_xcconfig = s.attributes_hash['pod_target_xcconfig'] || {}
|
|
31
|
+
existing = current_xcconfig['SWIFT_ACTIVE_COMPILATION_CONDITIONS'] || '$(inherited)'
|
|
32
|
+
s.pod_target_xcconfig = current_xcconfig.merge({
|
|
33
|
+
'SWIFT_ACTIVE_COMPILATION_CONDITIONS' => "#{existing} NITROFETCH_TRACING"
|
|
34
|
+
})
|
|
35
|
+
end
|
|
36
|
+
|
|
29
37
|
install_modules_dependencies(s)
|
|
30
38
|
end
|
package/android/build.gradle
CHANGED
|
@@ -39,6 +39,9 @@ android {
|
|
|
39
39
|
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
|
|
40
40
|
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
|
|
41
41
|
|
|
42
|
+
def enableTracing = (getExtOrDefault("enableTracing") ?: "false").toString().toBoolean()
|
|
43
|
+
buildConfigField "boolean", "NITRO_FETCH_TRACING", enableTracing.toString()
|
|
44
|
+
|
|
42
45
|
externalNativeBuild {
|
|
43
46
|
cmake {
|
|
44
47
|
cppFlags "-frtti -fexceptions -Wall -fstack-protector-all"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package com.margelo.nitro.nitrofetch
|
|
2
2
|
|
|
3
3
|
import android.net.Uri
|
|
4
|
+
import android.os.Trace
|
|
4
5
|
import android.util.Log
|
|
5
6
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
6
7
|
import com.margelo.nitro.NitroModules
|
|
@@ -71,12 +72,44 @@ class NitroFetchClient(private val engine: CronetEngine, private val executor: E
|
|
|
71
72
|
onFail: (Throwable) -> Unit
|
|
72
73
|
): UrlRequest {
|
|
73
74
|
val url = req.url
|
|
75
|
+
val shouldFollowRedirects = req.followRedirects ?: true
|
|
76
|
+
val traceLabel = if (BuildConfig.NITRO_FETCH_TRACING) {
|
|
77
|
+
"NitroFetch ${req.method?.name ?: "GET"} ${Uri.parse(url).path ?: url}"
|
|
78
|
+
} else ""
|
|
79
|
+
val traceCookie = if (BuildConfig.NITRO_FETCH_TRACING) url.hashCode() else 0
|
|
80
|
+
if (BuildConfig.NITRO_FETCH_TRACING) {
|
|
81
|
+
Trace.beginAsyncSection(traceLabel, traceCookie)
|
|
82
|
+
}
|
|
74
83
|
val callback = object : UrlRequest.Callback() {
|
|
75
84
|
private val buffer = ByteBuffer.allocateDirect(16 * 1024)
|
|
76
85
|
private val out = java.io.ByteArrayOutputStream()
|
|
86
|
+
private var redirectStopped = false
|
|
77
87
|
|
|
78
88
|
override fun onRedirectReceived(request: UrlRequest, info: UrlResponseInfo, newLocationUrl: String) {
|
|
79
|
-
|
|
89
|
+
if (shouldFollowRedirects) {
|
|
90
|
+
request.followRedirect()
|
|
91
|
+
} else {
|
|
92
|
+
// Return the redirect response as-is without following
|
|
93
|
+
redirectStopped = true
|
|
94
|
+
request.cancel()
|
|
95
|
+
try {
|
|
96
|
+
val headersArr = info.allHeadersAsList.map { NitroHeader(it.key, it.value) }.toTypedArray()
|
|
97
|
+
val status = info.httpStatusCode
|
|
98
|
+
val res = NitroResponse(
|
|
99
|
+
url = info.url,
|
|
100
|
+
status = status.toDouble(),
|
|
101
|
+
statusText = info.httpStatusText ?: "",
|
|
102
|
+
ok = false,
|
|
103
|
+
redirected = false,
|
|
104
|
+
headers = headersArr,
|
|
105
|
+
bodyString = "",
|
|
106
|
+
bodyBytes = null
|
|
107
|
+
)
|
|
108
|
+
onSuccess(res)
|
|
109
|
+
} catch (t: Throwable) {
|
|
110
|
+
onFail(t)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
80
113
|
}
|
|
81
114
|
|
|
82
115
|
override fun onResponseStarted(request: UrlRequest, info: UrlResponseInfo) {
|
|
@@ -94,6 +127,9 @@ class NitroFetchClient(private val engine: CronetEngine, private val executor: E
|
|
|
94
127
|
}
|
|
95
128
|
|
|
96
129
|
override fun onSucceeded(request: UrlRequest, info: UrlResponseInfo) {
|
|
130
|
+
if (BuildConfig.NITRO_FETCH_TRACING) {
|
|
131
|
+
Trace.endAsyncSection(traceLabel, traceCookie)
|
|
132
|
+
}
|
|
97
133
|
try {
|
|
98
134
|
val headersArr: Array<NitroHeader> =
|
|
99
135
|
info.allHeadersAsList.map { NitroHeader(it.key, it.value) }.toTypedArray()
|
|
@@ -127,11 +163,19 @@ class NitroFetchClient(private val engine: CronetEngine, private val executor: E
|
|
|
127
163
|
}
|
|
128
164
|
|
|
129
165
|
override fun onFailed(request: UrlRequest, info: UrlResponseInfo?, error: CronetException) {
|
|
166
|
+
if (BuildConfig.NITRO_FETCH_TRACING) {
|
|
167
|
+
Trace.endAsyncSection(traceLabel, traceCookie)
|
|
168
|
+
}
|
|
130
169
|
onFail(RuntimeException("Cronet failed: ${error.message}", error))
|
|
131
170
|
}
|
|
132
171
|
|
|
133
172
|
override fun onCanceled(request: UrlRequest, info: UrlResponseInfo?) {
|
|
134
|
-
|
|
173
|
+
if (BuildConfig.NITRO_FETCH_TRACING) {
|
|
174
|
+
Trace.endAsyncSection(traceLabel, traceCookie)
|
|
175
|
+
}
|
|
176
|
+
if (!redirectStopped) {
|
|
177
|
+
onFail(RuntimeException("Cronet canceled"))
|
|
178
|
+
}
|
|
135
179
|
}
|
|
136
180
|
}
|
|
137
181
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
package com.margelo.nitro.nitrofetch
|
|
2
2
|
|
|
3
|
-
import com.facebook.react.
|
|
3
|
+
import com.facebook.react.BaseReactPackage
|
|
4
4
|
import com.facebook.react.bridge.NativeModule
|
|
5
5
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
6
|
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
7
7
|
|
|
8
|
-
class NitroFetchPackage :
|
|
8
|
+
class NitroFetchPackage : BaseReactPackage() {
|
|
9
9
|
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
|
|
10
10
|
return null
|
|
11
11
|
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import NitroModules
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
#if NITROFETCH_TRACING
|
|
6
|
+
private let fetchLog = OSLog(subsystem: "com.margelo.nitrofetch", category: "network")
|
|
7
|
+
#endif
|
|
3
8
|
|
|
4
9
|
final class NitroFetchClient: HybridNitroFetchClientSpec {
|
|
5
10
|
|
|
@@ -154,7 +159,18 @@ final class NitroFetchClient: HybridNitroFetchClientSpec {
|
|
|
154
159
|
}
|
|
155
160
|
|
|
156
161
|
let (urlRequest, finalURL) = try await buildURLRequest(req)
|
|
157
|
-
let
|
|
162
|
+
let shouldFollowRedirects = req.followRedirects ?? true
|
|
163
|
+
let delegate: URLSessionTaskDelegate? = shouldFollowRedirects ? nil : NoRedirectDelegate()
|
|
164
|
+
|
|
165
|
+
#if NITROFETCH_TRACING
|
|
166
|
+
let signpostID = OSSignpostID(log: fetchLog)
|
|
167
|
+
let traceMethod = req.method?.stringValue ?? "GET"
|
|
168
|
+
let tracePath = URL(string: req.url)?.path ?? req.url
|
|
169
|
+
os_signpost(.begin, log: fetchLog, name: "NitroFetch", signpostID: signpostID,
|
|
170
|
+
"%{public}s %{public}s", traceMethod, tracePath)
|
|
171
|
+
#endif
|
|
172
|
+
|
|
173
|
+
let (data, response) = try await session.data(for: urlRequest, delegate: delegate)
|
|
158
174
|
guard let http = response as? HTTPURLResponse else {
|
|
159
175
|
throw NSError(domain: "NitroFetch", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid response"])
|
|
160
176
|
}
|
|
@@ -181,6 +197,11 @@ final class NitroFetchClient: HybridNitroFetchClientSpec {
|
|
|
181
197
|
|
|
182
198
|
// Do not write to cache here; only prefetch should populate the cache
|
|
183
199
|
|
|
200
|
+
#if NITROFETCH_TRACING
|
|
201
|
+
os_signpost(.end, log: fetchLog, name: "NitroFetch", signpostID: signpostID,
|
|
202
|
+
"status=%d bytes=%d", http.statusCode, data.count)
|
|
203
|
+
#endif
|
|
204
|
+
|
|
184
205
|
return res
|
|
185
206
|
}
|
|
186
207
|
|
|
@@ -310,3 +331,17 @@ final class NitroFetchClient: HybridNitroFetchClientSpec {
|
|
|
310
331
|
return nil
|
|
311
332
|
}
|
|
312
333
|
}
|
|
334
|
+
|
|
335
|
+
/// Delegate that prevents URLSession from following HTTP redirects.
|
|
336
|
+
/// When the completion handler receives `nil`, the 3xx response is returned as-is.
|
|
337
|
+
final class NoRedirectDelegate: NSObject, URLSessionTaskDelegate {
|
|
338
|
+
func urlSession(
|
|
339
|
+
_ session: URLSession,
|
|
340
|
+
task: URLSessionTask,
|
|
341
|
+
willPerformHTTPRedirection response: HTTPURLResponse,
|
|
342
|
+
newRequest request: URLRequest,
|
|
343
|
+
completionHandler: @escaping @Sendable (URLRequest?) -> Void
|
|
344
|
+
) {
|
|
345
|
+
completionHandler(nil)
|
|
346
|
+
}
|
|
347
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function shellEscape(str) {
|
|
4
|
+
if (/^[a-zA-Z0-9._\-/:=@,+]+$/.test(str)) return str;
|
|
5
|
+
return "'" + str.replace(/'/g, "'\\''") + "'";
|
|
6
|
+
}
|
|
7
|
+
export function generateCurl(options) {
|
|
8
|
+
const parts = ['curl'];
|
|
9
|
+
if (options.method && options.method !== 'GET') {
|
|
10
|
+
parts.push('-X', shellEscape(options.method));
|
|
11
|
+
}
|
|
12
|
+
if (options.headers) {
|
|
13
|
+
for (const h of options.headers) {
|
|
14
|
+
if (h.key.toLowerCase() === 'prefetchkey') continue;
|
|
15
|
+
parts.push('-H', shellEscape(`${h.key}: ${h.value}`));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (options.body) {
|
|
19
|
+
const maxLen = 10_000;
|
|
20
|
+
const truncated = options.body.length > maxLen ? options.body.slice(0, maxLen) + '...[truncated]' : options.body;
|
|
21
|
+
parts.push('-d', shellEscape(truncated));
|
|
22
|
+
}
|
|
23
|
+
if (options.verbose) parts.push('-v');
|
|
24
|
+
if (options.compressed) parts.push('--compressed');
|
|
25
|
+
parts.push(shellEscape(options.url));
|
|
26
|
+
return parts.join(' ');
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=CurlGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["shellEscape","str","test","replace","generateCurl","options","parts","method","push","headers","h","key","toLowerCase","value","body","maxLen","truncated","length","slice","verbose","compressed","url","join"],"sourceRoot":"../../src","sources":["CurlGenerator.ts"],"mappings":";;AASA,SAASA,WAAWA,CAACC,GAAW,EAAU;EACxC,IAAI,0BAA0B,CAACC,IAAI,CAACD,GAAG,CAAC,EAAE,OAAOA,GAAG;EACpD,OAAO,GAAG,GAAGA,GAAG,CAACE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,GAAG;AAC/C;AAEA,OAAO,SAASC,YAAYA,CAACC,OAAoB,EAAU;EACzD,MAAMC,KAAe,GAAG,CAAC,MAAM,CAAC;EAEhC,IAAID,OAAO,CAACE,MAAM,IAAIF,OAAO,CAACE,MAAM,KAAK,KAAK,EAAE;IAC9CD,KAAK,CAACE,IAAI,CAAC,IAAI,EAAER,WAAW,CAACK,OAAO,CAACE,MAAM,CAAC,CAAC;EAC/C;EAEA,IAAIF,OAAO,CAACI,OAAO,EAAE;IACnB,KAAK,MAAMC,CAAC,IAAIL,OAAO,CAACI,OAAO,EAAE;MAC/B,IAAIC,CAAC,CAACC,GAAG,CAACC,WAAW,CAAC,CAAC,KAAK,aAAa,EAAE;MAC3CN,KAAK,CAACE,IAAI,CAAC,IAAI,EAAER,WAAW,CAAC,GAAGU,CAAC,CAACC,GAAG,KAAKD,CAAC,CAACG,KAAK,EAAE,CAAC,CAAC;IACvD;EACF;EAEA,IAAIR,OAAO,CAACS,IAAI,EAAE;IAChB,MAAMC,MAAM,GAAG,MAAM;IACrB,MAAMC,SAAS,GACbX,OAAO,CAACS,IAAI,CAACG,MAAM,GAAGF,MAAM,GACxBV,OAAO,CAACS,IAAI,CAACI,KAAK,CAAC,CAAC,EAAEH,MAAM,CAAC,GAAG,gBAAgB,GAChDV,OAAO,CAACS,IAAI;IAClBR,KAAK,CAACE,IAAI,CAAC,IAAI,EAAER,WAAW,CAACgB,SAAS,CAAC,CAAC;EAC1C;EAEA,IAAIX,OAAO,CAACc,OAAO,EAAEb,KAAK,CAACE,IAAI,CAAC,IAAI,CAAC;EACrC,IAAIH,OAAO,CAACe,UAAU,EAAEd,KAAK,CAACE,IAAI,CAAC,cAAc,CAAC;EAElDF,KAAK,CAACE,IAAI,CAACR,WAAW,CAACK,OAAO,CAACgB,GAAG,CAAC,CAAC;EAEpC,OAAOf,KAAK,CAACgB,IAAI,CAAC,GAAG,CAAC;AACxB","ignoreList":[]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function normalizeName(name) {
|
|
4
|
+
return name.toLowerCase();
|
|
5
|
+
}
|
|
6
|
+
export class NitroHeaders {
|
|
7
|
+
constructor(init) {
|
|
8
|
+
this._map = new Map();
|
|
9
|
+
if (!init) return;
|
|
10
|
+
if (init instanceof NitroHeaders) {
|
|
11
|
+
init._map.forEach((values, key) => {
|
|
12
|
+
this._map.set(key, [...values]);
|
|
13
|
+
});
|
|
14
|
+
} else if (typeof Headers !== 'undefined' && init instanceof Headers) {
|
|
15
|
+
init.forEach((value, key) => {
|
|
16
|
+
this._map.set(normalizeName(key), [value]);
|
|
17
|
+
});
|
|
18
|
+
} else if (Array.isArray(init)) {
|
|
19
|
+
for (const entry of init) {
|
|
20
|
+
if (Array.isArray(entry) && entry.length >= 2) {
|
|
21
|
+
// [string, string] tuple
|
|
22
|
+
const key = normalizeName(String(entry[0]));
|
|
23
|
+
const value = String(entry[1]);
|
|
24
|
+
const existing = this._map.get(key);
|
|
25
|
+
if (existing) existing.push(value);else this._map.set(key, [value]);
|
|
26
|
+
} else if (entry && typeof entry === 'object' && 'key' in entry && 'value' in entry) {
|
|
27
|
+
// NitroHeader object
|
|
28
|
+
const key = normalizeName(entry.key);
|
|
29
|
+
const value = entry.value;
|
|
30
|
+
const existing = this._map.get(key);
|
|
31
|
+
if (existing) existing.push(value);else this._map.set(key, [value]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
} else if (typeof init === 'object' && init !== null) {
|
|
35
|
+
const keys = Object.keys(init);
|
|
36
|
+
for (let i = 0; i < keys.length; i++) {
|
|
37
|
+
const k = keys[i];
|
|
38
|
+
const v = init[k];
|
|
39
|
+
if (v !== undefined) {
|
|
40
|
+
this._map.set(normalizeName(k), [String(v)]);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
append(name, value) {
|
|
46
|
+
const key = normalizeName(name);
|
|
47
|
+
const existing = this._map.get(key);
|
|
48
|
+
if (existing) existing.push(value);else this._map.set(key, [value]);
|
|
49
|
+
}
|
|
50
|
+
delete(name) {
|
|
51
|
+
this._map.delete(normalizeName(name));
|
|
52
|
+
}
|
|
53
|
+
get(name) {
|
|
54
|
+
const values = this._map.get(normalizeName(name));
|
|
55
|
+
if (!values || values.length === 0) return null;
|
|
56
|
+
return values.join(', ');
|
|
57
|
+
}
|
|
58
|
+
getSetCookie() {
|
|
59
|
+
return this._map.get('set-cookie') ?? [];
|
|
60
|
+
}
|
|
61
|
+
has(name) {
|
|
62
|
+
return this._map.has(normalizeName(name));
|
|
63
|
+
}
|
|
64
|
+
set(name, value) {
|
|
65
|
+
this._map.set(normalizeName(name), [value]);
|
|
66
|
+
}
|
|
67
|
+
forEach(callback) {
|
|
68
|
+
const sortedKeys = Array.from(this._map.keys()).sort();
|
|
69
|
+
for (const key of sortedKeys) {
|
|
70
|
+
callback(this._map.get(key).join(', '), key, this);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
*entries() {
|
|
74
|
+
const sortedKeys = Array.from(this._map.keys()).sort();
|
|
75
|
+
for (const key of sortedKeys) {
|
|
76
|
+
yield [key, this._map.get(key).join(', ')];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
*keys() {
|
|
80
|
+
const sortedKeys = Array.from(this._map.keys()).sort();
|
|
81
|
+
for (const key of sortedKeys) {
|
|
82
|
+
yield key;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
*values() {
|
|
86
|
+
const sortedKeys = Array.from(this._map.keys()).sort();
|
|
87
|
+
for (const key of sortedKeys) {
|
|
88
|
+
yield this._map.get(key).join(', ');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
[Symbol.iterator]() {
|
|
92
|
+
return this.entries();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=Headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["normalizeName","name","toLowerCase","NitroHeaders","constructor","init","_map","Map","forEach","values","key","set","Headers","value","Array","isArray","entry","length","String","existing","get","push","keys","Object","i","k","v","undefined","append","delete","join","getSetCookie","has","callback","sortedKeys","from","sort","entries","Symbol","iterator"],"sourceRoot":"../../src","sources":["Headers.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
export async function profileFetch(fn, outputPath) {
|
|
4
|
+
const hermes = global.HermesInternal;
|
|
5
|
+
if (!hermes) {
|
|
6
|
+
const result = await fn();
|
|
7
|
+
return {
|
|
8
|
+
result
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
const path = outputPath ?? `/tmp/nitrofetch-profile-${Date.now()}.cpuprofile`;
|
|
12
|
+
hermes.enableSamplingProfiler();
|
|
13
|
+
try {
|
|
14
|
+
const result = await fn();
|
|
15
|
+
return {
|
|
16
|
+
result,
|
|
17
|
+
profilePath: path
|
|
18
|
+
};
|
|
19
|
+
} finally {
|
|
20
|
+
hermes.disableSamplingProfiler();
|
|
21
|
+
try {
|
|
22
|
+
hermes.dumpSamplingProfiler(path);
|
|
23
|
+
} catch {
|
|
24
|
+
// Profile dump may fail on some platforms
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=HermesProfiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["profileFetch","fn","outputPath","hermes","global","HermesInternal","result","path","Date","now","enableSamplingProfiler","profilePath","disableSamplingProfiler","dumpSamplingProfiler"],"sourceRoot":"../../src","sources":["HermesProfiler.ts"],"mappings":";;AAaA,OAAO,eAAeA,YAAYA,CAChCC,EAAoB,EACpBC,UAAmB,EACQ;EAC3B,MAAMC,MAAM,GAAGC,MAAM,CAACC,cAAc;EACpC,IAAI,CAACF,MAAM,EAAE;IACX,MAAMG,MAAM,GAAG,MAAML,EAAE,CAAC,CAAC;IACzB,OAAO;MAAEK;IAAO,CAAC;EACnB;EAEA,MAAMC,IAAI,GAAGL,UAAU,IAAI,2BAA2BM,IAAI,CAACC,GAAG,CAAC,CAAC,aAAa;EAC7EN,MAAM,CAACO,sBAAsB,CAAC,CAAC;EAC/B,IAAI;IACF,MAAMJ,MAAM,GAAG,MAAML,EAAE,CAAC,CAAC;IACzB,OAAO;MAAEK,MAAM;MAAEK,WAAW,EAAEJ;IAAK,CAAC;EACtC,CAAC,SAAS;IACRJ,MAAM,CAACS,uBAAuB,CAAC,CAAC;IAChC,IAAI;MACFT,MAAM,CAACU,oBAAoB,CAACN,IAAI,CAAC;IACnC,CAAC,CAAC,MAAM;MACN;IAAA;EAEJ;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { generateCurl } from "./CurlGenerator.js";
|
|
4
|
+
class NetworkInspectorImpl {
|
|
5
|
+
_enabled = false;
|
|
6
|
+
_entries = [];
|
|
7
|
+
_maxEntries = 500;
|
|
8
|
+
_maxBodyCapture = 4096;
|
|
9
|
+
_listeners = new Set();
|
|
10
|
+
enable(options) {
|
|
11
|
+
this._enabled = true;
|
|
12
|
+
if (options?.maxEntries != null) this._maxEntries = options.maxEntries;
|
|
13
|
+
if (options?.maxBodyCapture != null) this._maxBodyCapture = options.maxBodyCapture;
|
|
14
|
+
}
|
|
15
|
+
disable() {
|
|
16
|
+
this._enabled = false;
|
|
17
|
+
}
|
|
18
|
+
isEnabled() {
|
|
19
|
+
return this._enabled;
|
|
20
|
+
}
|
|
21
|
+
getEntries() {
|
|
22
|
+
return this._entries;
|
|
23
|
+
}
|
|
24
|
+
getHttpEntries() {
|
|
25
|
+
return this._entries.filter(e => e.type === 'http');
|
|
26
|
+
}
|
|
27
|
+
getWebSocketEntries() {
|
|
28
|
+
return this._entries.filter(e => e.type === 'websocket');
|
|
29
|
+
}
|
|
30
|
+
getEntry(id) {
|
|
31
|
+
return this._entries.find(e => e.id === id);
|
|
32
|
+
}
|
|
33
|
+
clear() {
|
|
34
|
+
this._entries = [];
|
|
35
|
+
}
|
|
36
|
+
onEntry(callback) {
|
|
37
|
+
this._listeners.add(callback);
|
|
38
|
+
return () => {
|
|
39
|
+
this._listeners.delete(callback);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
_notify(entry) {
|
|
43
|
+
for (const cb of this._listeners) {
|
|
44
|
+
try {
|
|
45
|
+
cb(entry);
|
|
46
|
+
} catch {
|
|
47
|
+
// swallow listener errors
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
_trimEntries() {
|
|
52
|
+
if (this._entries.length > this._maxEntries) {
|
|
53
|
+
this._entries.shift();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// --- HTTP recording ---
|
|
58
|
+
|
|
59
|
+
_recordStart(id, url, method, headers, body) {
|
|
60
|
+
if (!this._enabled) return;
|
|
61
|
+
const bodySize = body ? body.length : 0;
|
|
62
|
+
const entry = {
|
|
63
|
+
id,
|
|
64
|
+
type: 'http',
|
|
65
|
+
url,
|
|
66
|
+
method,
|
|
67
|
+
requestHeaders: headers.map(h => ({
|
|
68
|
+
key: h.key,
|
|
69
|
+
value: h.value
|
|
70
|
+
})),
|
|
71
|
+
requestBody: body ? body.slice(0, this._maxBodyCapture) : undefined,
|
|
72
|
+
requestBodySize: bodySize,
|
|
73
|
+
status: 0,
|
|
74
|
+
statusText: '',
|
|
75
|
+
responseHeaders: [],
|
|
76
|
+
responseBodySize: 0,
|
|
77
|
+
startTime: performance.now(),
|
|
78
|
+
endTime: 0,
|
|
79
|
+
duration: 0,
|
|
80
|
+
curl: generateCurl({
|
|
81
|
+
url,
|
|
82
|
+
method,
|
|
83
|
+
headers,
|
|
84
|
+
body
|
|
85
|
+
})
|
|
86
|
+
};
|
|
87
|
+
this._entries.push(entry);
|
|
88
|
+
this._trimEntries();
|
|
89
|
+
}
|
|
90
|
+
_recordEnd(id, status, statusText, headers, bodySize, error, responseBody) {
|
|
91
|
+
if (!this._enabled) return;
|
|
92
|
+
const entry = this._entries.find(e => e.id === id && e.type === 'http');
|
|
93
|
+
if (!entry) return;
|
|
94
|
+
entry.status = status;
|
|
95
|
+
entry.statusText = statusText;
|
|
96
|
+
entry.responseHeaders = headers.map(h => ({
|
|
97
|
+
key: h.key,
|
|
98
|
+
value: h.value
|
|
99
|
+
}));
|
|
100
|
+
entry.responseBodySize = bodySize;
|
|
101
|
+
entry.endTime = performance.now();
|
|
102
|
+
entry.duration = entry.endTime - entry.startTime;
|
|
103
|
+
if (error) entry.error = error;
|
|
104
|
+
if (responseBody != null) {
|
|
105
|
+
entry.responseBody = responseBody.slice(0, this._maxBodyCapture);
|
|
106
|
+
}
|
|
107
|
+
this._notify(entry);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// --- WebSocket recording ---
|
|
111
|
+
|
|
112
|
+
_recordWsOpen(id, url, protocols, headers) {
|
|
113
|
+
if (!this._enabled) return;
|
|
114
|
+
const entry = {
|
|
115
|
+
id,
|
|
116
|
+
type: 'websocket',
|
|
117
|
+
url,
|
|
118
|
+
protocols,
|
|
119
|
+
requestHeaders: headers.map(h => ({
|
|
120
|
+
key: h.key,
|
|
121
|
+
value: h.value
|
|
122
|
+
})),
|
|
123
|
+
startTime: performance.now(),
|
|
124
|
+
endTime: 0,
|
|
125
|
+
duration: 0,
|
|
126
|
+
readyState: 'CONNECTING',
|
|
127
|
+
messages: [],
|
|
128
|
+
messagesSent: 0,
|
|
129
|
+
messagesReceived: 0,
|
|
130
|
+
bytesSent: 0,
|
|
131
|
+
bytesReceived: 0
|
|
132
|
+
};
|
|
133
|
+
this._entries.push(entry);
|
|
134
|
+
this._trimEntries();
|
|
135
|
+
this._notify(entry);
|
|
136
|
+
}
|
|
137
|
+
_recordWsConnected(id) {
|
|
138
|
+
if (!this._enabled) return;
|
|
139
|
+
const entry = this._entries.find(e => e.id === id && e.type === 'websocket');
|
|
140
|
+
if (!entry) return;
|
|
141
|
+
entry.readyState = 'OPEN';
|
|
142
|
+
this._notify(entry);
|
|
143
|
+
}
|
|
144
|
+
_recordWsMessage(id, direction, data, size, isBinary) {
|
|
145
|
+
if (!this._enabled) return;
|
|
146
|
+
const entry = this._entries.find(e => e.id === id && e.type === 'websocket');
|
|
147
|
+
if (!entry) return;
|
|
148
|
+
entry.messages.push({
|
|
149
|
+
direction,
|
|
150
|
+
data: data.slice(0, this._maxBodyCapture),
|
|
151
|
+
size,
|
|
152
|
+
isBinary,
|
|
153
|
+
timestamp: performance.now()
|
|
154
|
+
});
|
|
155
|
+
if (direction === 'sent') {
|
|
156
|
+
entry.messagesSent++;
|
|
157
|
+
entry.bytesSent += size;
|
|
158
|
+
} else {
|
|
159
|
+
entry.messagesReceived++;
|
|
160
|
+
entry.bytesReceived += size;
|
|
161
|
+
}
|
|
162
|
+
this._notify(entry);
|
|
163
|
+
}
|
|
164
|
+
_recordWsClose(id, code, reason) {
|
|
165
|
+
if (!this._enabled) return;
|
|
166
|
+
const entry = this._entries.find(e => e.id === id && e.type === 'websocket');
|
|
167
|
+
if (!entry) return;
|
|
168
|
+
entry.readyState = 'CLOSED';
|
|
169
|
+
entry.closeCode = code;
|
|
170
|
+
entry.closeReason = reason;
|
|
171
|
+
entry.endTime = performance.now();
|
|
172
|
+
entry.duration = entry.endTime - entry.startTime;
|
|
173
|
+
this._notify(entry);
|
|
174
|
+
}
|
|
175
|
+
_recordWsError(id, error) {
|
|
176
|
+
if (!this._enabled) return;
|
|
177
|
+
const entry = this._entries.find(e => e.id === id && e.type === 'websocket');
|
|
178
|
+
if (!entry) return;
|
|
179
|
+
entry.error = error;
|
|
180
|
+
this._notify(entry);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
export const NetworkInspector = new NetworkInspectorImpl();
|
|
184
|
+
//# sourceMappingURL=NetworkInspector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["generateCurl","NetworkInspectorImpl","_enabled","_entries","_maxEntries","_maxBodyCapture","_listeners","Set","enable","options","maxEntries","maxBodyCapture","disable","isEnabled","getEntries","getHttpEntries","filter","e","type","getWebSocketEntries","getEntry","id","find","clear","onEntry","callback","add","delete","_notify","entry","cb","_trimEntries","length","shift","_recordStart","url","method","headers","body","bodySize","requestHeaders","map","h","key","value","requestBody","slice","undefined","requestBodySize","status","statusText","responseHeaders","responseBodySize","startTime","performance","now","endTime","duration","curl","push","_recordEnd","error","responseBody","_recordWsOpen","protocols","readyState","messages","messagesSent","messagesReceived","bytesSent","bytesReceived","_recordWsConnected","_recordWsMessage","direction","data","size","isBinary","timestamp","_recordWsClose","code","reason","closeCode","closeReason","_recordWsError","NetworkInspector"],"sourceRoot":"../../src","sources":["NetworkInspector.ts"],"mappings":"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","ignoreList":[]}
|