rezo 1.0.11 → 1.0.13
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 +73 -10
- package/dist/adapters/curl.js +73 -10
- package/dist/adapters/entries/curl.d.ts +66 -1
- package/dist/adapters/entries/fetch.d.ts +66 -1
- package/dist/adapters/entries/http.d.ts +66 -1
- package/dist/adapters/entries/http2.d.ts +66 -1
- package/dist/adapters/entries/react-native.d.ts +66 -1
- package/dist/adapters/entries/xhr.d.ts +66 -1
- package/dist/adapters/fetch.cjs +106 -59
- package/dist/adapters/fetch.js +106 -59
- package/dist/adapters/http.cjs +28 -15
- package/dist/adapters/http.js +28 -15
- package/dist/adapters/http2.cjs +114 -55
- package/dist/adapters/http2.js +114 -55
- package/dist/adapters/index.cjs +6 -6
- package/dist/cache/index.cjs +13 -13
- package/dist/crawler.d.ts +66 -1
- package/dist/entries/crawler.cjs +5 -5
- package/dist/index.cjs +24 -24
- package/dist/index.d.ts +66 -1
- package/dist/platform/browser.d.ts +66 -1
- package/dist/platform/bun.d.ts +66 -1
- package/dist/platform/deno.d.ts +66 -1
- package/dist/platform/node.d.ts +66 -1
- package/dist/platform/react-native.d.ts +66 -1
- package/dist/platform/worker.d.ts +66 -1
- package/dist/plugin/index.cjs +36 -36
- package/dist/proxy/index.cjs +2 -2
- package/dist/queue/index.cjs +8 -8
- package/dist/responses/buildError.cjs +5 -1
- package/dist/responses/buildError.js +5 -1
- package/dist/responses/buildResponse.cjs +30 -3
- package/dist/responses/buildResponse.js +30 -3
- package/dist/utils/compression.cjs +6 -6
- package/dist/utils/compression.js +6 -6
- package/dist/utils/headers.cjs +17 -0
- package/dist/utils/headers.js +17 -1
- package/dist/utils/http-config.cjs +47 -5
- package/dist/utils/http-config.js +47 -5
- package/package.json +1 -1
package/dist/adapters/http2.js
CHANGED
|
@@ -4,14 +4,15 @@ import { URL } from "node:url";
|
|
|
4
4
|
import { Readable } from "node:stream";
|
|
5
5
|
import { RezoError } from '../errors/rezo-error.js';
|
|
6
6
|
import { buildSmartError, buildDecompressionError, builErrorFromResponse, buildDownloadError } from '../responses/buildError.js';
|
|
7
|
-
import {
|
|
7
|
+
import { RezoCookieJar } from '../utils/cookies.js';
|
|
8
8
|
import RezoFormData from '../utils/form-data.js';
|
|
9
9
|
import { getDefaultConfig, prepareHTTPOptions } from '../utils/http-config.js';
|
|
10
|
-
import { RezoHeaders } from '../utils/headers.js';
|
|
10
|
+
import { RezoHeaders, sanitizeHttp2Headers } from '../utils/headers.js';
|
|
11
11
|
import { RezoURLSearchParams } from '../utils/data-operations.js';
|
|
12
12
|
import { StreamResponse } from '../responses/stream.js';
|
|
13
13
|
import { DownloadResponse } from '../responses/download.js';
|
|
14
14
|
import { UploadResponse } from '../responses/upload.js';
|
|
15
|
+
import { CompressionUtil } from '../utils/compression.js';
|
|
15
16
|
import { isSameDomain, RezoPerformance } from '../utils/tools.js';
|
|
16
17
|
import { ResponseCache } from '../cache/response-cache.js';
|
|
17
18
|
let zstdDecompressSync = null;
|
|
@@ -142,6 +143,9 @@ class Http2SessionPool {
|
|
|
142
143
|
reject(new Error(`HTTP/2 connection timeout after ${timeout}ms`));
|
|
143
144
|
}
|
|
144
145
|
}, timeout) : null;
|
|
146
|
+
if (timeoutId && typeof timeoutId === "object" && "unref" in timeoutId) {
|
|
147
|
+
timeoutId.unref();
|
|
148
|
+
}
|
|
145
149
|
session.on("connect", () => {
|
|
146
150
|
if (!settled) {
|
|
147
151
|
settled = true;
|
|
@@ -166,6 +170,12 @@ class Http2SessionPool {
|
|
|
166
170
|
if (entry) {
|
|
167
171
|
entry.refCount = Math.max(0, entry.refCount - 1);
|
|
168
172
|
entry.lastUsed = Date.now();
|
|
173
|
+
if (entry.refCount === 0) {
|
|
174
|
+
const socket = entry.session.socket;
|
|
175
|
+
if (socket && typeof socket.unref === "function") {
|
|
176
|
+
socket.unref();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
169
179
|
}
|
|
170
180
|
}
|
|
171
181
|
closeSession(url) {
|
|
@@ -271,38 +281,66 @@ function updateCookies(config, headers, url) {
|
|
|
271
281
|
if (!setCookieHeaders)
|
|
272
282
|
return;
|
|
273
283
|
const cookieHeaderArray = Array.isArray(setCookieHeaders) ? setCookieHeaders : [setCookieHeaders];
|
|
274
|
-
if (
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
setCookiesString: []
|
|
281
|
-
};
|
|
284
|
+
if (cookieHeaderArray.length === 0)
|
|
285
|
+
return;
|
|
286
|
+
const jar = new RezoCookieJar;
|
|
287
|
+
jar.setCookiesSync(cookieHeaderArray, url);
|
|
288
|
+
if (config.enableCookieJar && config.cookieJar) {
|
|
289
|
+
config.cookieJar.setCookiesSync(cookieHeaderArray, url);
|
|
282
290
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
const
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
path: "/",
|
|
295
|
-
httpOnly: cookieStr.toLowerCase().includes("httponly"),
|
|
296
|
-
secure: cookieStr.toLowerCase().includes("secure"),
|
|
297
|
-
sameSite: "lax"
|
|
298
|
-
});
|
|
299
|
-
config.responseCookies.array.push(cookie);
|
|
291
|
+
const cookies = jar.cookies();
|
|
292
|
+
cookies.setCookiesString = cookieHeaderArray;
|
|
293
|
+
if (config.useCookies) {
|
|
294
|
+
const existingArray = config.responseCookies?.array || [];
|
|
295
|
+
for (const cookie of cookies.array) {
|
|
296
|
+
const existingIndex = existingArray.findIndex((c) => c.key === cookie.key && c.domain === cookie.domain);
|
|
297
|
+
if (existingIndex >= 0) {
|
|
298
|
+
existingArray[existingIndex] = cookie;
|
|
299
|
+
} else {
|
|
300
|
+
existingArray.push(cookie);
|
|
301
|
+
}
|
|
300
302
|
}
|
|
303
|
+
const mergedJar = new RezoCookieJar(existingArray, url);
|
|
304
|
+
config.responseCookies = mergedJar.cookies();
|
|
305
|
+
config.responseCookies.setCookiesString = cookieHeaderArray;
|
|
306
|
+
} else {
|
|
307
|
+
config.responseCookies = cookies;
|
|
301
308
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
309
|
+
}
|
|
310
|
+
function mergeRequestAndResponseCookies(config, responseCookies, url) {
|
|
311
|
+
const mergedCookiesArray = [];
|
|
312
|
+
const cookieKeyDomainMap = new Map;
|
|
313
|
+
if (config.requestCookies && config.requestCookies.length > 0) {
|
|
314
|
+
for (const cookie of config.requestCookies) {
|
|
315
|
+
const key = `${cookie.key}|${cookie.domain || ""}`;
|
|
316
|
+
mergedCookiesArray.push(cookie);
|
|
317
|
+
cookieKeyDomainMap.set(key, mergedCookiesArray.length - 1);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
for (const cookie of responseCookies.array) {
|
|
321
|
+
const key = `${cookie.key}|${cookie.domain || ""}`;
|
|
322
|
+
const existingIndex = cookieKeyDomainMap.get(key);
|
|
323
|
+
if (existingIndex !== undefined) {
|
|
324
|
+
mergedCookiesArray[existingIndex] = cookie;
|
|
325
|
+
} else {
|
|
326
|
+
mergedCookiesArray.push(cookie);
|
|
327
|
+
cookieKeyDomainMap.set(key, mergedCookiesArray.length - 1);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
if (mergedCookiesArray.length > 0) {
|
|
331
|
+
const mergedJar = new RezoCookieJar(mergedCookiesArray, url);
|
|
332
|
+
return mergedJar.cookies();
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
array: [],
|
|
336
|
+
serialized: [],
|
|
337
|
+
netscape: `# Netscape HTTP Cookie File
|
|
338
|
+
# This file was generated by Rezo HTTP client
|
|
339
|
+
# Based on uniqhtt cookie implementation
|
|
340
|
+
`,
|
|
341
|
+
string: "",
|
|
342
|
+
setCookiesString: []
|
|
343
|
+
};
|
|
306
344
|
}
|
|
307
345
|
export async function executeRequest(options, defaultOptions, jar) {
|
|
308
346
|
if (!options.responseType) {
|
|
@@ -480,6 +518,8 @@ async function executeHttp2Request(fetchOptions, config, options, perform, fs, s
|
|
|
480
518
|
if (fileName && fs && fs.existsSync(fileName)) {
|
|
481
519
|
fs.unlinkSync(fileName);
|
|
482
520
|
}
|
|
521
|
+
if (!config.errors)
|
|
522
|
+
config.errors = [];
|
|
483
523
|
config.errors.push({
|
|
484
524
|
attempt: config.retryAttempts + 1,
|
|
485
525
|
error: response,
|
|
@@ -517,7 +557,7 @@ async function executeHttp2Request(fetchOptions, config, options, perform, fs, s
|
|
|
517
557
|
}
|
|
518
558
|
continue;
|
|
519
559
|
}
|
|
520
|
-
if (statusOnNext === "success") {
|
|
560
|
+
if (statusOnNext === "success" || statusOnNext === "error") {
|
|
521
561
|
return response;
|
|
522
562
|
}
|
|
523
563
|
if (statusOnNext === "redirect") {
|
|
@@ -616,6 +656,13 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
616
656
|
if (!headers["accept-encoding"]) {
|
|
617
657
|
headers["accept-encoding"] = "gzip, deflate, br";
|
|
618
658
|
}
|
|
659
|
+
if (body instanceof RezoFormData) {
|
|
660
|
+
headers["content-type"] = `multipart/form-data; boundary=${body.getBoundary()}`;
|
|
661
|
+
} else if (body instanceof FormData) {
|
|
662
|
+
const tempForm = await RezoFormData.fromNativeFormData(body);
|
|
663
|
+
headers["content-type"] = `multipart/form-data; boundary=${tempForm.getBoundary()}`;
|
|
664
|
+
fetchOptions._convertedFormData = tempForm;
|
|
665
|
+
}
|
|
619
666
|
const eventEmitter = streamResult || downloadResult || uploadResult;
|
|
620
667
|
if (eventEmitter && requestCount === 0) {
|
|
621
668
|
const startEvent = {
|
|
@@ -731,6 +778,25 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
731
778
|
config.timing.endTimestamp = Date.now();
|
|
732
779
|
config.timing.durationMs = performance.now() - timing.startTime;
|
|
733
780
|
config.timing.transferMs = timing.firstByteTime ? performance.now() - timing.firstByteTime : config.timing.durationMs;
|
|
781
|
+
if (!config.transfer) {
|
|
782
|
+
config.transfer = { requestSize: 0, responseSize: 0, headerSize: 0, bodySize: 0 };
|
|
783
|
+
}
|
|
784
|
+
if (config.transfer.requestSize === undefined) {
|
|
785
|
+
config.transfer.requestSize = 0;
|
|
786
|
+
}
|
|
787
|
+
if (config.transfer.requestSize === 0 && body) {
|
|
788
|
+
if (typeof body === "string") {
|
|
789
|
+
config.transfer.requestSize = Buffer.byteLength(body, "utf8");
|
|
790
|
+
} else if (body instanceof Buffer || body instanceof Uint8Array) {
|
|
791
|
+
config.transfer.requestSize = body.length;
|
|
792
|
+
} else if (body instanceof URLSearchParams || body instanceof RezoURLSearchParams) {
|
|
793
|
+
config.transfer.requestSize = Buffer.byteLength(body.toString(), "utf8");
|
|
794
|
+
} else if (body instanceof RezoFormData) {
|
|
795
|
+
config.transfer.requestSize = body.getLengthSync();
|
|
796
|
+
} else if (typeof body === "object") {
|
|
797
|
+
config.transfer.requestSize = Buffer.byteLength(JSON.stringify(body), "utf8");
|
|
798
|
+
}
|
|
799
|
+
}
|
|
734
800
|
config.transfer.bodySize = contentLengthCounter;
|
|
735
801
|
config.transfer.responseSize = contentLengthCounter;
|
|
736
802
|
(sessionPool || Http2SessionPool.getInstance()).releaseSession(url);
|
|
@@ -739,7 +805,7 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
739
805
|
data: "",
|
|
740
806
|
status,
|
|
741
807
|
statusText,
|
|
742
|
-
headers: new RezoHeaders(responseHeaders),
|
|
808
|
+
headers: new RezoHeaders(sanitizeHttp2Headers(responseHeaders)),
|
|
743
809
|
cookies: config.responseCookies || { array: [], serialized: [], netscape: "", string: "", setCookiesString: [] },
|
|
744
810
|
config,
|
|
745
811
|
contentType: responseHeaders["content-type"],
|
|
@@ -752,14 +818,14 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
752
818
|
}
|
|
753
819
|
let responseBody = Buffer.concat(chunks);
|
|
754
820
|
const contentEncoding = responseHeaders["content-encoding"];
|
|
755
|
-
if (contentEncoding && contentLengthCounter > 0) {
|
|
821
|
+
if (contentEncoding && contentLengthCounter > 0 && CompressionUtil.shouldDecompress(contentEncoding, config)) {
|
|
756
822
|
try {
|
|
757
823
|
const decompressed = await decompressBuffer(responseBody, contentEncoding);
|
|
758
824
|
responseBody = decompressed;
|
|
759
825
|
} catch (err) {
|
|
760
826
|
const error = buildDecompressionError({
|
|
761
827
|
statusCode: status,
|
|
762
|
-
headers: responseHeaders,
|
|
828
|
+
headers: sanitizeHttp2Headers(responseHeaders),
|
|
763
829
|
contentType: responseHeaders["content-type"],
|
|
764
830
|
contentLength: String(contentLengthCounter),
|
|
765
831
|
cookies: config.responseCookies?.setCookiesString || [],
|
|
@@ -799,24 +865,17 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
799
865
|
data = responseBody.toString("utf-8");
|
|
800
866
|
}
|
|
801
867
|
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
data
|
|
808
|
-
}, config, fetchOptions);
|
|
809
|
-
_stats.statusOnNext = "error";
|
|
810
|
-
resolve(error);
|
|
811
|
-
return;
|
|
812
|
-
}
|
|
813
|
-
_stats.statusOnNext = "success";
|
|
868
|
+
config.status = status;
|
|
869
|
+
config.statusText = statusText;
|
|
870
|
+
_stats.statusOnNext = status >= 400 ? "error" : "success";
|
|
871
|
+
const responseCookies = config.responseCookies || { array: [], serialized: [], netscape: "", string: "", setCookiesString: [] };
|
|
872
|
+
const mergedCookies = mergeRequestAndResponseCookies(config, responseCookies, url.href);
|
|
814
873
|
const finalResponse = {
|
|
815
874
|
data,
|
|
816
875
|
status,
|
|
817
876
|
statusText,
|
|
818
|
-
headers: new RezoHeaders(responseHeaders),
|
|
819
|
-
cookies:
|
|
877
|
+
headers: new RezoHeaders(sanitizeHttp2Headers(responseHeaders)),
|
|
878
|
+
cookies: mergedCookies,
|
|
820
879
|
config,
|
|
821
880
|
contentType,
|
|
822
881
|
contentLength: contentLengthCounter,
|
|
@@ -829,11 +888,11 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
829
888
|
const downloadFinishEvent = {
|
|
830
889
|
status,
|
|
831
890
|
statusText,
|
|
832
|
-
headers: new RezoHeaders(responseHeaders),
|
|
891
|
+
headers: new RezoHeaders(sanitizeHttp2Headers(responseHeaders)),
|
|
833
892
|
contentType,
|
|
834
893
|
contentLength: responseBody.length,
|
|
835
894
|
finalUrl: url.href,
|
|
836
|
-
cookies:
|
|
895
|
+
cookies: mergedCookies,
|
|
837
896
|
urls: buildUrlTree(config, url.href),
|
|
838
897
|
fileName: config.fileName,
|
|
839
898
|
fileSize: responseBody.length,
|
|
@@ -854,7 +913,7 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
854
913
|
} catch (err) {
|
|
855
914
|
const error = buildDownloadError({
|
|
856
915
|
statusCode: status,
|
|
857
|
-
headers: responseHeaders,
|
|
916
|
+
headers: sanitizeHttp2Headers(responseHeaders),
|
|
858
917
|
contentType,
|
|
859
918
|
contentLength: String(contentLengthCounter),
|
|
860
919
|
cookies: config.responseCookies?.setCookiesString || [],
|
|
@@ -874,7 +933,7 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
874
933
|
const streamFinishEvent = {
|
|
875
934
|
status,
|
|
876
935
|
statusText,
|
|
877
|
-
headers: new RezoHeaders(responseHeaders),
|
|
936
|
+
headers: new RezoHeaders(sanitizeHttp2Headers(responseHeaders)),
|
|
878
937
|
contentType,
|
|
879
938
|
contentLength: contentLengthCounter,
|
|
880
939
|
finalUrl: url.href,
|
|
@@ -900,7 +959,7 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
900
959
|
response: {
|
|
901
960
|
status,
|
|
902
961
|
statusText,
|
|
903
|
-
headers: new RezoHeaders(responseHeaders),
|
|
962
|
+
headers: new RezoHeaders(sanitizeHttp2Headers(responseHeaders)),
|
|
904
963
|
data,
|
|
905
964
|
contentType,
|
|
906
965
|
contentLength: contentLengthCounter
|
|
@@ -945,7 +1004,7 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
945
1004
|
body.pipe(req);
|
|
946
1005
|
return;
|
|
947
1006
|
} else {
|
|
948
|
-
const form = await RezoFormData.fromNativeFormData(body);
|
|
1007
|
+
const form = fetchOptions._convertedFormData || await RezoFormData.fromNativeFormData(body);
|
|
949
1008
|
form.pipe(req);
|
|
950
1009
|
return;
|
|
951
1010
|
}
|
package/dist/adapters/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const
|
|
2
|
-
exports.detectRuntime =
|
|
3
|
-
exports.getAdapterCapabilities =
|
|
4
|
-
exports.buildAdapterContext =
|
|
5
|
-
exports.getAvailableAdapters =
|
|
6
|
-
exports.selectAdapter =
|
|
1
|
+
const _mod_h6yyuw = require('./picker.cjs');
|
|
2
|
+
exports.detectRuntime = _mod_h6yyuw.detectRuntime;
|
|
3
|
+
exports.getAdapterCapabilities = _mod_h6yyuw.getAdapterCapabilities;
|
|
4
|
+
exports.buildAdapterContext = _mod_h6yyuw.buildAdapterContext;
|
|
5
|
+
exports.getAvailableAdapters = _mod_h6yyuw.getAvailableAdapters;
|
|
6
|
+
exports.selectAdapter = _mod_h6yyuw.selectAdapter;;
|
package/dist/cache/index.cjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
const
|
|
2
|
-
exports.LRUCache =
|
|
3
|
-
const
|
|
4
|
-
exports.DNSCache =
|
|
5
|
-
exports.getGlobalDNSCache =
|
|
6
|
-
exports.resetGlobalDNSCache =
|
|
7
|
-
const
|
|
8
|
-
exports.ResponseCache =
|
|
9
|
-
exports.normalizeResponseCacheConfig =
|
|
10
|
-
const
|
|
11
|
-
exports.FileCacher =
|
|
12
|
-
const
|
|
13
|
-
exports.UrlStore =
|
|
1
|
+
const _mod_vgyhxh = require('./lru-cache.cjs');
|
|
2
|
+
exports.LRUCache = _mod_vgyhxh.LRUCache;;
|
|
3
|
+
const _mod_57d30y = require('./dns-cache.cjs');
|
|
4
|
+
exports.DNSCache = _mod_57d30y.DNSCache;
|
|
5
|
+
exports.getGlobalDNSCache = _mod_57d30y.getGlobalDNSCache;
|
|
6
|
+
exports.resetGlobalDNSCache = _mod_57d30y.resetGlobalDNSCache;;
|
|
7
|
+
const _mod_qx55fg = require('./response-cache.cjs');
|
|
8
|
+
exports.ResponseCache = _mod_qx55fg.ResponseCache;
|
|
9
|
+
exports.normalizeResponseCacheConfig = _mod_qx55fg.normalizeResponseCacheConfig;;
|
|
10
|
+
const _mod_clz0cm = require('./file-cacher.cjs');
|
|
11
|
+
exports.FileCacher = _mod_clz0cm.FileCacher;;
|
|
12
|
+
const _mod_39vswi = require('./url-store.cjs');
|
|
13
|
+
exports.UrlStore = _mod_39vswi.UrlStore;;
|
package/dist/crawler.d.ts
CHANGED
|
@@ -2620,8 +2620,73 @@ export interface RezoRequestConfig<D = any> {
|
|
|
2620
2620
|
maxRedirects?: number;
|
|
2621
2621
|
/** Whether to automatically decompress response data */
|
|
2622
2622
|
decompress?: boolean;
|
|
2623
|
-
/**
|
|
2623
|
+
/**
|
|
2624
|
+
* Whether to keep TCP connections alive for reuse across multiple requests.
|
|
2625
|
+
*
|
|
2626
|
+
* When enabled, the underlying TCP connection is kept open after a request completes,
|
|
2627
|
+
* allowing subsequent requests to the same host to reuse the connection. This reduces
|
|
2628
|
+
* latency by avoiding the overhead of establishing new connections (TCP handshake,
|
|
2629
|
+
* TLS negotiation for HTTPS).
|
|
2630
|
+
*
|
|
2631
|
+
* **Behavior:**
|
|
2632
|
+
* - `false` (default) - Connection closes after each request. Process exits immediately.
|
|
2633
|
+
* - `true` - Connection stays open for reuse. Idle connections close after `keepAliveMsecs`.
|
|
2634
|
+
*
|
|
2635
|
+
* **When to use `keepAlive: true`:**
|
|
2636
|
+
* - Making multiple requests to the same host in sequence
|
|
2637
|
+
* - Long-running applications (servers, bots, scrapers)
|
|
2638
|
+
* - Performance-critical applications where connection overhead matters
|
|
2639
|
+
*
|
|
2640
|
+
* **When to use `keepAlive: false` (default):**
|
|
2641
|
+
* - Single requests or scripts that should exit immediately
|
|
2642
|
+
* - CLI tools that make one-off requests
|
|
2643
|
+
* - When you need predictable process termination
|
|
2644
|
+
*
|
|
2645
|
+
* @example
|
|
2646
|
+
* ```typescript
|
|
2647
|
+
* // Default: process exits immediately after request
|
|
2648
|
+
* const { data } = await rezo.get('https://api.example.com/data');
|
|
2649
|
+
*
|
|
2650
|
+
* // Keep connection alive for 1 minute (default) for subsequent requests
|
|
2651
|
+
* const client = new Rezo({ keepAlive: true });
|
|
2652
|
+
* await client.get('https://api.example.com/users');
|
|
2653
|
+
* await client.get('https://api.example.com/posts'); // Reuses connection
|
|
2654
|
+
*
|
|
2655
|
+
* // Custom keep-alive timeout (30 seconds)
|
|
2656
|
+
* const client = new Rezo({ keepAlive: true, keepAliveMsecs: 30000 });
|
|
2657
|
+
* ```
|
|
2658
|
+
*
|
|
2659
|
+
* @default false
|
|
2660
|
+
*/
|
|
2624
2661
|
keepAlive?: boolean;
|
|
2662
|
+
/**
|
|
2663
|
+
* How long to keep idle connections alive in milliseconds.
|
|
2664
|
+
*
|
|
2665
|
+
* Only applies when `keepAlive: true`. After this duration of inactivity,
|
|
2666
|
+
* the connection is closed automatically. This prevents resource leaks
|
|
2667
|
+
* from connections that are no longer needed.
|
|
2668
|
+
*
|
|
2669
|
+
* **Note:** Even with keep-alive enabled, the Node.js process can still exit
|
|
2670
|
+
* cleanly when there's no other work to do, thanks to socket unreferencing.
|
|
2671
|
+
*
|
|
2672
|
+
* @example
|
|
2673
|
+
* ```typescript
|
|
2674
|
+
* // Keep connections alive for 30 seconds
|
|
2675
|
+
* const client = new Rezo({
|
|
2676
|
+
* keepAlive: true,
|
|
2677
|
+
* keepAliveMsecs: 30000
|
|
2678
|
+
* });
|
|
2679
|
+
*
|
|
2680
|
+
* // Keep connections alive for 2 minutes
|
|
2681
|
+
* const client = new Rezo({
|
|
2682
|
+
* keepAlive: true,
|
|
2683
|
+
* keepAliveMsecs: 120000
|
|
2684
|
+
* });
|
|
2685
|
+
* ```
|
|
2686
|
+
*
|
|
2687
|
+
* @default 60000 (1 minute)
|
|
2688
|
+
*/
|
|
2689
|
+
keepAliveMsecs?: number;
|
|
2625
2690
|
withoutBodyOnRedirect?: boolean;
|
|
2626
2691
|
autoSetReferer?: boolean;
|
|
2627
2692
|
autoSetOrigin?: boolean;
|
package/dist/entries/crawler.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const
|
|
2
|
-
exports.Crawler =
|
|
3
|
-
const
|
|
4
|
-
exports.CrawlerOptions =
|
|
5
|
-
exports.Domain =
|
|
1
|
+
const _mod_m9euun = require('../plugin/crawler.cjs');
|
|
2
|
+
exports.Crawler = _mod_m9euun.Crawler;;
|
|
3
|
+
const _mod_358g2f = require('../plugin/crawler-options.cjs');
|
|
4
|
+
exports.CrawlerOptions = _mod_358g2f.CrawlerOptions;
|
|
5
|
+
exports.Domain = _mod_358g2f.Domain;;
|
package/dist/index.cjs
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
const
|
|
2
|
-
exports.Rezo =
|
|
3
|
-
exports.createRezoInstance =
|
|
4
|
-
exports.createDefaultInstance =
|
|
5
|
-
const
|
|
6
|
-
exports.RezoError =
|
|
7
|
-
exports.RezoErrorCode =
|
|
8
|
-
const
|
|
9
|
-
exports.RezoHeaders =
|
|
10
|
-
const
|
|
11
|
-
exports.RezoFormData =
|
|
12
|
-
const
|
|
13
|
-
exports.RezoCookieJar =
|
|
14
|
-
exports.Cookie =
|
|
15
|
-
const
|
|
16
|
-
exports.createDefaultHooks =
|
|
17
|
-
exports.mergeHooks =
|
|
18
|
-
const
|
|
19
|
-
exports.ProxyManager =
|
|
20
|
-
const
|
|
21
|
-
exports.RezoQueue =
|
|
22
|
-
exports.HttpQueue =
|
|
23
|
-
exports.Priority =
|
|
24
|
-
exports.HttpMethodPriority =
|
|
1
|
+
const _mod_txkkmz = require('./core/rezo.cjs');
|
|
2
|
+
exports.Rezo = _mod_txkkmz.Rezo;
|
|
3
|
+
exports.createRezoInstance = _mod_txkkmz.createRezoInstance;
|
|
4
|
+
exports.createDefaultInstance = _mod_txkkmz.createDefaultInstance;;
|
|
5
|
+
const _mod_a3vsp1 = require('./errors/rezo-error.cjs');
|
|
6
|
+
exports.RezoError = _mod_a3vsp1.RezoError;
|
|
7
|
+
exports.RezoErrorCode = _mod_a3vsp1.RezoErrorCode;;
|
|
8
|
+
const _mod_2ef980 = require('./utils/headers.cjs');
|
|
9
|
+
exports.RezoHeaders = _mod_2ef980.RezoHeaders;;
|
|
10
|
+
const _mod_e56bdp = require('./utils/form-data.cjs');
|
|
11
|
+
exports.RezoFormData = _mod_e56bdp.RezoFormData;;
|
|
12
|
+
const _mod_ss7zpn = require('./utils/cookies.cjs');
|
|
13
|
+
exports.RezoCookieJar = _mod_ss7zpn.RezoCookieJar;
|
|
14
|
+
exports.Cookie = _mod_ss7zpn.Cookie;;
|
|
15
|
+
const _mod_vdi6fa = require('./core/hooks.cjs');
|
|
16
|
+
exports.createDefaultHooks = _mod_vdi6fa.createDefaultHooks;
|
|
17
|
+
exports.mergeHooks = _mod_vdi6fa.mergeHooks;;
|
|
18
|
+
const _mod_049k4s = require('./proxy/manager.cjs');
|
|
19
|
+
exports.ProxyManager = _mod_049k4s.ProxyManager;;
|
|
20
|
+
const _mod_5l0v67 = require('./queue/index.cjs');
|
|
21
|
+
exports.RezoQueue = _mod_5l0v67.RezoQueue;
|
|
22
|
+
exports.HttpQueue = _mod_5l0v67.HttpQueue;
|
|
23
|
+
exports.Priority = _mod_5l0v67.Priority;
|
|
24
|
+
exports.HttpMethodPriority = _mod_5l0v67.HttpMethodPriority;;
|
|
25
25
|
const { RezoError } = require('./errors/rezo-error.cjs');
|
|
26
26
|
const isRezoError = exports.isRezoError = RezoError.isRezoError;
|
|
27
27
|
const Cancel = exports.Cancel = RezoError;
|
package/dist/index.d.ts
CHANGED
|
@@ -2628,8 +2628,73 @@ export interface RezoRequestConfig<D = any> {
|
|
|
2628
2628
|
maxRedirects?: number;
|
|
2629
2629
|
/** Whether to automatically decompress response data */
|
|
2630
2630
|
decompress?: boolean;
|
|
2631
|
-
/**
|
|
2631
|
+
/**
|
|
2632
|
+
* Whether to keep TCP connections alive for reuse across multiple requests.
|
|
2633
|
+
*
|
|
2634
|
+
* When enabled, the underlying TCP connection is kept open after a request completes,
|
|
2635
|
+
* allowing subsequent requests to the same host to reuse the connection. This reduces
|
|
2636
|
+
* latency by avoiding the overhead of establishing new connections (TCP handshake,
|
|
2637
|
+
* TLS negotiation for HTTPS).
|
|
2638
|
+
*
|
|
2639
|
+
* **Behavior:**
|
|
2640
|
+
* - `false` (default) - Connection closes after each request. Process exits immediately.
|
|
2641
|
+
* - `true` - Connection stays open for reuse. Idle connections close after `keepAliveMsecs`.
|
|
2642
|
+
*
|
|
2643
|
+
* **When to use `keepAlive: true`:**
|
|
2644
|
+
* - Making multiple requests to the same host in sequence
|
|
2645
|
+
* - Long-running applications (servers, bots, scrapers)
|
|
2646
|
+
* - Performance-critical applications where connection overhead matters
|
|
2647
|
+
*
|
|
2648
|
+
* **When to use `keepAlive: false` (default):**
|
|
2649
|
+
* - Single requests or scripts that should exit immediately
|
|
2650
|
+
* - CLI tools that make one-off requests
|
|
2651
|
+
* - When you need predictable process termination
|
|
2652
|
+
*
|
|
2653
|
+
* @example
|
|
2654
|
+
* ```typescript
|
|
2655
|
+
* // Default: process exits immediately after request
|
|
2656
|
+
* const { data } = await rezo.get('https://api.example.com/data');
|
|
2657
|
+
*
|
|
2658
|
+
* // Keep connection alive for 1 minute (default) for subsequent requests
|
|
2659
|
+
* const client = new Rezo({ keepAlive: true });
|
|
2660
|
+
* await client.get('https://api.example.com/users');
|
|
2661
|
+
* await client.get('https://api.example.com/posts'); // Reuses connection
|
|
2662
|
+
*
|
|
2663
|
+
* // Custom keep-alive timeout (30 seconds)
|
|
2664
|
+
* const client = new Rezo({ keepAlive: true, keepAliveMsecs: 30000 });
|
|
2665
|
+
* ```
|
|
2666
|
+
*
|
|
2667
|
+
* @default false
|
|
2668
|
+
*/
|
|
2632
2669
|
keepAlive?: boolean;
|
|
2670
|
+
/**
|
|
2671
|
+
* How long to keep idle connections alive in milliseconds.
|
|
2672
|
+
*
|
|
2673
|
+
* Only applies when `keepAlive: true`. After this duration of inactivity,
|
|
2674
|
+
* the connection is closed automatically. This prevents resource leaks
|
|
2675
|
+
* from connections that are no longer needed.
|
|
2676
|
+
*
|
|
2677
|
+
* **Note:** Even with keep-alive enabled, the Node.js process can still exit
|
|
2678
|
+
* cleanly when there's no other work to do, thanks to socket unreferencing.
|
|
2679
|
+
*
|
|
2680
|
+
* @example
|
|
2681
|
+
* ```typescript
|
|
2682
|
+
* // Keep connections alive for 30 seconds
|
|
2683
|
+
* const client = new Rezo({
|
|
2684
|
+
* keepAlive: true,
|
|
2685
|
+
* keepAliveMsecs: 30000
|
|
2686
|
+
* });
|
|
2687
|
+
*
|
|
2688
|
+
* // Keep connections alive for 2 minutes
|
|
2689
|
+
* const client = new Rezo({
|
|
2690
|
+
* keepAlive: true,
|
|
2691
|
+
* keepAliveMsecs: 120000
|
|
2692
|
+
* });
|
|
2693
|
+
* ```
|
|
2694
|
+
*
|
|
2695
|
+
* @default 60000 (1 minute)
|
|
2696
|
+
*/
|
|
2697
|
+
keepAliveMsecs?: number;
|
|
2633
2698
|
withoutBodyOnRedirect?: boolean;
|
|
2634
2699
|
autoSetReferer?: boolean;
|
|
2635
2700
|
autoSetOrigin?: boolean;
|
|
@@ -2502,8 +2502,73 @@ export interface RezoRequestConfig<D = any> {
|
|
|
2502
2502
|
maxRedirects?: number;
|
|
2503
2503
|
/** Whether to automatically decompress response data */
|
|
2504
2504
|
decompress?: boolean;
|
|
2505
|
-
/**
|
|
2505
|
+
/**
|
|
2506
|
+
* Whether to keep TCP connections alive for reuse across multiple requests.
|
|
2507
|
+
*
|
|
2508
|
+
* When enabled, the underlying TCP connection is kept open after a request completes,
|
|
2509
|
+
* allowing subsequent requests to the same host to reuse the connection. This reduces
|
|
2510
|
+
* latency by avoiding the overhead of establishing new connections (TCP handshake,
|
|
2511
|
+
* TLS negotiation for HTTPS).
|
|
2512
|
+
*
|
|
2513
|
+
* **Behavior:**
|
|
2514
|
+
* - `false` (default) - Connection closes after each request. Process exits immediately.
|
|
2515
|
+
* - `true` - Connection stays open for reuse. Idle connections close after `keepAliveMsecs`.
|
|
2516
|
+
*
|
|
2517
|
+
* **When to use `keepAlive: true`:**
|
|
2518
|
+
* - Making multiple requests to the same host in sequence
|
|
2519
|
+
* - Long-running applications (servers, bots, scrapers)
|
|
2520
|
+
* - Performance-critical applications where connection overhead matters
|
|
2521
|
+
*
|
|
2522
|
+
* **When to use `keepAlive: false` (default):**
|
|
2523
|
+
* - Single requests or scripts that should exit immediately
|
|
2524
|
+
* - CLI tools that make one-off requests
|
|
2525
|
+
* - When you need predictable process termination
|
|
2526
|
+
*
|
|
2527
|
+
* @example
|
|
2528
|
+
* ```typescript
|
|
2529
|
+
* // Default: process exits immediately after request
|
|
2530
|
+
* const { data } = await rezo.get('https://api.example.com/data');
|
|
2531
|
+
*
|
|
2532
|
+
* // Keep connection alive for 1 minute (default) for subsequent requests
|
|
2533
|
+
* const client = new Rezo({ keepAlive: true });
|
|
2534
|
+
* await client.get('https://api.example.com/users');
|
|
2535
|
+
* await client.get('https://api.example.com/posts'); // Reuses connection
|
|
2536
|
+
*
|
|
2537
|
+
* // Custom keep-alive timeout (30 seconds)
|
|
2538
|
+
* const client = new Rezo({ keepAlive: true, keepAliveMsecs: 30000 });
|
|
2539
|
+
* ```
|
|
2540
|
+
*
|
|
2541
|
+
* @default false
|
|
2542
|
+
*/
|
|
2506
2543
|
keepAlive?: boolean;
|
|
2544
|
+
/**
|
|
2545
|
+
* How long to keep idle connections alive in milliseconds.
|
|
2546
|
+
*
|
|
2547
|
+
* Only applies when `keepAlive: true`. After this duration of inactivity,
|
|
2548
|
+
* the connection is closed automatically. This prevents resource leaks
|
|
2549
|
+
* from connections that are no longer needed.
|
|
2550
|
+
*
|
|
2551
|
+
* **Note:** Even with keep-alive enabled, the Node.js process can still exit
|
|
2552
|
+
* cleanly when there's no other work to do, thanks to socket unreferencing.
|
|
2553
|
+
*
|
|
2554
|
+
* @example
|
|
2555
|
+
* ```typescript
|
|
2556
|
+
* // Keep connections alive for 30 seconds
|
|
2557
|
+
* const client = new Rezo({
|
|
2558
|
+
* keepAlive: true,
|
|
2559
|
+
* keepAliveMsecs: 30000
|
|
2560
|
+
* });
|
|
2561
|
+
*
|
|
2562
|
+
* // Keep connections alive for 2 minutes
|
|
2563
|
+
* const client = new Rezo({
|
|
2564
|
+
* keepAlive: true,
|
|
2565
|
+
* keepAliveMsecs: 120000
|
|
2566
|
+
* });
|
|
2567
|
+
* ```
|
|
2568
|
+
*
|
|
2569
|
+
* @default 60000 (1 minute)
|
|
2570
|
+
*/
|
|
2571
|
+
keepAliveMsecs?: number;
|
|
2507
2572
|
withoutBodyOnRedirect?: boolean;
|
|
2508
2573
|
autoSetReferer?: boolean;
|
|
2509
2574
|
autoSetOrigin?: boolean;
|