rezo 1.0.19 → 1.0.20
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/dist/adapters/curl.cjs +39 -34
- package/dist/adapters/curl.js +39 -34
- package/dist/adapters/entries/curl.d.ts +19 -17
- package/dist/adapters/entries/fetch.d.ts +19 -17
- package/dist/adapters/entries/http.d.ts +19 -17
- package/dist/adapters/entries/http2.d.ts +19 -17
- package/dist/adapters/entries/react-native.d.ts +19 -17
- package/dist/adapters/entries/xhr.d.ts +19 -17
- package/dist/adapters/fetch.cjs +42 -41
- package/dist/adapters/fetch.js +42 -41
- package/dist/adapters/http.cjs +65 -46
- package/dist/adapters/http.js +65 -46
- package/dist/adapters/http2.cjs +41 -36
- package/dist/adapters/http2.js +41 -36
- package/dist/adapters/index.cjs +6 -6
- package/dist/adapters/react-native.cjs +41 -27
- package/dist/adapters/react-native.js +41 -27
- package/dist/adapters/xhr.cjs +43 -38
- package/dist/adapters/xhr.js +43 -38
- package/dist/cache/index.cjs +13 -13
- package/dist/crawler.d.ts +19 -17
- package/dist/entries/crawler.cjs +5 -5
- package/dist/index.cjs +24 -24
- package/dist/index.d.ts +19 -17
- package/dist/platform/browser.d.ts +19 -17
- package/dist/platform/bun.d.ts +19 -17
- package/dist/platform/deno.d.ts +19 -17
- package/dist/platform/node.d.ts +19 -17
- package/dist/platform/react-native.d.ts +19 -17
- package/dist/platform/worker.d.ts +19 -17
- package/dist/plugin/index.cjs +36 -36
- package/dist/proxy/index.cjs +2 -2
- package/dist/queue/index.cjs +8 -8
- package/dist/utils/http-config.cjs +5 -3
- package/dist/utils/http-config.js +5 -3
- package/dist/utils/timing.cjs +90 -0
- package/dist/utils/timing.js +78 -0
- package/package.json +1 -1
package/dist/adapters/curl.cjs
CHANGED
|
@@ -34,6 +34,35 @@ function mergeRequestAndResponseCookies(requestCookies, responseCookies) {
|
|
|
34
34
|
}
|
|
35
35
|
return Array.from(cookieMap.values());
|
|
36
36
|
}
|
|
37
|
+
function buildTimingFromCurlStats(stats, startTime) {
|
|
38
|
+
const timeNamelookup = parseFloat(stats["time_namelookup"]) * 1000 || 0;
|
|
39
|
+
const timeConnect = parseFloat(stats["time_connect"]) * 1000 || 0;
|
|
40
|
+
const timeAppconnect = parseFloat(stats["time_appconnect"]) * 1000 || 0;
|
|
41
|
+
const timeStarttransfer = parseFloat(stats["time_starttransfer"]) * 1000 || 0;
|
|
42
|
+
const timeTotal = parseFloat(stats["time_total"]) * 1000 || 0;
|
|
43
|
+
return {
|
|
44
|
+
startTime,
|
|
45
|
+
domainLookupStart: startTime,
|
|
46
|
+
domainLookupEnd: startTime + timeNamelookup,
|
|
47
|
+
connectStart: startTime + timeNamelookup,
|
|
48
|
+
secureConnectionStart: timeAppconnect > timeConnect ? startTime + timeConnect : 0,
|
|
49
|
+
connectEnd: startTime + (timeAppconnect > 0 ? timeAppconnect : timeConnect),
|
|
50
|
+
requestStart: startTime + (timeAppconnect > 0 ? timeAppconnect : timeConnect),
|
|
51
|
+
responseStart: startTime + timeStarttransfer,
|
|
52
|
+
responseEnd: startTime + timeTotal
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function getTimingDurations(config) {
|
|
56
|
+
const t = config.timing;
|
|
57
|
+
return {
|
|
58
|
+
total: t.responseEnd - t.startTime,
|
|
59
|
+
dns: t.domainLookupEnd - t.domainLookupStart,
|
|
60
|
+
tcp: t.secureConnectionStart > 0 ? t.secureConnectionStart - t.connectStart : t.connectEnd - t.connectStart,
|
|
61
|
+
tls: t.secureConnectionStart > 0 ? t.connectEnd - t.secureConnectionStart : undefined,
|
|
62
|
+
firstByte: t.responseStart - t.startTime,
|
|
63
|
+
download: t.responseEnd - t.responseStart
|
|
64
|
+
};
|
|
65
|
+
}
|
|
37
66
|
|
|
38
67
|
class CurlCapabilities {
|
|
39
68
|
static instance;
|
|
@@ -1433,18 +1462,8 @@ class CurlResponseParser {
|
|
|
1433
1462
|
} else {
|
|
1434
1463
|
data = responseBody;
|
|
1435
1464
|
}
|
|
1436
|
-
const
|
|
1437
|
-
|
|
1438
|
-
startTimestamp: config.timing?.startTimestamp || Date.now(),
|
|
1439
|
-
endTimestamp: Date.now(),
|
|
1440
|
-
dnsMs: parseFloat(stats["time_namelookup"]) * 1000 || 0,
|
|
1441
|
-
tcpMs: (parseFloat(stats["time_connect"]) - parseFloat(stats["time_namelookup"])) * 1000 || 0,
|
|
1442
|
-
tlsMs: (parseFloat(stats["time_appconnect"]) - parseFloat(stats["time_connect"])) * 1000 || 0,
|
|
1443
|
-
ttfbMs: parseFloat(stats["time_starttransfer"]) * 1000 || 0,
|
|
1444
|
-
transferMs: (parseFloat(stats["time_total"]) - parseFloat(stats["time_starttransfer"])) * 1000 || 0,
|
|
1445
|
-
durationMs: totalMs
|
|
1446
|
-
};
|
|
1447
|
-
config.timing = timing;
|
|
1465
|
+
const startTime = config.timing?.startTime || performance.now();
|
|
1466
|
+
config.timing = buildTimingFromCurlStats(stats, startTime);
|
|
1448
1467
|
config.status = status;
|
|
1449
1468
|
config.statusText = statusText;
|
|
1450
1469
|
const isSecure = config.url?.startsWith("https") || false;
|
|
@@ -1682,14 +1701,7 @@ class CurlExecutor {
|
|
|
1682
1701
|
finalUrl: response.finalUrl,
|
|
1683
1702
|
cookies: response.cookies,
|
|
1684
1703
|
urls: response.urls,
|
|
1685
|
-
timing:
|
|
1686
|
-
total: performance.now() - startTime,
|
|
1687
|
-
firstByte: config.timing?.ttfbMs,
|
|
1688
|
-
dns: config.timing?.dnsMs,
|
|
1689
|
-
tcp: config.timing?.tcpMs,
|
|
1690
|
-
tls: config.timing?.tlsMs,
|
|
1691
|
-
download: config.timing?.transferMs
|
|
1692
|
-
},
|
|
1704
|
+
timing: getTimingDurations(config),
|
|
1693
1705
|
config
|
|
1694
1706
|
};
|
|
1695
1707
|
streamResult.emit("finish", finishEvent);
|
|
@@ -1712,14 +1724,10 @@ class CurlExecutor {
|
|
|
1712
1724
|
fileName,
|
|
1713
1725
|
fileSize,
|
|
1714
1726
|
timing: {
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
dns: config.timing?.dnsMs,
|
|
1718
|
-
tcp: config.timing?.tcpMs,
|
|
1719
|
-
tls: config.timing?.tlsMs,
|
|
1720
|
-
download: performance.now() - startTime
|
|
1727
|
+
...getTimingDurations(config),
|
|
1728
|
+
download: getTimingDurations(config).download || 0
|
|
1721
1729
|
},
|
|
1722
|
-
averageSpeed: fileSize / (
|
|
1730
|
+
averageSpeed: getTimingDurations(config).download ? fileSize / getTimingDurations(config).download * 1000 : 0,
|
|
1723
1731
|
config
|
|
1724
1732
|
};
|
|
1725
1733
|
downloadResult.emit("finish", finishEvent);
|
|
@@ -1742,14 +1750,11 @@ class CurlExecutor {
|
|
|
1742
1750
|
urls: response.urls,
|
|
1743
1751
|
uploadSize: config.transfer?.requestSize || 0,
|
|
1744
1752
|
timing: {
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
tls: config.timing?.tlsMs,
|
|
1749
|
-
upload: performance.now() - startTime,
|
|
1750
|
-
waiting: 0
|
|
1753
|
+
...getTimingDurations(config),
|
|
1754
|
+
upload: getTimingDurations(config).firstByte || 0,
|
|
1755
|
+
waiting: getTimingDurations(config).download > 0 && getTimingDurations(config).firstByte > 0 ? getTimingDurations(config).download - getTimingDurations(config).firstByte : 0
|
|
1751
1756
|
},
|
|
1752
|
-
averageUploadSpeed: (config.transfer?.requestSize
|
|
1757
|
+
averageUploadSpeed: getTimingDurations(config).firstByte && config.transfer?.requestSize ? config.transfer.requestSize / getTimingDurations(config).firstByte * 1000 : 0,
|
|
1753
1758
|
config
|
|
1754
1759
|
};
|
|
1755
1760
|
uploadResult.emit("finish", finishEvent);
|
package/dist/adapters/curl.js
CHANGED
|
@@ -34,6 +34,35 @@ function mergeRequestAndResponseCookies(requestCookies, responseCookies) {
|
|
|
34
34
|
}
|
|
35
35
|
return Array.from(cookieMap.values());
|
|
36
36
|
}
|
|
37
|
+
function buildTimingFromCurlStats(stats, startTime) {
|
|
38
|
+
const timeNamelookup = parseFloat(stats["time_namelookup"]) * 1000 || 0;
|
|
39
|
+
const timeConnect = parseFloat(stats["time_connect"]) * 1000 || 0;
|
|
40
|
+
const timeAppconnect = parseFloat(stats["time_appconnect"]) * 1000 || 0;
|
|
41
|
+
const timeStarttransfer = parseFloat(stats["time_starttransfer"]) * 1000 || 0;
|
|
42
|
+
const timeTotal = parseFloat(stats["time_total"]) * 1000 || 0;
|
|
43
|
+
return {
|
|
44
|
+
startTime,
|
|
45
|
+
domainLookupStart: startTime,
|
|
46
|
+
domainLookupEnd: startTime + timeNamelookup,
|
|
47
|
+
connectStart: startTime + timeNamelookup,
|
|
48
|
+
secureConnectionStart: timeAppconnect > timeConnect ? startTime + timeConnect : 0,
|
|
49
|
+
connectEnd: startTime + (timeAppconnect > 0 ? timeAppconnect : timeConnect),
|
|
50
|
+
requestStart: startTime + (timeAppconnect > 0 ? timeAppconnect : timeConnect),
|
|
51
|
+
responseStart: startTime + timeStarttransfer,
|
|
52
|
+
responseEnd: startTime + timeTotal
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function getTimingDurations(config) {
|
|
56
|
+
const t = config.timing;
|
|
57
|
+
return {
|
|
58
|
+
total: t.responseEnd - t.startTime,
|
|
59
|
+
dns: t.domainLookupEnd - t.domainLookupStart,
|
|
60
|
+
tcp: t.secureConnectionStart > 0 ? t.secureConnectionStart - t.connectStart : t.connectEnd - t.connectStart,
|
|
61
|
+
tls: t.secureConnectionStart > 0 ? t.connectEnd - t.secureConnectionStart : undefined,
|
|
62
|
+
firstByte: t.responseStart - t.startTime,
|
|
63
|
+
download: t.responseEnd - t.responseStart
|
|
64
|
+
};
|
|
65
|
+
}
|
|
37
66
|
|
|
38
67
|
class CurlCapabilities {
|
|
39
68
|
static instance;
|
|
@@ -1433,18 +1462,8 @@ class CurlResponseParser {
|
|
|
1433
1462
|
} else {
|
|
1434
1463
|
data = responseBody;
|
|
1435
1464
|
}
|
|
1436
|
-
const
|
|
1437
|
-
|
|
1438
|
-
startTimestamp: config.timing?.startTimestamp || Date.now(),
|
|
1439
|
-
endTimestamp: Date.now(),
|
|
1440
|
-
dnsMs: parseFloat(stats["time_namelookup"]) * 1000 || 0,
|
|
1441
|
-
tcpMs: (parseFloat(stats["time_connect"]) - parseFloat(stats["time_namelookup"])) * 1000 || 0,
|
|
1442
|
-
tlsMs: (parseFloat(stats["time_appconnect"]) - parseFloat(stats["time_connect"])) * 1000 || 0,
|
|
1443
|
-
ttfbMs: parseFloat(stats["time_starttransfer"]) * 1000 || 0,
|
|
1444
|
-
transferMs: (parseFloat(stats["time_total"]) - parseFloat(stats["time_starttransfer"])) * 1000 || 0,
|
|
1445
|
-
durationMs: totalMs
|
|
1446
|
-
};
|
|
1447
|
-
config.timing = timing;
|
|
1465
|
+
const startTime = config.timing?.startTime || performance.now();
|
|
1466
|
+
config.timing = buildTimingFromCurlStats(stats, startTime);
|
|
1448
1467
|
config.status = status;
|
|
1449
1468
|
config.statusText = statusText;
|
|
1450
1469
|
const isSecure = config.url?.startsWith("https") || false;
|
|
@@ -1682,14 +1701,7 @@ class CurlExecutor {
|
|
|
1682
1701
|
finalUrl: response.finalUrl,
|
|
1683
1702
|
cookies: response.cookies,
|
|
1684
1703
|
urls: response.urls,
|
|
1685
|
-
timing:
|
|
1686
|
-
total: performance.now() - startTime,
|
|
1687
|
-
firstByte: config.timing?.ttfbMs,
|
|
1688
|
-
dns: config.timing?.dnsMs,
|
|
1689
|
-
tcp: config.timing?.tcpMs,
|
|
1690
|
-
tls: config.timing?.tlsMs,
|
|
1691
|
-
download: config.timing?.transferMs
|
|
1692
|
-
},
|
|
1704
|
+
timing: getTimingDurations(config),
|
|
1693
1705
|
config
|
|
1694
1706
|
};
|
|
1695
1707
|
streamResult.emit("finish", finishEvent);
|
|
@@ -1712,14 +1724,10 @@ class CurlExecutor {
|
|
|
1712
1724
|
fileName,
|
|
1713
1725
|
fileSize,
|
|
1714
1726
|
timing: {
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
dns: config.timing?.dnsMs,
|
|
1718
|
-
tcp: config.timing?.tcpMs,
|
|
1719
|
-
tls: config.timing?.tlsMs,
|
|
1720
|
-
download: performance.now() - startTime
|
|
1727
|
+
...getTimingDurations(config),
|
|
1728
|
+
download: getTimingDurations(config).download || 0
|
|
1721
1729
|
},
|
|
1722
|
-
averageSpeed: fileSize / (
|
|
1730
|
+
averageSpeed: getTimingDurations(config).download ? fileSize / getTimingDurations(config).download * 1000 : 0,
|
|
1723
1731
|
config
|
|
1724
1732
|
};
|
|
1725
1733
|
downloadResult.emit("finish", finishEvent);
|
|
@@ -1742,14 +1750,11 @@ class CurlExecutor {
|
|
|
1742
1750
|
urls: response.urls,
|
|
1743
1751
|
uploadSize: config.transfer?.requestSize || 0,
|
|
1744
1752
|
timing: {
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
tls: config.timing?.tlsMs,
|
|
1749
|
-
upload: performance.now() - startTime,
|
|
1750
|
-
waiting: 0
|
|
1753
|
+
...getTimingDurations(config),
|
|
1754
|
+
upload: getTimingDurations(config).firstByte || 0,
|
|
1755
|
+
waiting: getTimingDurations(config).download > 0 && getTimingDurations(config).firstByte > 0 ? getTimingDurations(config).download - getTimingDurations(config).firstByte : 0
|
|
1751
1756
|
},
|
|
1752
|
-
averageUploadSpeed: (config.transfer?.requestSize
|
|
1757
|
+
averageUploadSpeed: getTimingDurations(config).firstByte && config.transfer?.requestSize ? config.transfer.requestSize / getTimingDurations(config).firstByte * 1000 : 0,
|
|
1753
1758
|
config
|
|
1754
1759
|
};
|
|
1755
1760
|
uploadResult.emit("finish", finishEvent);
|
|
@@ -1815,24 +1815,26 @@ export interface RezoConfig {
|
|
|
1815
1815
|
* - removeAllCookiesSync(): Clear all cookies
|
|
1816
1816
|
*/
|
|
1817
1817
|
cookieJar: RezoCookieJar;
|
|
1818
|
-
/** @description Comprehensive timing information */
|
|
1818
|
+
/** @description Comprehensive timing information (matches PerformanceResourceTiming API) */
|
|
1819
1819
|
timing: {
|
|
1820
|
-
/** @description Request start timestamp (
|
|
1821
|
-
|
|
1822
|
-
/** @description
|
|
1823
|
-
|
|
1824
|
-
/** @description DNS lookup
|
|
1825
|
-
|
|
1826
|
-
/** @description
|
|
1827
|
-
|
|
1828
|
-
/** @description TLS handshake
|
|
1829
|
-
|
|
1830
|
-
/** @description
|
|
1831
|
-
|
|
1832
|
-
/** @description
|
|
1833
|
-
|
|
1834
|
-
/** @description
|
|
1835
|
-
|
|
1820
|
+
/** @description Request start timestamp (performance.now() value when request began) */
|
|
1821
|
+
startTime: number;
|
|
1822
|
+
/** @description Timestamp when DNS lookup started */
|
|
1823
|
+
domainLookupStart: number;
|
|
1824
|
+
/** @description Timestamp when DNS lookup ended */
|
|
1825
|
+
domainLookupEnd: number;
|
|
1826
|
+
/** @description Timestamp when connection started */
|
|
1827
|
+
connectStart: number;
|
|
1828
|
+
/** @description Timestamp when TLS handshake started (0 for HTTP) */
|
|
1829
|
+
secureConnectionStart: number;
|
|
1830
|
+
/** @description Timestamp when connection completed */
|
|
1831
|
+
connectEnd: number;
|
|
1832
|
+
/** @description Timestamp when request was sent */
|
|
1833
|
+
requestStart: number;
|
|
1834
|
+
/** @description Timestamp when first byte of response received */
|
|
1835
|
+
responseStart: number;
|
|
1836
|
+
/** @description Timestamp when response completed */
|
|
1837
|
+
responseEnd: number;
|
|
1836
1838
|
};
|
|
1837
1839
|
/** @description Network connection information */
|
|
1838
1840
|
network: {
|
|
@@ -1815,24 +1815,26 @@ export interface RezoConfig {
|
|
|
1815
1815
|
* - removeAllCookiesSync(): Clear all cookies
|
|
1816
1816
|
*/
|
|
1817
1817
|
cookieJar: RezoCookieJar;
|
|
1818
|
-
/** @description Comprehensive timing information */
|
|
1818
|
+
/** @description Comprehensive timing information (matches PerformanceResourceTiming API) */
|
|
1819
1819
|
timing: {
|
|
1820
|
-
/** @description Request start timestamp (
|
|
1821
|
-
|
|
1822
|
-
/** @description
|
|
1823
|
-
|
|
1824
|
-
/** @description DNS lookup
|
|
1825
|
-
|
|
1826
|
-
/** @description
|
|
1827
|
-
|
|
1828
|
-
/** @description TLS handshake
|
|
1829
|
-
|
|
1830
|
-
/** @description
|
|
1831
|
-
|
|
1832
|
-
/** @description
|
|
1833
|
-
|
|
1834
|
-
/** @description
|
|
1835
|
-
|
|
1820
|
+
/** @description Request start timestamp (performance.now() value when request began) */
|
|
1821
|
+
startTime: number;
|
|
1822
|
+
/** @description Timestamp when DNS lookup started */
|
|
1823
|
+
domainLookupStart: number;
|
|
1824
|
+
/** @description Timestamp when DNS lookup ended */
|
|
1825
|
+
domainLookupEnd: number;
|
|
1826
|
+
/** @description Timestamp when connection started */
|
|
1827
|
+
connectStart: number;
|
|
1828
|
+
/** @description Timestamp when TLS handshake started (0 for HTTP) */
|
|
1829
|
+
secureConnectionStart: number;
|
|
1830
|
+
/** @description Timestamp when connection completed */
|
|
1831
|
+
connectEnd: number;
|
|
1832
|
+
/** @description Timestamp when request was sent */
|
|
1833
|
+
requestStart: number;
|
|
1834
|
+
/** @description Timestamp when first byte of response received */
|
|
1835
|
+
responseStart: number;
|
|
1836
|
+
/** @description Timestamp when response completed */
|
|
1837
|
+
responseEnd: number;
|
|
1836
1838
|
};
|
|
1837
1839
|
/** @description Network connection information */
|
|
1838
1840
|
network: {
|
|
@@ -1815,24 +1815,26 @@ export interface RezoConfig {
|
|
|
1815
1815
|
* - removeAllCookiesSync(): Clear all cookies
|
|
1816
1816
|
*/
|
|
1817
1817
|
cookieJar: RezoCookieJar;
|
|
1818
|
-
/** @description Comprehensive timing information */
|
|
1818
|
+
/** @description Comprehensive timing information (matches PerformanceResourceTiming API) */
|
|
1819
1819
|
timing: {
|
|
1820
|
-
/** @description Request start timestamp (
|
|
1821
|
-
|
|
1822
|
-
/** @description
|
|
1823
|
-
|
|
1824
|
-
/** @description DNS lookup
|
|
1825
|
-
|
|
1826
|
-
/** @description
|
|
1827
|
-
|
|
1828
|
-
/** @description TLS handshake
|
|
1829
|
-
|
|
1830
|
-
/** @description
|
|
1831
|
-
|
|
1832
|
-
/** @description
|
|
1833
|
-
|
|
1834
|
-
/** @description
|
|
1835
|
-
|
|
1820
|
+
/** @description Request start timestamp (performance.now() value when request began) */
|
|
1821
|
+
startTime: number;
|
|
1822
|
+
/** @description Timestamp when DNS lookup started */
|
|
1823
|
+
domainLookupStart: number;
|
|
1824
|
+
/** @description Timestamp when DNS lookup ended */
|
|
1825
|
+
domainLookupEnd: number;
|
|
1826
|
+
/** @description Timestamp when connection started */
|
|
1827
|
+
connectStart: number;
|
|
1828
|
+
/** @description Timestamp when TLS handshake started (0 for HTTP) */
|
|
1829
|
+
secureConnectionStart: number;
|
|
1830
|
+
/** @description Timestamp when connection completed */
|
|
1831
|
+
connectEnd: number;
|
|
1832
|
+
/** @description Timestamp when request was sent */
|
|
1833
|
+
requestStart: number;
|
|
1834
|
+
/** @description Timestamp when first byte of response received */
|
|
1835
|
+
responseStart: number;
|
|
1836
|
+
/** @description Timestamp when response completed */
|
|
1837
|
+
responseEnd: number;
|
|
1836
1838
|
};
|
|
1837
1839
|
/** @description Network connection information */
|
|
1838
1840
|
network: {
|
|
@@ -1815,24 +1815,26 @@ export interface RezoConfig {
|
|
|
1815
1815
|
* - removeAllCookiesSync(): Clear all cookies
|
|
1816
1816
|
*/
|
|
1817
1817
|
cookieJar: RezoCookieJar;
|
|
1818
|
-
/** @description Comprehensive timing information */
|
|
1818
|
+
/** @description Comprehensive timing information (matches PerformanceResourceTiming API) */
|
|
1819
1819
|
timing: {
|
|
1820
|
-
/** @description Request start timestamp (
|
|
1821
|
-
|
|
1822
|
-
/** @description
|
|
1823
|
-
|
|
1824
|
-
/** @description DNS lookup
|
|
1825
|
-
|
|
1826
|
-
/** @description
|
|
1827
|
-
|
|
1828
|
-
/** @description TLS handshake
|
|
1829
|
-
|
|
1830
|
-
/** @description
|
|
1831
|
-
|
|
1832
|
-
/** @description
|
|
1833
|
-
|
|
1834
|
-
/** @description
|
|
1835
|
-
|
|
1820
|
+
/** @description Request start timestamp (performance.now() value when request began) */
|
|
1821
|
+
startTime: number;
|
|
1822
|
+
/** @description Timestamp when DNS lookup started */
|
|
1823
|
+
domainLookupStart: number;
|
|
1824
|
+
/** @description Timestamp when DNS lookup ended */
|
|
1825
|
+
domainLookupEnd: number;
|
|
1826
|
+
/** @description Timestamp when connection started */
|
|
1827
|
+
connectStart: number;
|
|
1828
|
+
/** @description Timestamp when TLS handshake started (0 for HTTP) */
|
|
1829
|
+
secureConnectionStart: number;
|
|
1830
|
+
/** @description Timestamp when connection completed */
|
|
1831
|
+
connectEnd: number;
|
|
1832
|
+
/** @description Timestamp when request was sent */
|
|
1833
|
+
requestStart: number;
|
|
1834
|
+
/** @description Timestamp when first byte of response received */
|
|
1835
|
+
responseStart: number;
|
|
1836
|
+
/** @description Timestamp when response completed */
|
|
1837
|
+
responseEnd: number;
|
|
1836
1838
|
};
|
|
1837
1839
|
/** @description Network connection information */
|
|
1838
1840
|
network: {
|
|
@@ -1815,24 +1815,26 @@ export interface RezoConfig {
|
|
|
1815
1815
|
* - removeAllCookiesSync(): Clear all cookies
|
|
1816
1816
|
*/
|
|
1817
1817
|
cookieJar: RezoCookieJar;
|
|
1818
|
-
/** @description Comprehensive timing information */
|
|
1818
|
+
/** @description Comprehensive timing information (matches PerformanceResourceTiming API) */
|
|
1819
1819
|
timing: {
|
|
1820
|
-
/** @description Request start timestamp (
|
|
1821
|
-
|
|
1822
|
-
/** @description
|
|
1823
|
-
|
|
1824
|
-
/** @description DNS lookup
|
|
1825
|
-
|
|
1826
|
-
/** @description
|
|
1827
|
-
|
|
1828
|
-
/** @description TLS handshake
|
|
1829
|
-
|
|
1830
|
-
/** @description
|
|
1831
|
-
|
|
1832
|
-
/** @description
|
|
1833
|
-
|
|
1834
|
-
/** @description
|
|
1835
|
-
|
|
1820
|
+
/** @description Request start timestamp (performance.now() value when request began) */
|
|
1821
|
+
startTime: number;
|
|
1822
|
+
/** @description Timestamp when DNS lookup started */
|
|
1823
|
+
domainLookupStart: number;
|
|
1824
|
+
/** @description Timestamp when DNS lookup ended */
|
|
1825
|
+
domainLookupEnd: number;
|
|
1826
|
+
/** @description Timestamp when connection started */
|
|
1827
|
+
connectStart: number;
|
|
1828
|
+
/** @description Timestamp when TLS handshake started (0 for HTTP) */
|
|
1829
|
+
secureConnectionStart: number;
|
|
1830
|
+
/** @description Timestamp when connection completed */
|
|
1831
|
+
connectEnd: number;
|
|
1832
|
+
/** @description Timestamp when request was sent */
|
|
1833
|
+
requestStart: number;
|
|
1834
|
+
/** @description Timestamp when first byte of response received */
|
|
1835
|
+
responseStart: number;
|
|
1836
|
+
/** @description Timestamp when response completed */
|
|
1837
|
+
responseEnd: number;
|
|
1836
1838
|
};
|
|
1837
1839
|
/** @description Network connection information */
|
|
1838
1840
|
network: {
|
|
@@ -1815,24 +1815,26 @@ export interface RezoConfig {
|
|
|
1815
1815
|
* - removeAllCookiesSync(): Clear all cookies
|
|
1816
1816
|
*/
|
|
1817
1817
|
cookieJar: RezoCookieJar;
|
|
1818
|
-
/** @description Comprehensive timing information */
|
|
1818
|
+
/** @description Comprehensive timing information (matches PerformanceResourceTiming API) */
|
|
1819
1819
|
timing: {
|
|
1820
|
-
/** @description Request start timestamp (
|
|
1821
|
-
|
|
1822
|
-
/** @description
|
|
1823
|
-
|
|
1824
|
-
/** @description DNS lookup
|
|
1825
|
-
|
|
1826
|
-
/** @description
|
|
1827
|
-
|
|
1828
|
-
/** @description TLS handshake
|
|
1829
|
-
|
|
1830
|
-
/** @description
|
|
1831
|
-
|
|
1832
|
-
/** @description
|
|
1833
|
-
|
|
1834
|
-
/** @description
|
|
1835
|
-
|
|
1820
|
+
/** @description Request start timestamp (performance.now() value when request began) */
|
|
1821
|
+
startTime: number;
|
|
1822
|
+
/** @description Timestamp when DNS lookup started */
|
|
1823
|
+
domainLookupStart: number;
|
|
1824
|
+
/** @description Timestamp when DNS lookup ended */
|
|
1825
|
+
domainLookupEnd: number;
|
|
1826
|
+
/** @description Timestamp when connection started */
|
|
1827
|
+
connectStart: number;
|
|
1828
|
+
/** @description Timestamp when TLS handshake started (0 for HTTP) */
|
|
1829
|
+
secureConnectionStart: number;
|
|
1830
|
+
/** @description Timestamp when connection completed */
|
|
1831
|
+
connectEnd: number;
|
|
1832
|
+
/** @description Timestamp when request was sent */
|
|
1833
|
+
requestStart: number;
|
|
1834
|
+
/** @description Timestamp when first byte of response received */
|
|
1835
|
+
responseStart: number;
|
|
1836
|
+
/** @description Timestamp when response completed */
|
|
1837
|
+
responseEnd: number;
|
|
1836
1838
|
};
|
|
1837
1839
|
/** @description Network connection information */
|
|
1838
1840
|
network: {
|
package/dist/adapters/fetch.cjs
CHANGED
|
@@ -28,6 +28,30 @@ const Environment = {
|
|
|
28
28
|
return typeof AbortController !== "undefined";
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
|
+
function updateTiming(config, timing, bodySize) {
|
|
32
|
+
const now = performance.now();
|
|
33
|
+
config.timing.domainLookupStart = config.timing.startTime;
|
|
34
|
+
config.timing.domainLookupEnd = config.timing.startTime;
|
|
35
|
+
config.timing.connectStart = config.timing.startTime;
|
|
36
|
+
config.timing.secureConnectionStart = 0;
|
|
37
|
+
config.timing.connectEnd = config.timing.startTime;
|
|
38
|
+
config.timing.requestStart = config.timing.startTime;
|
|
39
|
+
config.timing.responseStart = timing.firstByteTime || config.timing.startTime;
|
|
40
|
+
config.timing.responseEnd = now;
|
|
41
|
+
config.transfer.bodySize = bodySize;
|
|
42
|
+
config.transfer.responseSize = bodySize;
|
|
43
|
+
}
|
|
44
|
+
function getTimingDurations(config) {
|
|
45
|
+
const t = config.timing;
|
|
46
|
+
return {
|
|
47
|
+
total: t.responseEnd - t.startTime,
|
|
48
|
+
dns: t.domainLookupEnd - t.domainLookupStart,
|
|
49
|
+
tcp: t.secureConnectionStart > 0 ? t.secureConnectionStart - t.connectStart : t.connectEnd - t.connectStart,
|
|
50
|
+
tls: t.secureConnectionStart > 0 ? t.connectEnd - t.secureConnectionStart : undefined,
|
|
51
|
+
firstByte: t.responseStart - t.startTime,
|
|
52
|
+
download: t.responseEnd - t.responseStart
|
|
53
|
+
};
|
|
54
|
+
}
|
|
31
55
|
const responseCacheInstances = new Map;
|
|
32
56
|
function getCacheConfigKey(option) {
|
|
33
57
|
if (option === true)
|
|
@@ -314,10 +338,11 @@ async function executeFetchRequest(fetchOptions, config, options, perform, strea
|
|
|
314
338
|
const maxRetries = config?.retry?.maxRetries || 0;
|
|
315
339
|
const incrementDelay = config?.retry?.incrementDelay || false;
|
|
316
340
|
const statusCodes = config?.retry?.statusCodes;
|
|
341
|
+
const startTime = performance.now();
|
|
317
342
|
const timing = {
|
|
318
|
-
startTime
|
|
319
|
-
startTimestamp: Date.now()
|
|
343
|
+
startTime
|
|
320
344
|
};
|
|
345
|
+
config.timing.startTime = startTime;
|
|
321
346
|
const ABSOLUTE_MAX_ATTEMPTS = 50;
|
|
322
347
|
const visitedUrls = new Set;
|
|
323
348
|
let totalAttempts = 0;
|
|
@@ -471,7 +496,6 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
|
|
|
471
496
|
config.finalUrl = url.href;
|
|
472
497
|
config.network.protocol = isSecure ? "https" : "http";
|
|
473
498
|
config.network.httpVersion = undefined;
|
|
474
|
-
config.timing.startTimestamp = timing.startTimestamp;
|
|
475
499
|
if (!config.transfer) {
|
|
476
500
|
config.transfer = { requestSize: 0, responseSize: 0, headerSize: 0, bodySize: 0 };
|
|
477
501
|
} else if (config.transfer.requestSize === undefined) {
|
|
@@ -550,9 +574,9 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
|
|
|
550
574
|
if (timeoutId)
|
|
551
575
|
clearTimeout(timeoutId);
|
|
552
576
|
}
|
|
553
|
-
if (!
|
|
577
|
+
if (!timing.firstByteTime) {
|
|
554
578
|
timing.firstByteTime = performance.now();
|
|
555
|
-
config.timing.
|
|
579
|
+
config.timing.responseStart = timing.firstByteTime;
|
|
556
580
|
}
|
|
557
581
|
const status = response.status;
|
|
558
582
|
const statusText = response.statusText;
|
|
@@ -589,8 +613,8 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
|
|
|
589
613
|
contentLength: contentLength ? parseInt(contentLength, 10) : undefined,
|
|
590
614
|
cookies: cookies.array,
|
|
591
615
|
timing: {
|
|
592
|
-
firstByte: config.timing.
|
|
593
|
-
total: performance.now() - timing.startTime
|
|
616
|
+
firstByte: config.timing.responseStart - config.timing.startTime,
|
|
617
|
+
total: performance.now() - config.timing.startTime
|
|
594
618
|
}
|
|
595
619
|
};
|
|
596
620
|
eventEmitter.emit("headers", headersEvent);
|
|
@@ -635,12 +659,8 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
|
|
|
635
659
|
responseData = await response.text();
|
|
636
660
|
}
|
|
637
661
|
}
|
|
638
|
-
config.timing.endTimestamp = Date.now();
|
|
639
|
-
config.timing.durationMs = performance.now() - timing.startTime;
|
|
640
|
-
config.timing.transferMs = timing.firstByteTime ? performance.now() - timing.firstByteTime : config.timing.durationMs;
|
|
641
662
|
const bodySize = bodyBuffer?.byteLength || (typeof responseData === "string" ? responseData.length : 0);
|
|
642
|
-
config
|
|
643
|
-
config.transfer.responseSize = bodySize;
|
|
663
|
+
updateTiming(config, timing, bodySize);
|
|
644
664
|
config.status = status;
|
|
645
665
|
config.statusText = statusText;
|
|
646
666
|
_stats.statusOnNext = status >= 400 ? "error" : "success";
|
|
@@ -674,14 +694,10 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
|
|
|
674
694
|
fileName: config.fileName,
|
|
675
695
|
fileSize: buffer.length,
|
|
676
696
|
timing: {
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
tcp: config.timing.tcpMs,
|
|
680
|
-
tls: config.timing.tlsMs,
|
|
681
|
-
firstByte: config.timing.ttfbMs,
|
|
682
|
-
download: config.timing.transferMs || 0
|
|
697
|
+
...getTimingDurations(config),
|
|
698
|
+
download: getTimingDurations(config).download || 0
|
|
683
699
|
},
|
|
684
|
-
averageSpeed: config.
|
|
700
|
+
averageSpeed: getTimingDurations(config).download ? buffer.length / getTimingDurations(config).download * 1000 : 0,
|
|
685
701
|
config: sanitizeConfig(config)
|
|
686
702
|
};
|
|
687
703
|
downloadResult.emit("finish", downloadFinishEvent);
|
|
@@ -720,16 +736,12 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
|
|
|
720
736
|
urls: buildUrlTree(config, url.href),
|
|
721
737
|
uploadSize: config.transfer.requestSize || 0,
|
|
722
738
|
timing: {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
tls: config.timing.tlsMs,
|
|
727
|
-
upload: config.timing.transferMs || 0,
|
|
728
|
-
waiting: config.timing.ttfbMs || 0,
|
|
729
|
-
download: config.timing.transferMs
|
|
739
|
+
...getTimingDurations(config),
|
|
740
|
+
upload: getTimingDurations(config).firstByte || 0,
|
|
741
|
+
waiting: getTimingDurations(config).download > 0 && getTimingDurations(config).firstByte > 0 ? getTimingDurations(config).download - getTimingDurations(config).firstByte : 0
|
|
730
742
|
},
|
|
731
|
-
averageUploadSpeed: config.
|
|
732
|
-
averageDownloadSpeed: config.
|
|
743
|
+
averageUploadSpeed: getTimingDurations(config).firstByte && config.transfer.requestSize ? config.transfer.requestSize / getTimingDurations(config).firstByte * 1000 : 0,
|
|
744
|
+
averageDownloadSpeed: getTimingDurations(config).download ? bodySize / getTimingDurations(config).download * 1000 : 0,
|
|
733
745
|
config: sanitizeConfig(config)
|
|
734
746
|
};
|
|
735
747
|
uploadResult.emit("finish", uploadFinishEvent);
|
|
@@ -777,11 +789,7 @@ async function handleStreamingResponse(response, config, timing, streamResult, u
|
|
|
777
789
|
streamResult.emit("download-progress", progressEvent);
|
|
778
790
|
}
|
|
779
791
|
}
|
|
780
|
-
config
|
|
781
|
-
config.timing.durationMs = performance.now() - timing.startTime;
|
|
782
|
-
config.timing.transferMs = timing.firstByteTime ? performance.now() - timing.firstByteTime : config.timing.durationMs;
|
|
783
|
-
config.transfer.bodySize = bytesReceived;
|
|
784
|
-
config.transfer.responseSize = bytesReceived;
|
|
792
|
+
updateTiming(config, timing, bytesReceived);
|
|
785
793
|
const streamFinishEvent = {
|
|
786
794
|
status,
|
|
787
795
|
statusText,
|
|
@@ -791,14 +799,7 @@ async function handleStreamingResponse(response, config, timing, streamResult, u
|
|
|
791
799
|
finalUrl: url.href,
|
|
792
800
|
cookies,
|
|
793
801
|
urls: buildUrlTree(config, url.href),
|
|
794
|
-
timing:
|
|
795
|
-
total: config.timing.durationMs || 0,
|
|
796
|
-
dns: config.timing.dnsMs,
|
|
797
|
-
tcp: config.timing.tcpMs,
|
|
798
|
-
tls: config.timing.tlsMs,
|
|
799
|
-
firstByte: config.timing.ttfbMs,
|
|
800
|
-
download: config.timing.transferMs
|
|
801
|
-
},
|
|
802
|
+
timing: getTimingDurations(config),
|
|
802
803
|
config: sanitizeConfig(config)
|
|
803
804
|
};
|
|
804
805
|
streamResult.emit("finish", streamFinishEvent);
|