rezo 1.0.30 → 1.0.31

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 (60) hide show
  1. package/dist/adapters/curl.cjs +8 -10
  2. package/dist/adapters/curl.js +8 -10
  3. package/dist/adapters/entries/curl.d.ts +169 -313
  4. package/dist/adapters/entries/fetch.d.ts +169 -313
  5. package/dist/adapters/entries/http.d.ts +169 -313
  6. package/dist/adapters/entries/http2.d.ts +169 -313
  7. package/dist/adapters/entries/react-native.d.ts +169 -313
  8. package/dist/adapters/entries/xhr.d.ts +169 -313
  9. package/dist/adapters/fetch.cjs +10 -7
  10. package/dist/adapters/fetch.js +10 -7
  11. package/dist/adapters/http.cjs +9 -12
  12. package/dist/adapters/http.js +9 -12
  13. package/dist/adapters/http2.cjs +6 -11
  14. package/dist/adapters/http2.js +6 -11
  15. package/dist/adapters/index.cjs +6 -6
  16. package/dist/adapters/react-native.cjs +4 -4
  17. package/dist/adapters/react-native.js +4 -4
  18. package/dist/adapters/xhr.cjs +4 -4
  19. package/dist/adapters/xhr.js +4 -4
  20. package/dist/cache/index.cjs +13 -13
  21. package/dist/cache/universal-response-cache.cjs +156 -0
  22. package/dist/cache/universal-response-cache.js +155 -0
  23. package/dist/core/rezo.cjs +2 -8
  24. package/dist/core/rezo.js +2 -8
  25. package/dist/crawler.d.ts +163 -313
  26. package/dist/entries/crawler.cjs +5 -5
  27. package/dist/index.cjs +24 -24
  28. package/dist/index.d.ts +169 -313
  29. package/dist/platform/browser.d.ts +169 -313
  30. package/dist/platform/bun.d.ts +169 -313
  31. package/dist/platform/deno.d.ts +169 -313
  32. package/dist/platform/node.d.ts +169 -313
  33. package/dist/platform/react-native.d.ts +169 -313
  34. package/dist/platform/worker.d.ts +169 -313
  35. package/dist/plugin/crawler.cjs +1 -1
  36. package/dist/plugin/crawler.js +1 -1
  37. package/dist/plugin/index.cjs +36 -36
  38. package/dist/proxy/index.cjs +4 -4
  39. package/dist/queue/index.cjs +8 -8
  40. package/dist/responses/buildResponse.cjs +15 -15
  41. package/dist/responses/buildResponse.js +15 -15
  42. package/dist/responses/universal/download.cjs +23 -0
  43. package/dist/responses/universal/download.js +22 -0
  44. package/dist/responses/universal/event-emitter.cjs +104 -0
  45. package/dist/responses/universal/event-emitter.js +102 -0
  46. package/dist/responses/universal/index.cjs +11 -0
  47. package/dist/responses/universal/index.js +4 -0
  48. package/dist/responses/universal/stream.cjs +32 -0
  49. package/dist/responses/universal/stream.js +31 -0
  50. package/dist/responses/universal/upload.cjs +23 -0
  51. package/dist/responses/universal/upload.js +22 -0
  52. package/dist/utils/cookies.browser.cjs +63 -0
  53. package/dist/utils/cookies.browser.js +61 -0
  54. package/dist/utils/form-data.cjs +212 -189
  55. package/dist/utils/form-data.js +212 -189
  56. package/dist/utils/http-config.cjs +28 -15
  57. package/dist/utils/http-config.js +28 -15
  58. package/package.json +11 -4
  59. package/dist/types/cookies.cjs +0 -394
  60. package/dist/types/cookies.js +0 -391
