rezo 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +1507 -0
  3. package/assets/icon.svg +37 -0
  4. package/assets/logo-dark.svg +47 -0
  5. package/assets/logo.svg +58 -0
  6. package/dist/adapters/curl.cjs +1034 -0
  7. package/dist/adapters/curl.js +1031 -0
  8. package/dist/adapters/entries/curl.cjs +4 -0
  9. package/dist/adapters/entries/curl.d.ts +2136 -0
  10. package/dist/adapters/entries/curl.js +2 -0
  11. package/dist/adapters/entries/fetch.cjs +2 -0
  12. package/dist/adapters/entries/fetch.d.ts +2127 -0
  13. package/dist/adapters/entries/fetch.js +1 -0
  14. package/dist/adapters/entries/http.cjs +2 -0
  15. package/dist/adapters/entries/http.d.ts +2126 -0
  16. package/dist/adapters/entries/http.js +1 -0
  17. package/dist/adapters/entries/http2.cjs +4 -0
  18. package/dist/adapters/entries/http2.d.ts +2136 -0
  19. package/dist/adapters/entries/http2.js +2 -0
  20. package/dist/adapters/entries/react-native.cjs +2 -0
  21. package/dist/adapters/entries/react-native.d.ts +2126 -0
  22. package/dist/adapters/entries/react-native.js +1 -0
  23. package/dist/adapters/entries/xhr.cjs +2 -0
  24. package/dist/adapters/entries/xhr.d.ts +2127 -0
  25. package/dist/adapters/entries/xhr.js +1 -0
  26. package/dist/adapters/fetch.cjs +740 -0
  27. package/dist/adapters/fetch.js +739 -0
  28. package/dist/adapters/http.cjs +1153 -0
  29. package/dist/adapters/http.js +1151 -0
  30. package/dist/adapters/http2.cjs +957 -0
  31. package/dist/adapters/http2.js +956 -0
  32. package/dist/adapters/index.cjs +6 -0
  33. package/dist/adapters/index.js +7 -0
  34. package/dist/adapters/picker.cjs +342 -0
  35. package/dist/adapters/picker.js +331 -0
  36. package/dist/adapters/react-native.cjs +545 -0
  37. package/dist/adapters/react-native.js +544 -0
  38. package/dist/adapters/xhr.cjs +622 -0
  39. package/dist/adapters/xhr.js +621 -0
  40. package/dist/cache/dns-cache.cjs +118 -0
  41. package/dist/cache/dns-cache.js +113 -0
  42. package/dist/cache/file-cacher.cjs +264 -0
  43. package/dist/cache/file-cacher.js +261 -0
  44. package/dist/cache/index.cjs +13 -0
  45. package/dist/cache/index.js +5 -0
  46. package/dist/cache/lru-cache.cjs +96 -0
  47. package/dist/cache/lru-cache.js +93 -0
  48. package/dist/cache/response-cache.cjs +314 -0
  49. package/dist/cache/response-cache.js +310 -0
  50. package/dist/cache/url-store.cjs +288 -0
  51. package/dist/cache/url-store.js +285 -0
  52. package/dist/core/hooks.cjs +133 -0
  53. package/dist/core/hooks.js +120 -0
  54. package/dist/core/rezo.cjs +464 -0
  55. package/dist/core/rezo.js +458 -0
  56. package/dist/crawler.d.ts +6255 -0
  57. package/dist/dom/index.cjs +1 -0
  58. package/dist/dom/index.d.ts +23 -0
  59. package/dist/dom/index.js +1 -0
  60. package/dist/entries/crawler.cjs +5 -0
  61. package/dist/entries/crawler.js +2 -0
  62. package/dist/errors/rezo-error.cjs +722 -0
  63. package/dist/errors/rezo-error.js +716 -0
  64. package/dist/index.cjs +34 -0
  65. package/dist/index.d.ts +3335 -0
  66. package/dist/index.js +26 -0
  67. package/dist/platform/browser.cjs +9 -0
  68. package/dist/platform/browser.d.ts +3203 -0
  69. package/dist/platform/browser.js +7 -0
  70. package/dist/platform/bun.cjs +9 -0
  71. package/dist/platform/bun.d.ts +3203 -0
  72. package/dist/platform/bun.js +7 -0
  73. package/dist/platform/deno.cjs +9 -0
  74. package/dist/platform/deno.d.ts +3203 -0
  75. package/dist/platform/deno.js +7 -0
  76. package/dist/platform/node.cjs +9 -0
  77. package/dist/platform/node.d.ts +3203 -0
  78. package/dist/platform/node.js +7 -0
  79. package/dist/platform/react-native.cjs +9 -0
  80. package/dist/platform/react-native.d.ts +3203 -0
  81. package/dist/platform/react-native.js +7 -0
  82. package/dist/platform/worker.cjs +9 -0
  83. package/dist/platform/worker.d.ts +3203 -0
  84. package/dist/platform/worker.js +7 -0
  85. package/dist/plugin/addon/decodo/index.cjs +1 -0
  86. package/dist/plugin/addon/decodo/index.js +1 -0
  87. package/dist/plugin/addon/decodo/options.cjs +1 -0
  88. package/dist/plugin/addon/decodo/options.js +1 -0
  89. package/dist/plugin/addon/oxylabs/index.cjs +1 -0
  90. package/dist/plugin/addon/oxylabs/index.js +1 -0
  91. package/dist/plugin/addon/oxylabs/options.cjs +1 -0
  92. package/dist/plugin/addon/oxylabs/options.js +1 -0
  93. package/dist/plugin/crawler-options.cjs +1 -0
  94. package/dist/plugin/crawler-options.js +1 -0
  95. package/dist/plugin/crawler.cjs +519 -0
  96. package/dist/plugin/crawler.js +517 -0
  97. package/dist/plugin/index.cjs +36 -0
  98. package/dist/plugin/index.js +32 -0
  99. package/dist/proxy/index.cjs +142 -0
  100. package/dist/proxy/index.js +139 -0
  101. package/dist/responses/buildError.cjs +452 -0
  102. package/dist/responses/buildError.js +441 -0
  103. package/dist/responses/buildResponse.cjs +365 -0
  104. package/dist/responses/buildResponse.js +361 -0
  105. package/dist/responses/download.cjs +54 -0
  106. package/dist/responses/download.js +52 -0
  107. package/dist/responses/stream.cjs +60 -0
  108. package/dist/responses/stream.js +58 -0
  109. package/dist/responses/upload.cjs +54 -0
  110. package/dist/responses/upload.js +52 -0
  111. package/dist/types/cookies.cjs +394 -0
  112. package/dist/types/cookies.js +391 -0
  113. package/dist/types/download.cjs +10 -0
  114. package/dist/types/download.js +10 -0
  115. package/dist/types/rezo-request.cjs +131 -0
  116. package/dist/types/rezo-request.js +131 -0
  117. package/dist/utils/agent-merger.cjs +111 -0
  118. package/dist/utils/agent-merger.js +108 -0
  119. package/dist/utils/compression.cjs +84 -0
  120. package/dist/utils/compression.js +82 -0
  121. package/dist/utils/cookies.cjs +514 -0
  122. package/dist/utils/cookies.js +511 -0
  123. package/dist/utils/data-operations.cjs +75 -0
  124. package/dist/utils/data-operations.js +73 -0
  125. package/dist/utils/form-data.cjs +164 -0
  126. package/dist/utils/form-data.js +161 -0
  127. package/dist/utils/headers.cjs +162 -0
  128. package/dist/utils/headers.js +161 -0
  129. package/dist/utils/http-config.cjs +723 -0
  130. package/dist/utils/http-config.js +718 -0
  131. package/dist/utils/index.cjs +8 -0
  132. package/dist/utils/index.js +8 -0
  133. package/dist/utils/tools.cjs +18 -0
  134. package/dist/utils/tools.js +15 -0
  135. package/package.json +172 -0
