@npy/fetch 0.1.2 → 0.1.4
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/README.md +143 -50
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,111 +1,204 @@
|
|
|
1
1
|
# @npy/fetch
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An HTTP/1.1 client built on raw TCP sockets with a fetch-compatible API, per-origin connection pooling, and first-class proxy support.
|
|
4
4
|
|
|
5
5
|
> [!NOTE]
|
|
6
|
-
>
|
|
6
|
+
> Node.js and Bun only — does not work in the browser.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
7
9
|
|
|
8
|
-
## install
|
|
9
10
|
```sh
|
|
10
11
|
bun add @npy/fetch
|
|
11
|
-
# or
|
|
12
12
|
npm install @npy/fetch
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Simple fetch
|
|
16
18
|
|
|
17
|
-
### simple fetch
|
|
18
19
|
```ts
|
|
19
20
|
import { fetch } from '@npy/fetch'
|
|
20
21
|
|
|
21
|
-
const response = await fetch('https://httpbin.org/
|
|
22
|
-
const
|
|
23
|
-
console.log(
|
|
22
|
+
const response = await fetch('https://httpbin.org/get')
|
|
23
|
+
const data = await response.json()
|
|
24
|
+
console.log(data)
|
|
24
25
|
|
|
25
|
-
fetch.close()
|
|
26
|
+
await fetch.close()
|
|
26
27
|
```
|
|
27
28
|
|
|
28
|
-
###
|
|
29
|
-
```ts
|
|
30
|
-
import { createFetch, HttpClient } from '@npy/fetch'
|
|
31
|
-
import { ProxyDialer } from '@npy/fetch/dialers'
|
|
29
|
+
### With proxy
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
dialer: new ProxyDialer('http://user:pass@proxy.example.com:8080'),
|
|
35
|
-
}))
|
|
31
|
+
Pass a proxy URL directly to the fetch options:
|
|
36
32
|
|
|
37
|
-
|
|
33
|
+
```ts
|
|
34
|
+
import { fetch } from '@npy/fetch'
|
|
35
|
+
|
|
36
|
+
const response = await fetch('https://httpbin.org/ip', {
|
|
37
|
+
proxy: 'http://user:password@proxy.example.com:8080'
|
|
38
|
+
})
|
|
38
39
|
console.log(await response.json())
|
|
39
40
|
|
|
40
|
-
fetch.close()
|
|
41
|
+
await fetch.close()
|
|
41
42
|
```
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
Supports HTTP, HTTPS, and SOCKS5 proxies:
|
|
45
|
+
|
|
44
46
|
```ts
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
// SOCKS5
|
|
48
|
+
await fetch('https://example.com', {
|
|
49
|
+
proxy: 'socks5://user:password@proxy.example.com:1080'
|
|
50
|
+
})
|
|
51
|
+
```
|
|
47
52
|
|
|
48
|
-
|
|
49
|
-
dialer: new ProxyDialer('socks5://user:pass@proxy.example.com:1080'),
|
|
50
|
-
}))
|
|
53
|
+
### POST request
|
|
51
54
|
|
|
52
|
-
|
|
55
|
+
```ts
|
|
56
|
+
import { fetch } from '@npy/fetch'
|
|
57
|
+
|
|
58
|
+
const response = await fetch('https://httpbin.org/post', {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
headers: { 'content-type': 'application/json' },
|
|
61
|
+
body: JSON.stringify({ hello: 'world' })
|
|
62
|
+
})
|
|
53
63
|
console.log(await response.json())
|
|
54
64
|
|
|
55
|
-
fetch.close()
|
|
65
|
+
await fetch.close()
|
|
56
66
|
```
|
|
57
67
|
|
|
58
|
-
###
|
|
68
|
+
### Custom HTTP client
|
|
69
|
+
|
|
70
|
+
For fine-grained control over connection pooling and I/O:
|
|
71
|
+
|
|
59
72
|
```ts
|
|
60
73
|
import { HttpClient } from '@npy/fetch'
|
|
61
74
|
|
|
62
75
|
const client = new HttpClient({
|
|
63
|
-
poolMaxPerHost:
|
|
64
|
-
poolMaxIdlePerHost:
|
|
65
|
-
poolIdleTimeout: 30_000,
|
|
76
|
+
poolMaxPerHost: 32,
|
|
77
|
+
poolMaxIdlePerHost: 8,
|
|
66
78
|
connect: {
|
|
67
79
|
keepAlive: true,
|
|
68
80
|
noDelay: true,
|
|
69
|
-
timeout: 5_000,
|
|
70
81
|
},
|
|
71
82
|
io: {
|
|
72
83
|
reader: {
|
|
73
84
|
bufferSize: 32 * 1024,
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
maxBodySize: '10mb',
|
|
85
|
+
maxHeaderSize: 64 * 1024,
|
|
86
|
+
maxBodySize: '50mb',
|
|
77
87
|
decompress: true,
|
|
78
88
|
},
|
|
79
89
|
writer: {
|
|
80
|
-
|
|
81
|
-
|
|
90
|
+
writeBufferSize: 16 * 1024,
|
|
91
|
+
directWriteThreshold: 64 * 1024,
|
|
82
92
|
},
|
|
83
93
|
},
|
|
84
94
|
})
|
|
85
95
|
|
|
86
|
-
const response = await client.send({
|
|
87
|
-
|
|
96
|
+
const response = await client.send({
|
|
97
|
+
url: 'https://httpbin.org/post',
|
|
98
|
+
method: 'POST',
|
|
99
|
+
headers: new Headers({ 'content-type': 'application/json' }),
|
|
100
|
+
body: JSON.stringify({ data: 'example' }),
|
|
101
|
+
})
|
|
88
102
|
|
|
103
|
+
console.log(await response.json())
|
|
89
104
|
await client.close()
|
|
90
105
|
```
|
|
91
106
|
|
|
92
|
-
###
|
|
93
|
-
```ts
|
|
94
|
-
import { HttpClient } from '@npy/fetch'
|
|
107
|
+
### With ProxyDialer
|
|
95
108
|
|
|
96
|
-
|
|
109
|
+
Use `ProxyDialer` for explicit proxy configuration with custom HTTP client:
|
|
97
110
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
111
|
+
```ts
|
|
112
|
+
import { createFetch, HttpClient } from '@npy/fetch'
|
|
113
|
+
import { ProxyDialer } from '@npy/fetch/dialers'
|
|
114
|
+
|
|
115
|
+
const client = new HttpClient({
|
|
116
|
+
dialer: new ProxyDialer('http://user:password@proxy.example.com:8080'),
|
|
117
|
+
poolMaxPerHost: 16,
|
|
118
|
+
poolMaxIdlePerHost: 4,
|
|
103
119
|
})
|
|
104
120
|
|
|
121
|
+
const fetch = createFetch(client)
|
|
122
|
+
const response = await fetch('https://httpbin.org/ip')
|
|
105
123
|
console.log(await response.json())
|
|
124
|
+
|
|
106
125
|
await client.close()
|
|
107
126
|
```
|
|
108
127
|
|
|
109
|
-
|
|
128
|
+
Supports all proxy protocols:
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
// HTTP proxy
|
|
132
|
+
new ProxyDialer('http://proxy.example.com:8080')
|
|
133
|
+
|
|
134
|
+
// HTTPS proxy
|
|
135
|
+
new ProxyDialer('https://proxy.example.com:8443')
|
|
136
|
+
|
|
137
|
+
// SOCKS5 proxy
|
|
138
|
+
new ProxyDialer('socks5://proxy.example.com:1080')
|
|
139
|
+
|
|
140
|
+
// With authentication
|
|
141
|
+
new ProxyDialer('socks5://user:password@proxy.example.com:1080')
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## API
|
|
145
|
+
|
|
146
|
+
### `fetch(input, init?)`
|
|
147
|
+
|
|
148
|
+
Standard Fetch API with additional options:
|
|
149
|
+
|
|
150
|
+
- `proxy?: string | ProxyInfo | null` — Proxy URL (http, https, socks5)
|
|
151
|
+
- `client?: HttpClient` — Custom HTTP client instance
|
|
152
|
+
|
|
153
|
+
### `HttpClient` options
|
|
154
|
+
|
|
155
|
+
**Pool:**
|
|
156
|
+
|
|
157
|
+
- `poolMaxPerHost` (default: `10`)
|
|
158
|
+
- `poolMaxIdlePerHost` (default: `5`)
|
|
159
|
+
- `poolIdleTimeout` (default: `30000` ms)
|
|
160
|
+
|
|
161
|
+
**Connection:**
|
|
162
|
+
|
|
163
|
+
- `connect.timeout` (default: `5000` ms)
|
|
164
|
+
- `connect.keepAlive` (default: `true`)
|
|
165
|
+
- `connect.noDelay` (default: `true`)
|
|
166
|
+
|
|
167
|
+
**Reader:**
|
|
168
|
+
|
|
169
|
+
- `io.reader.bufferSize` — Internal buffer size
|
|
170
|
+
- `io.reader.readChunkSize` — Chunk read size
|
|
171
|
+
- `io.reader.maxHeaderSize` — Maximum header size
|
|
172
|
+
- `io.reader.maxBodySize` — Maximum body size
|
|
173
|
+
- `io.reader.maxLineSize` — Maximum line size
|
|
174
|
+
- `io.reader.maxBufferedBytes` — Max buffered before processing
|
|
175
|
+
- `io.reader.decompress` (default: `true`) — Auto-decompress gzip/deflate
|
|
176
|
+
|
|
177
|
+
**Writer:**
|
|
178
|
+
|
|
179
|
+
- `io.writer.writeBufferSize` — Write buffer size
|
|
180
|
+
- `io.writer.directWriteThreshold` — Direct write threshold
|
|
181
|
+
- `io.writer.coalesceBodyMaxBytes` — Coalesce writes up to this size
|
|
182
|
+
|
|
183
|
+
## Environment Variables
|
|
184
|
+
|
|
185
|
+
The library respects standard proxy environment variables:
|
|
186
|
+
|
|
187
|
+
- `HTTP_PROXY` — HTTP proxy URL
|
|
188
|
+
- `HTTPS_PROXY` — HTTPS proxy URL
|
|
189
|
+
- `SOCKS5_PROXY` — SOCKS5 proxy URL
|
|
190
|
+
- `SOCKS_PROXY` — Alternative SOCKS proxy URL
|
|
191
|
+
|
|
192
|
+
These are used when no explicit proxy is configured.
|
|
193
|
+
|
|
194
|
+
## Limitations
|
|
195
|
+
|
|
196
|
+
- **HTTP/1.1 only** — Does not support HTTP/2 or HTTP/3
|
|
197
|
+
- **Node.js and Bun** — Browser environments are not supported
|
|
198
|
+
- **Limited to standard HTTP methods** — GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS
|
|
199
|
+
|
|
200
|
+
## License
|
|
201
|
+
|
|
202
|
+
MIT License © 2026 matheus fernandes
|
|
110
203
|
|
|
111
|
-
|
|
204
|
+
Based on [deno-simple-fetch](https://github.com/esroyo/deno-simple-fetch).
|
package/package.json
CHANGED