@@ -1067,19 +1067,16 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
1067
1067
  if (body instanceof URLSearchParams || body instanceof RezoURLSearchParams) {
1068
1068
  req.write(body.toString());
1069
1069
  } else if (body instanceof FormData || body instanceof RezoFormData) {
1070
- bodyPiped = true;
1071
- if (body instanceof RezoFormData) {
1072
- req.setHeader("Content-Type", `multipart/form-data; boundary=${body.getBoundary()}`);
1073
- body.pipe(req);
1074
- } else {
1075
- const form = await RezoFormData.fromNativeFormData(body);
1076
- req.setHeader("Content-Type", `multipart/form-data; boundary=${form.getBoundary()}`);
1077
- form.pipe(req);
1078
- }
1070
+ const form = body instanceof RezoFormData ? body : RezoFormData.fromNativeFormData(body);
1071
+ const buffer = await form.toBuffer();
1072
+ const contentType = await form.getContentTypeAsync();
1073
+ req.setHeader("Content-Type", contentType);
1074
+ req.setHeader("Content-Length", buffer.length);
1075
+ req.write(buffer);
1079
1076
  } else if (body instanceof Readable) {
1080
1077
  bodyPiped = true;
1081
1078
  body.pipe(req);
1082
- } else if (typeof body === "object" && !(body instanceof Buffer) && !(body instanceof Uint8Array)) {
1079
+ } else if (typeof body === "object" && !Buffer.isBuffer(body) && !(body instanceof Uint8Array)) {
1083
1080
  req.write(JSON.stringify(body));
1084
1081
  } else {
1085
1082
  req.write(body);
@@ -1346,9 +1343,9 @@ async function setInitialConfig(config, fetchOptions, isSecure, url, httpModule,
1346
1343
  } else if (Buffer.isBuffer(fetchOptions.body)) {
1347
1344
  requestBodySize = fetchOptions.body.length;
1348
1345
  } else if (fetchOptions.body instanceof RezoFormData) {
1349
- requestBodySize = fetchOptions.body.getLengthSync();
1346
+ requestBodySize = await fetchOptions.body.getLength();
1350
1347
  } else if (fetchOptions.body instanceof FormData) {
1351
- requestBodySize = (await RezoFormData.fromNativeFormData(fetchOptions.body)).getLengthSync();
1348
+ requestBodySize = await RezoFormData.fromNativeFormData(fetchOptions.body).getLength();
1352
1349
  }
1353
1350
  }
1354
1351
  const headers = fetchOptions.headers instanceof RezoHeaders ? fetchOptions.headers : new RezoHeaders(fetchOptions.headers);
@@ -1067,19 +1067,16 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
1067
1067
  if (body instanceof URLSearchParams || body instanceof RezoURLSearchParams) {
1068
1068
  req.write(body.toString());
1069
1069
  } else if (body instanceof FormData || body instanceof RezoFormData) {
1070
- bodyPiped = true;
1071
- if (body instanceof RezoFormData) {
1072
- req.setHeader("Content-Type", `multipart/form-data; boundary=${body.getBoundary()}`);
1073
- body.pipe(req);
1074
- } else {
1075
- const form = await RezoFormData.fromNativeFormData(body);
1076
- req.setHeader("Content-Type", `multipart/form-data; boundary=${form.getBoundary()}`);
1077
- form.pipe(req);
1078
- }
1070
+ const form = body instanceof RezoFormData ? body : RezoFormData.fromNativeFormData(body);
1071
+ const buffer = await form.toBuffer();
1072
+ const contentType = await form.getContentTypeAsync();
1073
+ req.setHeader("Content-Type", contentType);
1074
+ req.setHeader("Content-Length", buffer.length);
1075
+ req.write(buffer);
1079
1076
  } else if (body instanceof Readable) {
1080
1077
  bodyPiped = true;
1081
1078
  body.pipe(req);
1082
- } else if (typeof body === "object" && !(body instanceof Buffer) && !(body instanceof Uint8Array)) {
1079
+ } else if (typeof body === "object" && !Buffer.isBuffer(body) && !(body instanceof Uint8Array)) {
1083
1080
  req.write(JSON.stringify(body));
1084
1081
  } else {
1085
1082
  req.write(body);
@@ -1346,9 +1343,9 @@ async function setInitialConfig(config, fetchOptions, isSecure, url, httpModule,
1346
1343
  } else if (Buffer.isBuffer(fetchOptions.body)) {
1347
1344
  requestBodySize = fetchOptions.body.length;
1348
1345
  } else if (fetchOptions.body instanceof RezoFormData) {
1349
- requestBodySize = fetchOptions.body.getLengthSync();
1346
+ requestBodySize = await fetchOptions.body.getLength();
1350
1347
  } else if (fetchOptions.body instanceof FormData) {
1351
- requestBodySize = (await RezoFormData.fromNativeFormData(fetchOptions.body)).getLengthSync();
1348
+ requestBodySize = await RezoFormData.fromNativeFormData(fetchOptions.body).getLength();
1352
1349
  }
1353
1350
  }