@@ -0,0 +1,6 @@
1
+ const _mod_htaps8 = require('./picker.cjs');
2
+ exports.detectRuntime = _mod_htaps8.detectRuntime;
3
+ exports.getAdapterCapabilities = _mod_htaps8.getAdapterCapabilities;
4
+ exports.buildAdapterContext = _mod_htaps8.buildAdapterContext;
5
+ exports.getAvailableAdapters = _mod_htaps8.getAvailableAdapters;
6
+ exports.selectAdapter = _mod_htaps8.selectAdapter;;
@@ -0,0 +1,7 @@
1
+ export {
2
+ detectRuntime,
3
+ getAdapterCapabilities,
4
+ buildAdapterContext,
5
+ getAvailableAdapters,
6
+ selectAdapter
7
+ } from './picker.js';
@@ -0,0 +1,342 @@
1
+ const adapterCache = new Map;
2
+ function detectRuntime() {
3
+ const result = {
4
+ isNode: false,
5
+ isBrowser: false,
6
+ isDeno: false,
7
+ isBun: false,
8
+ isReactNative: false,
9
+ isEdge: false,
10
+ isWebWorker: false,
11
+ isElectronMain: false,
12
+ isElectronRenderer: false
13
+ };
14
+ if (typeof globalThis.Deno !== "undefined") {
15
+ result.isDeno = true;
16
+ return result;
17
+ }
18
+ if (typeof globalThis.Bun !== "undefined") {
19
+ result.isBun = true;
20
+ result.isNode = true;
21
+ return result;
22
+ }
23
+ if (typeof navigator !== "undefined" && typeof navigator.product === "string" && navigator.product === "ReactNative") {
24
+ result.isReactNative = true;
25
+ return result;
26
+ }
27
+ if (typeof globalThis.EdgeRuntime !== "undefined" || typeof globalThis.caches !== "undefined" && typeof globalThis.WebSocketPair !== "undefined") {
28
+ result.isEdge = true;
29
+ return result;
30
+ }
31
+ if (typeof self !== "undefined" && typeof self.WorkerGlobalScope !== "undefined" && self instanceof self.WorkerGlobalScope) {
32
+ result.isWebWorker = true;
33
+ result.isBrowser = true;
34
+ return result;
35
+ }
36
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
37
+ if (typeof process !== "undefined" && process.versions?.electron) {
38
+ if (process.type === "renderer") {
39
+ result.isElectronRenderer = true;
40
+ } else {
41
+ result.isElectronMain = true;
42
+ }
43
+ result.isNode = true;
44
+ } else {
45
+ result.isBrowser = true;
46
+ }
47
+ return result;
48
+ }
49
+ if (typeof process !== "undefined" && process.versions?.node && typeof module !== "undefined") {
50
+ result.isNode = true;
51
+ return result;
52
+ }
53
+ result.isNode = true;
54
+ return result;
55
+ }
56
+ function getAdapterCapabilities(adapter) {
57
+ const capabilities = {
58
+ http: {
59
+ cookies: true,
60
+ proxy: true,
61
+ streaming: true,
62
+ http2: false,
63
+ uploadProgress: true,
64
+ downloadProgress: true,
65
+ fileDownload: true,
66
+ compression: true,
67
+ abortSignal: true,
68
+ tlsConfig: true
69
+ },
70
+ http2: {
71
+ cookies: true,
72
+ proxy: true,
73
+ streaming: true,
74
+ http2: true,
75
+ uploadProgress: true,
76
+ downloadProgress: true,
77
+ fileDownload: true,
78
+ compression: true,
79
+ abortSignal: true,
80
+ tlsConfig: true
81
+ },
82
+ curl: {
83
+ cookies: true,
84
+ proxy: true,
85
+ streaming: true,
86
+ http2: true,
87
+ uploadProgress: true,
88
+ downloadProgress: true,
89
+ fileDownload: true,
90
+ compression: true,
91
+ abortSignal: true,
92
+ tlsConfig: true
93
+ },
94
+ fetch: {
95
+ cookies: false,
96
+ proxy: false,
97
+ streaming: true,
98
+ http2: false,
99
+ uploadProgress: false,
100
+ downloadProgress: true,
101
+ fileDownload: false,
102
+ compression: true,
103
+ abortSignal: true,
104
+ tlsConfig: false
105
+ },
106
+ xhr: {
107
+ cookies: false,
108
+ proxy: false,
109
+ streaming: false,
110
+ http2: false,
111
+ uploadProgress: true,
112
+ downloadProgress: true,
113
+ fileDownload: false,
114
+ compression: false,
115
+ abortSignal: true,
116
+ tlsConfig: false
117
+ },
118
+ "react-native": {
119
+ cookies: false,
120
+ proxy: false,
121
+ streaming: true,
122
+ http2: false,
123
+ uploadProgress: false,
124
+ downloadProgress: true,
125
+ fileDownload: true,
126
+ compression: true,
127
+ abortSignal: true,
128
+ tlsConfig: false
129
+ }
130
+ };
131
+ return capabilities[adapter];
132
+ }
133
+ function buildAdapterContext(options, defaultOptions) {
134
+ const internal = options;
135
+ return {
136
+ needsCookies: !!(options.cookieJar || defaultOptions.cookieJar),
137
+ needsProxy: !!options.proxy,
138
+ needsStreaming: !!internal._isStream,
139
+ needsHttp2: !!(options.http2 || defaultOptions.http2),
140
+ needsUploadProgress: !!internal._isUpload,
141
+ needsDownloadProgress: !!internal._isDownload,
142
+ needsFileDownload: !!(internal.fileName || internal.saveTo),
143
+ preferredAdapter: options.adapter
144
+ };
145
+ }
146
+ function getAvailableAdapters(runtime) {
147
+ if (runtime.isReactNative) {
148
+ return ["react-native", "fetch"];
149
+ }
150
+ if (runtime.isBrowser || runtime.isWebWorker) {
151
+ return ["fetch", "xhr"];
152
+ }
153
+ if (runtime.isEdge) {
154
+ return ["fetch"];
155
+ }
156
+ if (runtime.isDeno) {
157
+ return ["fetch", "http"];
158
+ }
159
+ if (runtime.isNode || runtime.isBun || runtime.isElectronMain || runtime.isElectronRenderer) {
160
+ return ["http", "http2", "curl", "fetch"];
161
+ }
162
+ return ["fetch", "http"];
163
+ }
164
+ function scoreAdapter(adapter, context, runtime) {
165
+ const caps = getAdapterCapabilities(adapter);
166
+ let score = 100;
167
+ if (context.needsCookies && !caps.cookies) {
168
+ return -1;
169
+ }
170
+ if (context.needsProxy && !caps.proxy) {
171
+ return -1;
172
+ }
173
+ if (context.needsHttp2 && !caps.http2) {
174
+ score -= 30;
175
+ }
176
+ if (context.needsStreaming && caps.streaming) {
177
+ score += 20;
178
+ }
179
+ if (context.needsUploadProgress && caps.uploadProgress) {
180
+ score += 10;
181
+ }
182
+ if (context.needsDownloadProgress && caps.downloadProgress) {
183
+ score += 10;
184
+ }
185
+ if (context.needsFileDownload && caps.fileDownload) {
186
+ score += 15;
187
+ }
188
+ if (runtime.isNode || runtime.isBun) {
189
+ if (adapter === "http" || adapter === "http2") {
190
+ score += 10;
191
+ }
192
+ }
193
+ if (runtime.isBrowser) {
194
+ if (adapter === "fetch") {
195
+ score += 15;
196
+ }
197
+ }
198
+ if (runtime.isReactNative) {
199
+ if (adapter === "react-native") {
200
+ score += 20;
201
+ }
202
+ }
203
+ if (runtime.isEdge) {
204
+ if (adapter === "fetch") {
205
+ score += 25;
206
+ }
207
+ }
208
+ const featureCount = Object.values(caps).filter(Boolean).length;
209
+ score += featureCount * 2;
210
+ return score;
211
+ }
212
+ function selectAdapter(context, runtime) {
213
+ const env = runtime || detectRuntime();
214
+ if (context.preferredAdapter) {
215
+ const available = getAvailableAdapters(env);
216
+ if (available.includes(context.preferredAdapter)) {
217
+ return context.preferredAdapter;
218
+ }
219
+ console.warn(`[Rezo] Preferred adapter '${context.preferredAdapter}' not available in current runtime. ` + `Available: ${available.join(", ")}`);
220
+ }
221
+ const available = getAvailableAdapters(env);
222
+ const scored = available.map((adapter) => ({
223
+ adapter,
224
+ score: scoreAdapter(adapter, context, env)
225
+ }));
226
+ const qualified = scored.filter((s) => s.score >= 0);
227
+ if (qualified.length === 0) {
228
+ console.warn(`[Rezo] No adapter fully satisfies requirements. ` + `Falling back to '${available[0]}'. Some features may be unavailable.`);
229
+ return available[0];
230
+ }
231
+ qualified.sort((a, b) => b.score - a.score);
232
+ return qualified[0].adapter;
233
+ }
234
+ async function loadAdapter(adapter) {
235
+ const cached = adapterCache.get(adapter);
236
+ if (cached) {
237
+ return cached;
238
+ }
239
+ let adapterModule;
240
+ switch (adapter) {
241
+ case "http":
242
+ adapterModule = await import("./http.js");
243
+ break;
244
+ case "http2":
245
+ adapterModule = await import("./http2.js");
246
+ break;
247
+ case "curl":
248
+ adapterModule = await import("./curl.js");
249
+ break;
250
+ case "fetch":
251
+ adapterModule = await import("./fetch.js");
252
+ break;
253
+ case "xhr":
254
+ adapterModule = await import("./xhr.js");
255
+ break;
256
+ case "react-native":
257
+ adapterModule = await import("./react-native.js");
258
+ break;
259
+ default:
260
+ throw new Error(`[Rezo] Unknown adapter type: ${adapter}`);
261
+ }
262
+ adapterCache.set(adapter, adapterModule);
263
+ return adapterModule;
264
+ }
265
+ function clearAdapterCache() {
266
+ adapterCache.clear();
267
+ }
268
+ async function executeWithBestAdapter(options, defaultOptions, jar) {
269
+ const runtime = detectRuntime();
270
+ const context = buildAdapterContext(options, defaultOptions);
271
+ const adapter = selectAdapter(context, runtime);
272
+ const adapterModule = await loadAdapter(adapter);
273
+ return adapterModule.executeRequest(options, defaultOptions, jar);
274
+ }
275
+ function getAdapterDiagnostics(options, defaultOptions) {
276
+ const runtime = detectRuntime();
277
+ const context = buildAdapterContext(options, defaultOptions);
278
+ const available = getAvailableAdapters(runtime);
279
+ const scores = available.map((adapter) => ({
280
+ adapter,
281
+ score: scoreAdapter(adapter, context, runtime)
282
+ }));
283
+ const selected = selectAdapter(context, runtime);
284
+ return {
285
+ runtime,
286
+ context,
287
+ available,
288
+ selected,
289
+ scores,
290
+ selectedCapabilities: getAdapterCapabilities(selected)
291
+ };
292
+ }
293
+ function createAdapterPicker(config = {}) {
294
+ return (options, defaultOptions) => {
295
+ const runtime = detectRuntime();
296
+ const context = buildAdapterContext(options, defaultOptions);
297
+ if (config.adapter) {
298
+ if (config.debug) {
299
+ console.log(`[Rezo Picker] Using manually configured adapter: ${config.adapter}`);
300
+ }
301
+ return config.adapter;
302
+ }
303
+ if (config.customPicker) {
304
+ const selected = config.customPicker(context, runtime);
305
+ if (config.debug) {
306
+ console.log(`[Rezo Picker] Custom picker selected: ${selected}`);
307
+ }
308
+ return selected;
309
+ }
310
+ const selected = selectAdapter(context, runtime);
311
+ if (config.debug) {
312
+ const diagnostics = getAdapterDiagnostics(options, defaultOptions);
313
+ console.log(`[Rezo Picker] Auto-selected: ${selected}`);
314
+ console.log(`[Rezo Picker] Runtime:`, diagnostics.runtime);
315
+ console.log(`[Rezo Picker] Scores:`, diagnostics.scores);
316
+ }
317
+ return selected;
318
+ };
319
+ }
320
+ export default {
321
+ detectRuntime,
322
+ getAdapterCapabilities,
323
+ buildAdapterContext,
324
+ getAvailableAdapters,
325
+ selectAdapter,
326
+ loadAdapter,
327
+ clearAdapterCache,
328
+ executeWithBestAdapter,
329
+ getAdapterDiagnostics,
330
+ createAdapterPicker
331
+ };
332
+
333
+ exports.detectRuntime = detectRuntime;
334
+ exports.getAdapterCapabilities = getAdapterCapabilities;
335
+ exports.buildAdapterContext = buildAdapterContext;
336
+ exports.getAvailableAdapters = getAvailableAdapters;
337
+ exports.selectAdapter = selectAdapter;
338
+ exports.loadAdapter = loadAdapter;
339
+ exports.clearAdapterCache = clearAdapterCache;
340
+ exports.executeWithBestAdapter = executeWithBestAdapter;
341
+ exports.getAdapterDiagnostics = getAdapterDiagnostics;
342
+ exports.createAdapterPicker = createAdapterPicker;
@@ -0,0 +1,331 @@
1
+ const adapterCache = new Map;
2
+ export function detectRuntime() {
3
+ const result = {
4
+ isNode: false,
5
+ isBrowser: false,
6
+ isDeno: false,
7
+ isBun: false,
8
+ isReactNative: false,
9
+ isEdge: false,
10
+ isWebWorker: false,
11
+ isElectronMain: false,
12
+ isElectronRenderer: false
13
+ };
14
+ if (typeof globalThis.Deno !== "undefined") {
15
+ result.isDeno = true;
16
+ return result;
17
+ }
18
+ if (typeof globalThis.Bun !== "undefined") {
19
+ result.isBun = true;
20
+ result.isNode = true;
21
+ return result;
22
+ }
23
+ if (typeof navigator !== "undefined" && typeof navigator.product === "string" && navigator.product === "ReactNative") {
24
+ result.isReactNative = true;
25
+ return result;
26
+ }
27
+ if (typeof globalThis.EdgeRuntime !== "undefined" || typeof globalThis.caches !== "undefined" && typeof globalThis.WebSocketPair !== "undefined") {
28
+ result.isEdge = true;
29
+ return result;
30
+ }
31
+ if (typeof self !== "undefined" && typeof self.WorkerGlobalScope !== "undefined" && self instanceof self.WorkerGlobalScope) {
32
+ result.isWebWorker = true;
33
+ result.isBrowser = true;
34
+ return result;
35
+ }
36
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
37
+ if (typeof process !== "undefined" && process.versions?.electron) {
38
+ if (process.type === "renderer") {
39
+ result.isElectronRenderer = true;
40
+ } else {
41
+ result.isElectronMain = true;
42
+ }
43
+ result.isNode = true;
44
+ } else {
45
+ result.isBrowser = true;
46
+ }
47
+ return result;
48
+ }
49
+ if (typeof process !== "undefined" && process.versions?.node && typeof module !== "undefined") {
50
+ result.isNode = true;
51
+ return result;
52
+ }
53
+ result.isNode = true;
54
+ return result;
55
+ }
56
+ export function getAdapterCapabilities(adapter) {
57
+ const capabilities = {
58
+ http: {
59
+ cookies: true,
60
+ proxy: true,
61
+ streaming: true,
62
+ http2: false,
63
+ uploadProgress: true,
64
+ downloadProgress: true,
65
+ fileDownload: true,
66
+ compression: true,
67
+ abortSignal: true,
68
+ tlsConfig: true
69
+ },
70
+ http2: {
71
+ cookies: true,
72
+ proxy: true,
73
+ streaming: true,
74
+ http2: true,
75
+ uploadProgress: true,
76
+ downloadProgress: true,
77
+ fileDownload: true,
78
+ compression: true,
79
+ abortSignal: true,
80
+ tlsConfig: true
81
+ },
82
+ curl: {
83
+ cookies: true,
84
+ proxy: true,
85
+ streaming: true,
86
+ http2: true,
87
+ uploadProgress: true,
88
+ downloadProgress: true,
89
+ fileDownload: true,
90
+ compression: true,
91
+ abortSignal: true,
92
+ tlsConfig: true
93
+ },
94
+ fetch: {
95
+ cookies: false,
96
+ proxy: false,
97
+ streaming: true,
98
+ http2: false,
99
+ uploadProgress: false,
100
+ downloadProgress: true,
101
+ fileDownload: false,
102
+ compression: true,
103
+ abortSignal: true,
104
+ tlsConfig: false
105
+ },
106
+ xhr: {
107
+ cookies: false,
108
+ proxy: false,
109
+ streaming: false,
110
+ http2: false,
111
+ uploadProgress: true,
112
+ downloadProgress: true,
113
+ fileDownload: false,
114
+ compression: false,
115
+ abortSignal: true,
116
+ tlsConfig: false
117
+ },
118
+ "react-native": {
119
+ cookies: false,
120
+ proxy: false,
121
+ streaming: true,
122
+ http2: false,
123
+ uploadProgress: false,
124
+ downloadProgress: true,
125
+ fileDownload: true,
126
+ compression: true,
127
+ abortSignal: true,
128
+ tlsConfig: false
129
+ }
130
+ };
131
+ return capabilities[adapter];
132
+ }
133
+ export function buildAdapterContext(options, defaultOptions) {
134
+ const internal = options;
135
+ return {
136
+ needsCookies: !!(options.cookieJar || defaultOptions.cookieJar),
137
+ needsProxy: !!options.proxy,
138
+ needsStreaming: !!internal._isStream,
139
+ needsHttp2: !!(options.http2 || defaultOptions.http2),
140
+ needsUploadProgress: !!internal._isUpload,
141
+ needsDownloadProgress: !!internal._isDownload,
142
+ needsFileDownload: !!(internal.fileName || internal.saveTo),
143
+ preferredAdapter: options.adapter
144
+ };
145
+ }
146
+ export function getAvailableAdapters(runtime) {
147
+ if (runtime.isReactNative) {
148
+ return ["react-native", "fetch"];
149
+ }
150
+ if (runtime.isBrowser || runtime.isWebWorker) {
151
+ return ["fetch", "xhr"];
152
+ }
153
+ if (runtime.isEdge) {
154
+ return ["fetch"];
155
+ }
156
+ if (runtime.isDeno) {
157
+ return ["fetch", "http"];
158
+ }
159
+ if (runtime.isNode || runtime.isBun || runtime.isElectronMain || runtime.isElectronRenderer) {
160
+ return ["http", "http2", "curl", "fetch"];
161
+ }
162
+ return ["fetch", "http"];
163
+ }
164
+ function scoreAdapter(adapter, context, runtime) {
165
+ const caps = getAdapterCapabilities(adapter);
166
+ let score = 100;
167
+ if (context.needsCookies && !caps.cookies) {
168
+ return -1;
169
+ }
170
+ if (context.needsProxy && !caps.proxy) {
171
+ return -1;
172
+ }
173
+ if (context.needsHttp2 && !caps.http2) {
174
+ score -= 30;
175
+ }
176
+ if (context.needsStreaming && caps.streaming) {
177
+ score += 20;
178
+ }
179
+ if (context.needsUploadProgress && caps.uploadProgress) {
180
+ score += 10;
181
+ }
182
+ if (context.needsDownloadProgress && caps.downloadProgress) {
183
+ score += 10;
184
+ }
185
+ if (context.needsFileDownload && caps.fileDownload) {
186
+ score += 15;
187
+ }
188
+ if (runtime.isNode || runtime.isBun) {
189
+ if (adapter === "http" || adapter === "http2") {
190
+ score += 10;
191
+ }
192
+ }
193
+ if (runtime.isBrowser) {
194
+ if (adapter === "fetch") {
195
+ score += 15;
196
+ }
197
+ }
198
+ if (runtime.isReactNative) {
199
+ if (adapter === "react-native") {
200
+ score += 20;
201
+ }
202
+ }
203
+ if (runtime.isEdge) {
204
+ if (adapter === "fetch") {
205
+ score += 25;
206
+ }
207
+ }
208
+ const featureCount = Object.values(caps).filter(Boolean).length;
209
+ score += featureCount * 2;
210
+ return score;
211
+ }
212
+ export function selectAdapter(context, runtime) {
213
+ const env = runtime || detectRuntime();
214
+ if (context.preferredAdapter) {
215
+ const available = getAvailableAdapters(env);
216
+ if (available.includes(context.preferredAdapter)) {
217
+ return context.preferredAdapter;
218
+ }
219
+ console.warn(`[Rezo] Preferred adapter '${context.preferredAdapter}' not available in current runtime. ` + `Available: ${available.join(", ")}`);
220
+ }
221
+ const available = getAvailableAdapters(env);
222
+ const scored = available.map((adapter) => ({
223
+ adapter,
224
+ score: scoreAdapter(adapter, context, env)
225
+ }));
226
+ const qualified = scored.filter((s) => s.score >= 0);
227
+ if (qualified.length === 0) {
228
+ console.warn(`[Rezo] No adapter fully satisfies requirements. ` + `Falling back to '${available[0]}'. Some features may be unavailable.`);
229
+ return available[0];
230
+ }
231
+ qualified.sort((a, b) => b.score - a.score);
232
+ return qualified[0].adapter;
233
+ }
234
+ export async function loadAdapter(adapter) {
235
+ const cached = adapterCache.get(adapter);
236
+ if (cached) {
237
+ return cached;
238
+ }
239
+ let adapterModule;
240
+ switch (adapter) {
241
+ case "http":
242
+ adapterModule = await import("./http.js");
243
+ break;
244
+ case "http2":
245
+ adapterModule = await import("./http2.js");
246
+ break;
247
+ case "curl":
248
+ adapterModule = await import("./curl.js");
249
+ break;
250
+ case "fetch":
251
+ adapterModule = await import("./fetch.js");
252
+ break;
253
+ case "xhr":
254
+ adapterModule = await import("./xhr.js");
255
+ break;
256
+ case "react-native":
257
+ adapterModule = await import("./react-native.js");
258
+ break;
259
+ default:
260
+ throw new Error(`[Rezo] Unknown adapter type: ${adapter}`);
261
+ }
262
+ adapterCache.set(adapter, adapterModule);
263
+ return adapterModule;
264
+ }
265
+ export function clearAdapterCache() {
266
+ adapterCache.clear();
267
+ }
268
+ export async function executeWithBestAdapter(options, defaultOptions, jar) {
269
+ const runtime = detectRuntime();
270
+ const context = buildAdapterContext(options, defaultOptions);
271
+ const adapter = selectAdapter(context, runtime);
272
+ const adapterModule = await loadAdapter(adapter);
273
+ return adapterModule.executeRequest(options, defaultOptions, jar);
274
+ }
275
+ export function getAdapterDiagnostics(options, defaultOptions) {
276
+ const runtime = detectRuntime();
277
+ const context = buildAdapterContext(options, defaultOptions);
278
+ const available = getAvailableAdapters(runtime);
279
+ const scores = available.map((adapter) => ({
280
+ adapter,
281
+ score: scoreAdapter(adapter, context, runtime)
282
+ }));
283
+ const selected = selectAdapter(context, runtime);
284
+ return {
285
+ runtime,
286
+ context,
287
+ available,
288
+ selected,
289
+ scores,
290
+ selectedCapabilities: getAdapterCapabilities(selected)
291
+ };
292
+ }
293
+ export function createAdapterPicker(config = {}) {
294
+ return (options, defaultOptions) => {
295
+ const runtime = detectRuntime();
296
+ const context = buildAdapterContext(options, defaultOptions);
297
+ if (config.adapter) {
298
+ if (config.debug) {
299
+ console.log(`[Rezo Picker] Using manually configured adapter: ${config.adapter}`);
300
+ }
301
+ return config.adapter;
302
+ }
303
+ if (config.customPicker) {
304
+ const selected = config.customPicker(context, runtime);
305
+ if (config.debug) {
306
+ console.log(`[Rezo Picker] Custom picker selected: ${selected}`);
307
+ }
308
+ return selected;
309
+ }
310
+ const selected = selectAdapter(context, runtime);
311
+ if (config.debug) {
312
+ const diagnostics = getAdapterDiagnostics(options, defaultOptions);
313
+ console.log(`[Rezo Picker] Auto-selected: ${selected}`);
314
+ console.log(`[Rezo Picker] Runtime:`, diagnostics.runtime);
315
+ console.log(`[Rezo Picker] Scores:`, diagnostics.scores);
316
+ }
317
+ return selected;
318
+ };
319
+ }
320
+ export default {
321
+ detectRuntime,
322
+ getAdapterCapabilities,
323
+ buildAdapterContext,
324
+ getAvailableAdapters,
325
+ selectAdapter,
326
+ loadAdapter,
327
+ clearAdapterCache,
328
+ executeWithBestAdapter,
329
+ getAdapterDiagnostics,
330
+ createAdapterPicker
331
+ };