1354
1351
  const headers = fetchOptions.headers instanceof RezoHeaders ? fetchOptions.headers : new RezoHeaders(fetchOptions.headers);
@@ -897,12 +897,12 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
897
897
  if (config.transfer.requestSize === 0 && body) {
898
898
  if (typeof body === "string") {
899
899
  config.transfer.requestSize = Buffer.byteLength(body, "utf8");
900
- } else if (body instanceof Buffer || body instanceof Uint8Array) {
900
+ } else if (Buffer.isBuffer(body) || body instanceof Uint8Array) {
901
901
  config.transfer.requestSize = body.length;
902
902
  } else if (body instanceof URLSearchParams || body instanceof RezoURLSearchParams) {
903
903
  config.transfer.requestSize = Buffer.byteLength(body.toString(), "utf8");
904
904
  } else if (body instanceof RezoFormData) {
905
- config.transfer.requestSize = body.getLengthSync();
905
+ config.transfer.requestSize = await body.getLength() || 0;
906
906
  } else if (typeof body === "object") {
907
907
  config.transfer.requestSize = Buffer.byteLength(JSON.stringify(body), "utf8");
908
908
  }
@@ -1093,15 +1093,10 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
1093
1093
  if (body instanceof URLSearchParams || body instanceof RezoURLSearchParams) {
1094
1094
  req.write(body.toString());
1095
1095
  } else if (body instanceof FormData || body instanceof RezoFormData) {
1096
- if (body instanceof RezoFormData) {
1097
- body.pipe(req);
1098
- return;
1099
- } else {
1100
- const form = fetchOptions._convertedFormData || await RezoFormData.fromNativeFormData(body);
1101
- form.pipe(req);
1102
- return;
1103
- }
1104
- } else if (typeof body === "object" && !(body instanceof Buffer) && !(body instanceof Uint8Array) && !(body instanceof Readable)) {
1096
+ const form = body instanceof RezoFormData ? body : RezoFormData.fromNativeFormData(body);
1097
+ const buffer = await form.toBuffer();
1098
+ req.write(buffer);
1099
+ } else if (typeof body === "object" && !Buffer.isBuffer(body) && !(body instanceof Uint8Array) && !(body instanceof Readable)) {
1105
1100
  req.write(JSON.stringify(body));
1106
1101
  } else if (body instanceof Readable) {
1107
1102
  body.pipe(req);
@@ -897,12 +897,12 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
897
897
  if (config.transfer.requestSize === 0 && body) {
898
898
  if (typeof body === "string") {
899
899
  config.transfer.requestSize = Buffer.byteLength(body, "utf8");
900
- } else if (body instanceof Buffer || body instanceof Uint8Array) {
900
+ } else if (Buffer.isBuffer(body) || body instanceof Uint8Array) {
901
901
  config.transfer.requestSize = body.length;
902
902
  } else if (body instanceof URLSearchParams || body instanceof RezoURLSearchParams) {
903
903
  config.transfer.requestSize = Buffer.byteLength(body.toString(), "utf8");
904
904
  } else if (body instanceof RezoFormData) {
905
- config.transfer.requestSize = body.getLengthSync();
905
+ config.transfer.requestSize = await body.getLength() || 0;
906
906
  } else if (typeof body === "object") {
907
907
  config.transfer.requestSize = Buffer.byteLength(JSON.stringify(body), "utf8");
908
908
  }
@@ -1093,15 +1093,10 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
1093
1093
  if (body instanceof URLSearchParams || body instanceof RezoURLSearchParams) {
1094
1094
  req.write(body.toString());
1095
1095
  } else if (body instanceof FormData || body instanceof RezoFormData) {
1096
- if (body instanceof RezoFormData) {
1097
- body.pipe(req);
1098
- return;
1099
- } else {
1100
- const form = fetchOptions._convertedFormData || await RezoFormData.fromNativeFormData(body);
1101
- form.pipe(req);
1102
- return;
1103
- }
1104
- } else if (typeof body === "object" && !(body instanceof Buffer) && !(body instanceof Uint8Array) && !(body instanceof Readable)) {
1096
+ const form = body instanceof RezoFormData ? body : RezoFormData.fromNativeFormData(body);
1097
+ const buffer = await form.toBuffer();
1098
+ req.write(buffer);
1099
+ } else if (typeof body === "object" && !Buffer.isBuffer(body) && !(body instanceof Uint8Array) && !(body instanceof Readable)) {
1105
1100
  req.write(JSON.stringify(body));
1106
1101
  } else if (body instanceof Readable) {
1107
1102
  body.pipe(req);
@@ -1,6 +1,6 @@
1
- const _mod_jvt2y3 = require('./picker.cjs');
2
- exports.detectRuntime = _mod_jvt2y3.detectRuntime;
3
- exports.getAdapterCapabilities = _mod_jvt2y3.getAdapterCapabilities;
4
- exports.buildAdapterContext = _mod_jvt2y3.buildAdapterContext;
5
- exports.getAvailableAdapters = _mod_jvt2y3.getAvailableAdapters;
6
- exports.selectAdapter = _mod_jvt2y3.selectAdapter;;
1
+ const _mod_smz6sm = require('./picker.cjs');
2
+ exports.detectRuntime = _mod_smz6sm.detectRuntime;
3
+ exports.getAdapterCapabilities = _mod_smz6sm.getAdapterCapabilities;
4
+ exports.buildAdapterContext = _mod_smz6sm.buildAdapterContext;
5
+ exports.getAvailableAdapters = _mod_smz6sm.getAvailableAdapters;
6
+ exports.selectAdapter = _mod_smz6sm.selectAdapter;;
@@ -5,11 +5,11 @@ const RezoFormData = require('../utils/form-data.cjs');
5
5
  const { getDefaultConfig, prepareHTTPOptions } = require('../utils/http-config.cjs');
6
6
  const { RezoHeaders } = require('../utils/headers.cjs');
7
7
  const { RezoURLSearchParams } = require('../utils/data-operations.cjs');
8
- const { StreamResponse } = require('../responses/stream.cjs');
9
- const { DownloadResponse } = require('../responses/download.cjs');
10
- const { UploadResponse } = require('../responses/upload.cjs');
8
+ const { StreamResponse } = require('../responses/universal/stream.cjs');
9
+ const { DownloadResponse } = require('../responses/universal/download.cjs');
10
+ const { UploadResponse } = require('../responses/universal/upload.cjs');
11
11
  const { RezoPerformance } = require('../utils/tools.cjs');
12
- const { ResponseCache } = require('../cache/response-cache.cjs');
12
+ const { ResponseCache } = require('../cache/universal-response-cache.cjs');
13
13
  const Environment = {
14
14
  isReactNative: typeof navigator !== "undefined" && navigator.product === "ReactNative",
15
15
  isExpo: typeof globalThis.expo !== "undefined",
@@ -5,11 +5,11 @@ import RezoFormData from '../utils/form-data.js';
5
5
  import { getDefaultConfig, prepareHTTPOptions } from '../utils/http-config.js';
6
6
  import { RezoHeaders } from '../utils/headers.js';
7
7
  import { RezoURLSearchParams } from '../utils/data-operations.js';
8
- import { StreamResponse } from '../responses/stream.js';
9
- import { DownloadResponse } from '../responses/download.js';
10
- import { UploadResponse } from '../responses/upload.js';
8
+ import { StreamResponse } from '../responses/universal/stream.js';
9
+ import { DownloadResponse } from '../responses/universal/download.js';
10
+ import { UploadResponse } from '../responses/universal/upload.js';
11
11
  import { RezoPerformance } from '../utils/tools.js';
12
- import { ResponseCache } from '../cache/response-cache.js';
12
+ import { ResponseCache } from '../cache/universal-response-cache.js';
13
13
  const Environment = {
14
14
  isReactNative: typeof navigator !== "undefined" && navigator.product === "ReactNative",
15
15
  isExpo: typeof globalThis.expo !== "undefined",
@@ -5,11 +5,11 @@ const RezoFormData = require('../utils/form-data.cjs');
5
5
  const { getDefaultConfig, prepareHTTPOptions } = require('../utils/http-config.cjs');
6
6
  const { RezoHeaders } = require('../utils/headers.cjs');
7
7
  const { RezoURLSearchParams } = require('../utils/data-operations.cjs');
8
- const { StreamResponse } = require('../responses/stream.cjs');
9
- const { DownloadResponse } = require('../responses/download.cjs');
10
- const { UploadResponse } = require('../responses/upload.cjs');
8
+ const { StreamResponse } = require('../responses/universal/stream.cjs');
9
+ const { DownloadResponse } = require('../responses/universal/download.cjs');
10
+ const { UploadResponse } = require('../responses/universal/upload.cjs');
11
11
  const { RezoPerformance } = require('../utils/tools.cjs');
12
- const { ResponseCache } = require('../cache/response-cache.cjs');
12
+ const { ResponseCache } = require('../cache/universal-response-cache.cjs');
13
13
  const Environment = {
14
14
  isBrowser: typeof window !== "undefined" && typeof document !== "undefined",
15
15
  hasXHR: typeof XMLHttpRequest !== "undefined",
@@ -5,11 +5,11 @@ import RezoFormData from '../utils/form-data.js';
5
5
  import { getDefaultConfig, prepareHTTPOptions } from '../utils/http-config.js';
6
6
  import { RezoHeaders } from '../utils/headers.js';
7
7
  import { RezoURLSearchParams } from '../utils/data-operations.js';
8
- import { StreamResponse } from '../responses/stream.js';
9
- import { DownloadResponse } from '../responses/download.js';
10
- import { UploadResponse } from '../responses/upload.js';
8
+ import { StreamResponse } from '../responses/universal/stream.js';
9
+ import { DownloadResponse } from '../responses/universal/download.js';
10
+ import { UploadResponse } from '../responses/universal/upload.js';
11
11
  import { RezoPerformance } from '../utils/tools.js';
12
- import { ResponseCache } from '../cache/response-cache.js';
12
+ import { ResponseCache } from '../cache/universal-response-cache.js';
13
13
  const Environment = {
14
14
  isBrowser: typeof window !== "undefined" && typeof document !== "undefined",
15
15
  hasXHR: typeof XMLHttpRequest !== "undefined",
@@ -1,13 +1,13 @@
1
- const _mod_rmp3wu = require('./lru-cache.cjs');
2
- exports.LRUCache = _mod_rmp3wu.LRUCache;;
3
- const _mod_r7c9g6 = require('./dns-cache.cjs');
4
- exports.DNSCache = _mod_r7c9g6.DNSCache;
5
- exports.getGlobalDNSCache = _mod_r7c9g6.getGlobalDNSCache;
6
- exports.resetGlobalDNSCache = _mod_r7c9g6.resetGlobalDNSCache;;
7
- const _mod_hc21ei = require('./response-cache.cjs');
8
- exports.ResponseCache = _mod_hc21ei.ResponseCache;
9
- exports.normalizeResponseCacheConfig = _mod_hc21ei.normalizeResponseCacheConfig;;
10
- const _mod_e129fq = require('./file-cacher.cjs');
11
- exports.FileCacher = _mod_e129fq.FileCacher;;
12
- const _mod_wyslbn = require('./url-store.cjs');
13
- exports.UrlStore = _mod_wyslbn.UrlStore;;
1
+ const _mod_yramme = require('./lru-cache.cjs');
2
+ exports.LRUCache = _mod_yramme.LRUCache;;
3
+ const _mod_e4j10p = require('./dns-cache.cjs');
4
+ exports.DNSCache = _mod_e4j10p.DNSCache;
5
+ exports.getGlobalDNSCache = _mod_e4j10p.getGlobalDNSCache;
6
+ exports.resetGlobalDNSCache = _mod_e4j10p.resetGlobalDNSCache;;
7
+ const _mod_l3bzsd = require('./response-cache.cjs');
8
+ exports.ResponseCache = _mod_l3bzsd.ResponseCache;
9
+ exports.normalizeResponseCacheConfig = _mod_l3bzsd.normalizeResponseCacheConfig;;
10
+ const _mod_519is0 = require('./file-cacher.cjs');
11
+ exports.FileCacher = _mod_519is0.FileCacher;;
12
+ const _mod_arz7ag = require('./url-store.cjs');
13
+ exports.UrlStore = _mod_arz7ag.UrlStore;;
@@ -0,0 +1,156 @@
1
+ const { LRUCache } = require('./lru-cache.cjs');
2
+ const DEFAULT_TTL = 3000000;
3
+ const DEFAULT_MAX_ENTRIES = 500;
4
+ const DEFAULT_METHODS = ["GET", "HEAD"];
5
+
6
+ class UniversalResponseCache {
7
+ memoryCache;
8
+ config;
9
+ constructor(options = true) {
10
+ const config = options === true ? {} : options === false ? { enable: false } : options;
11
+ this.config = {
12
+ enable: config.enable !== false,
13
+ networkCheck: config.networkCheck ?? false,
14
+ ttl: config.ttl ?? DEFAULT_TTL,
15
+ maxEntries: config.maxEntries ?? DEFAULT_MAX_ENTRIES,
16
+ methods: config.methods ?? DEFAULT_METHODS,
17
+ respectHeaders: config.respectHeaders ?? true
18
+ };
19
+ this.memoryCache = new LRUCache({
20
+ maxEntries: this.config.maxEntries,
21
+ ttl: this.config.ttl
22
+ });
23
+ }
24
+ generateCacheKey(method, url, headers) {
25
+ const varyHeader = headers?.["vary"];
26
+ let key = `${method}:${url}`;
27
+ if (varyHeader && headers) {
28
+ const varyFields = varyHeader.split(",").map((f) => f.trim().toLowerCase());
29
+ for (const field of varyFields) {
30
+ const value = headers[field] || "";
31
+ key += `:${field}=${value}`;
32
+ }
33
+ }
34
+ return key;
35
+ }
36
+ parseCacheControl(headers) {
37
+ const cacheControl = headers["cache-control"] || "";
38
+ const directives = cacheControl.toLowerCase().split(",").map((d) => d.trim());
39
+ let maxAge;
40
+ for (const directive of directives) {
41
+ if (directive.startsWith("max-age=")) {
42
+ maxAge = parseInt(directive.substring(8), 10);
43
+ }
44
+ }
45
+ return {
46
+ noStore: directives.includes("no-store"),
47
+ noCache: directives.includes("no-cache"),
48
+ mustRevalidate: directives.includes("must-revalidate"),
49
+ maxAge
50
+ };
51
+ }
52
+ get(method, url, requestHeaders) {
53
+ if (!this.config.enable)
54
+ return;
55
+ if (!this.config.methods.includes(method.toUpperCase()))
56
+ return;
57
+ const key = this.generateCacheKey(method, url, requestHeaders);
58
+ const cached = this.memoryCache.get(key);
59
+ if (!cached)
60
+ return;
61
+ const now = Date.now();
62
+ if (now - cached.timestamp > cached.ttl) {
63
+ this.memoryCache.delete(key);
64
+ return;
65
+ }
66
+ return cached;
67
+ }
68
+ set(method, url, response, requestHeaders) {
69
+ if (!this.config.enable)
70
+ return false;
71
+ if (!this.config.methods.includes(method.toUpperCase()))
72
+ return false;
73
+ const responseHeaders = {};
74
+ if (response.headers) {
75
+ if (typeof response.headers.forEach === "function") {
76
+ response.headers.forEach((value, key) => {
77
+ responseHeaders[key.toLowerCase()] = value;
78
+ });
79
+ } else if (typeof response.headers === "object") {
80
+ for (const [key, value] of Object.entries(response.headers)) {
81
+ if (typeof value === "string") {
82
+ responseHeaders[key.toLowerCase()] = value;
83
+ }
84
+ }
85
+ }
86
+ }
87
+ if (this.config.respectHeaders) {
88
+ const cacheControl = this.parseCacheControl(responseHeaders);
89
+ if (cacheControl.noStore)
90
+ return false;
91
+ }
92
+ let ttl = this.config.ttl;
93
+ if (this.config.respectHeaders) {
94
+ const cacheControl = this.parseCacheControl(responseHeaders);
95
+ if (cacheControl.maxAge !== undefined) {
96
+ ttl = cacheControl.maxAge * 1000;
97
+ }
98
+ }
99
+ const key = this.generateCacheKey(method, url, requestHeaders);
100
+ const cached = {
101
+ status: response.status,
102
+ statusText: response.statusText,
103
+ headers: responseHeaders,
104
+ data: response.data,
105
+ url,
106
+ timestamp: Date.now(),
107
+ ttl,
108
+ etag: responseHeaders["etag"],
109
+ lastModified: responseHeaders["last-modified"]
110
+ };
111
+ this.memoryCache.set(key, cached);
112
+ return true;
113
+ }
114
+ getConditionalHeaders(method, url, requestHeaders) {
115
+ const cached = this.get(method, url, requestHeaders);
116
+ if (!cached)
117
+ return null;
118
+ if (!cached.etag && !cached.lastModified)
119
+ return null;
120
+ return {
121
+ etag: cached.etag,
122
+ lastModified: cached.lastModified
123
+ };
124
+ }
125
+ updateRevalidated(method, url, responseHeaders, requestHeaders) {
126
+ const key = this.generateCacheKey(method, url, requestHeaders);
127
+ const cached = this.memoryCache.get(key);
128
+ if (!cached)
129
+ return null;
130
+ let newTtl = this.config.ttl;
131
+ if (this.config.respectHeaders) {
132
+ const cacheControl = this.parseCacheControl(responseHeaders);
133
+ if (cacheControl.maxAge !== undefined) {
134
+ newTtl = cacheControl.maxAge * 1000;
135
+ }
136
+ }
137
+ const updated = {
138
+ ...cached,
139
+ timestamp: Date.now(),
140
+ ttl: newTtl,
141
+ etag: responseHeaders["etag"] || cached.etag,
142
+ lastModified: responseHeaders["last-modified"] || cached.lastModified
143
+ };
144
+ this.memoryCache.set(key, updated);
145
+ return updated;
146
+ }
147
+ clear() {
148
+ this.memoryCache.clear();
149
+ }
150
+ size() {
151
+ return this.memoryCache.size;
152
+ }
153
+ }
154
+
155
+ exports.ResponseCache = UniversalResponseCache;
156
+ exports.UniversalResponseCache = UniversalResponseCache;
@@ -0,0 +1,155 @@
1
+ import { LRUCache } from './lru-cache.js';
2
+ const DEFAULT_TTL = 3000000;
3
+ const DEFAULT_MAX_ENTRIES = 500;
4
+ const DEFAULT_METHODS = ["GET", "HEAD"];
5
+
6
+ export class UniversalResponseCache {
7
+ memoryCache;
8
+ config;
9
+ constructor(options = true) {
10
+ const config = options === true ? {} : options === false ? { enable: false } : options;
11
+ this.config = {
12
+ enable: config.enable !== false,
13
+ networkCheck: config.networkCheck ?? false,
14
+ ttl: config.ttl ?? DEFAULT_TTL,
15
+ maxEntries: config.maxEntries ?? DEFAULT_MAX_ENTRIES,
16
+ methods: config.methods ?? DEFAULT_METHODS,
17
+ respectHeaders: config.respectHeaders ?? true
18
+ };
19
+ this.memoryCache = new LRUCache({
20
+ maxEntries: this.config.maxEntries,
21
+ ttl: this.config.ttl
22
+ });
23
+ }
24
+ generateCacheKey(method, url, headers) {
25
+ const varyHeader = headers?.["vary"];
26
+ let key = `${method}:${url}`;
27
+ if (varyHeader && headers) {
28
+ const varyFields = varyHeader.split(",").map((f) => f.trim().toLowerCase());
29
+ for (const field of varyFields) {
30
+ const value = headers[field] || "";
31
+ key += `:${field}=${value}`;
32
+ }
33
+ }
34
+ return key;
35
+ }
36
+ parseCacheControl(headers) {
37
+ const cacheControl = headers["cache-control"] || "";
38
+ const directives = cacheControl.toLowerCase().split(",").map((d) => d.trim());
39
+ let maxAge;
40
+ for (const directive of directives) {
41
+ if (directive.startsWith("max-age=")) {
42
+ maxAge = parseInt(directive.substring(8), 10);
43
+ }
44
+ }
45
+ return {
46
+ noStore: directives.includes("no-store"),
47
+ noCache: directives.includes("no-cache"),
48
+ mustRevalidate: directives.includes("must-revalidate"),
49
+ maxAge
50
+ };
51
+ }
52
+ get(method, url, requestHeaders) {
53
+ if (!this.config.enable)
54
+ return;
55
+ if (!this.config.methods.includes(method.toUpperCase()))
56
+ return;
57
+ const key = this.generateCacheKey(method, url, requestHeaders);
58
+ const cached = this.memoryCache.get(key);
59
+ if (!cached)
60
+ return;
61
+ const now = Date.now();
62
+ if (now - cached.timestamp > cached.ttl) {
63
+ this.memoryCache.delete(key);
64
+ return;
65
+ }
66
+ return cached;
67
+ }
68
+ set(method, url, response, requestHeaders) {
69
+ if (!this.config.enable)
70
+ return false;
71
+ if (!this.config.methods.includes(method.toUpperCase()))
72
+ return false;
73
+ const responseHeaders = {};
74
+ if (response.headers) {
75
+ if (typeof response.headers.forEach === "function") {
76
+ response.headers.forEach((value, key) => {
77
+ responseHeaders[key.toLowerCase()] = value;
78
+ });
79
+ } else if (typeof response.headers === "object") {
80
+ for (const [key, value] of Object.entries(response.headers)) {
81
+ if (typeof value === "string") {
82
+ responseHeaders[key.toLowerCase()] = value;
83
+ }
84
+ }
85
+ }
86
+ }
87
+ if (this.config.respectHeaders) {
88
+ const cacheControl = this.parseCacheControl(responseHeaders);
89
+ if (cacheControl.noStore)
90
+ return false;
91
+ }
92
+ let ttl = this.config.ttl;
93
+ if (this.config.respectHeaders) {
94
+ const cacheControl = this.parseCacheControl(responseHeaders);
95
+ if (cacheControl.maxAge !== undefined) {
96
+ ttl = cacheControl.maxAge * 1000;
97
+ }
98
+ }
99
+ const key = this.generateCacheKey(method, url, requestHeaders);
100
+ const cached = {
101
+ status: response.status,
102
+ statusText: response.statusText,
103
+ headers: responseHeaders,
104
+ data: response.data,
105
+ url,
106
+ timestamp: Date.now(),
107
+ ttl,
108
+ etag: responseHeaders["etag"],
109
+ lastModified: responseHeaders["last-modified"]
110
+ };
111
+ this.memoryCache.set(key, cached);
112
+ return true;
113
+ }
114
+ getConditionalHeaders(method, url, requestHeaders) {
115
+ const cached = this.get(method, url, requestHeaders);
116
+ if (!cached)
117
+ return null;
118
+ if (!cached.etag && !cached.lastModified)
119
+ return null;
120
+ return {
121
+ etag: cached.etag,
122
+ lastModified: cached.lastModified
123
+ };
124
+ }
125
+ updateRevalidated(method, url, responseHeaders, requestHeaders) {
126
+ const key = this.generateCacheKey(method, url, requestHeaders);
127
+ const cached = this.memoryCache.get(key);
128
+ if (!cached)
129
+ return null;
130
+ let newTtl = this.config.ttl;
131
+ if (this.config.respectHeaders) {
132
+ const cacheControl = this.parseCacheControl(responseHeaders);
133
+ if (cacheControl.maxAge !== undefined) {
134
+ newTtl = cacheControl.maxAge * 1000;
135
+ }
136
+ }
137
+ const updated = {
138
+ ...cached,
139
+ timestamp: Date.now(),
140
+ ttl: newTtl,
141
+ etag: responseHeaders["etag"] || cached.etag,
142
+ lastModified: responseHeaders["last-modified"] || cached.lastModified
143
+ };
144
+ this.memoryCache.set(key, updated);
145
+ return updated;
146
+ }
147
+ clear() {
148
+ this.memoryCache.clear();
149
+ }
150
+ size() {
151
+ return this.memoryCache.size;
152
+ }
153
+ }
154
+
155
+ export { UniversalResponseCache as ResponseCache };
@@ -491,17 +491,11 @@ const defaultTransforms = exports.defaultTransforms = {
491
491
  return data;
492
492
  }
493
493
  if (data instanceof RezoFormData) {
494
- if (headers instanceof RezoHeaders) {
495
- headers.setContentType(data.getContentType());
496
- }
497
- return data.toBuffer();
494
+ return data;
498
495
  }
499
496
  if (typeof data === "object" && data.constructor === Object) {
500
497
  const formData = RezoFormData.fromObject(data);
501
- if (headers instanceof RezoHeaders) {
502
- headers.setContentType(formData.getContentType());
503
- }
504
- return formData.toBuffer();
498
+ return formData;
505
499
  }
506
500
  return data;
507
501
  }
package/dist/core/rezo.js CHANGED
@@ -491,17 +491,11 @@ export const defaultTransforms = {
491
491
  return data;
492
492
  }
493
493
  if (data instanceof RezoFormData) {
494
- if (headers instanceof RezoHeaders) {
495
- headers.setContentType(data.getContentType());
496
- }
497
- return data.toBuffer();
494
+ return data;
498
495
  }
499
496
  if (typeof data === "object" && data.constructor === Object) {
500
497
  const formData = RezoFormData.fromObject(data);
501
- if (headers instanceof RezoHeaders) {
502
- headers.setContentType(formData.getContentType());
503
- }
504
- return formData.toBuffer();
498
+ return formData;
505
499
  }
506
500
  return data;
507
501
  }