jiren 1.1.0 → 1.1.5

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 CHANGED
@@ -1,19 +1,18 @@
1
- # jiren
1
+ # Jiren
2
2
 
3
- > **⚠️ BUN ONLY**: This package requires [Bun](https://bun.sh) runtime. Node.js is not supported.
4
-
5
- Ultra-fast HTTP/HTTPS client.
3
+ Ultra-fast HTTP/HTTPS client powered by native Zig (FFI).
6
4
  Designed to be significantly faster than `fetch` and other Node/Bun HTTP clients.
7
5
 
8
6
  ## Features
9
7
 
10
- - **Blazing Fast**: Native implementation with minimal overhead.
11
- - **HTTP/3 (QUIC) Support**: First-class support for modern, high-performance connections.
12
- - **Automatic Redirects**: Recursively follows redirects (301, 302, etc.) with cycle protection.
13
- - **Type-Safe API**: Strict options (`GetRequestOptions`, `PostRequestOptions`) for better DX.
14
- - **Helper Methods**: Built-in `.json<T>()` parser and header accessors.
8
+ - **Native Performance**: Written in Zig for memory safety and speed.
9
+ - **Anti-Bot Protection**: Bypass Cloudflare with curl-impersonate (Chrome TLS fingerprinting).
10
+ - **HTTP/1.1, HTTP/2 & HTTP/3 (QUIC)**: Full support for modern protocols.
15
11
  - **Connection Pooling**: Reuse connections for maximum throughput.
16
- - **0-RTT Session Resumption**: Extremely fast subsequent requests.
12
+ - **Mandatory Warmup**: Pre-warm connections for instant requests.
13
+ - **Type-Safe URLs**: Define named endpoints with full TypeScript autocomplete.
14
+ - **JSON & Text Helpers**: Easy response parsing.
15
+ - **Automatic Gzip Decompression**: Handles compressed responses transparently.
17
16
 
18
17
  ## Installation
19
18
 
@@ -23,67 +22,221 @@ bun add jiren
23
22
 
24
23
  ## Usage
25
24
 
26
- ### Basic Requests
25
+ ### Basic Usage (Type-Safe URLs)
26
+
27
+ **Warmup is now mandatory** - you must define URLs in the constructor:
27
28
 
28
29
  ```typescript
29
30
  import { JirenClient } from "jiren";
30
31
 
31
- const client = new JirenClient();
32
+ const client = new JirenClient({
33
+ warmup: {
34
+ google: "https://www.google.com",
35
+ github: "https://api.github.com",
36
+ myapi: "https://api.myservice.com",
37
+ },
38
+ });
32
39
 
33
- // Simple GET
34
- const res = client.get("https://google.com");
35
- console.log(res.status); // 200
40
+ // TypeScript knows about 'google', 'github', 'myapi' - full autocomplete!
41
+ const res = await client.url.google.get();
42
+ console.log(res.status);
43
+ const text = await res.body.text();
44
+ ```
36
45
 
37
- // JSON Parsing Helper
38
- const data = res.json<{ message: string }>();
46
+ ### JSON Response
47
+
48
+ ```typescript
49
+ interface User {
50
+ id: number;
51
+ name: string;
52
+ }
53
+
54
+ const client = new JirenClient({
55
+ warmup: {
56
+ api: "https://api.example.com",
57
+ },
58
+ });
59
+
60
+ const res = await client.url.api.get<User>({
61
+ path: "/user/1",
62
+ responseType: "json",
63
+ });
64
+ console.log(res.name); // Fully typed!
39
65
  ```
40
66
 
41
- ### Advanced Options (Headers, Redirects, Body)
67
+ ### Anti-Bot Mode (NEW! �️)
42
68
 
43
- Jiren enforces type safety. You cannot pass a body to a GET request!
69
+ Enable curl-impersonate for sites with bot protection:
44
70
 
45
71
  ```typescript
46
- // GET with Headers
47
- client.get("https://api.example.com", {
48
- headers: { Authorization: "Bearer token" },
72
+ const client = new JirenClient({
73
+ warmup: {
74
+ protected: "https://protected-site.com",
75
+ },
76
+ });
77
+
78
+ // Enable antibot mode for this request
79
+ const res = await client.url.protected.get({
80
+ antibot: true, // Uses curl-impersonate with Chrome fingerprinting
49
81
  });
82
+ ```
83
+
84
+ ### POST, PUT, PATCH, DELETE
50
85
 
51
- // POST with JSON body
52
- client.post(
53
- "https://api.example.com/users",
54
- JSON.stringify({ name: "Jiren" }),
86
+ ```typescript
87
+ const client = new JirenClient({
88
+ warmup: {
89
+ api: "https://api.myservice.com",
90
+ },
91
+ });
92
+
93
+ // POST with body
94
+ const created = await client.url.api.post(
95
+ JSON.stringify({ name: "New Item" }),
55
96
  {
97
+ path: "/items",
56
98
  headers: { "Content-Type": "application/json" },
57
99
  }
58
100
  );
59
101
 
60
- // Follow Redirects (e.g., http -> https)
61
- client.get("http://google.com", {
62
- maxRedirects: 5, // Automatically follows up to 5 hops
102
+ // PUT, PATCH, DELETE
103
+ await client.url.api.put(body, { path: "/items/1" });
104
+ await client.url.api.patch(body, { path: "/items/1" });
105
+ await client.url.api.delete(null, { path: "/items/1" });
106
+ ```
107
+
108
+ ### Response Helpers
109
+
110
+ ```typescript
111
+ const res = await client.url.api.get({ path: "/data" });
112
+
113
+ // Get as text
114
+ const text = await res.body.text();
115
+
116
+ // Get as JSON
117
+ const json = await res.body.json();
118
+
119
+ // Get as ArrayBuffer
120
+ const buffer = await res.body.arrayBuffer();
121
+
122
+ // Get as Blob
123
+ const blob = await res.body.blob();
124
+
125
+ // Or use responseType for automatic parsing
126
+ const data = await client.url.api.get({
127
+ path: "/data",
128
+ responseType: "json", // Returns parsed JSON directly
63
129
  });
64
130
  ```
65
131
 
66
- ### Prefetching
132
+ ## Why Jiren?
67
133
 
68
- Warm up DNS and TLS handshakes to ensure subsequent requests are instant.
134
+ ### Comparison with Other Clients
135
+
136
+ | Feature | **Jiren** | **Axios** | **ky** | **got** | **node-fetch** |
137
+ | -------------------- | :-------: | :-------: | :----: | :-----: | :------------: |
138
+ | Type-safe named URLs | ✅ | ❌ | ❌ | ❌ | ❌ |
139
+ | Mandatory warmup | ✅ | ❌ | ❌ | ❌ | ❌ |
140
+ | HTTP/3 (QUIC) | ✅ | ❌ | ❌ | ❌ | ❌ |
141
+ | Anti-bot protection | ✅ | ❌ | ❌ | ❌ | ❌ |
142
+ | Native performance | ✅ | ❌ | ❌ | ❌ | ❌ |
143
+ | Zero code generation | ✅ | ✅ | ✅ | ✅ | ✅ |
144
+ | Bun FFI optimized | ✅ | ❌ | ❌ | ❌ | ❌ |
145
+
146
+ ### What Makes Jiren Unique
147
+
148
+ 1. **🔥 Mandatory Warmup** - Pre-establishes connections at startup for instant requests
149
+ 2. **📝 Type-Safe URLs** - Full autocomplete without needing backend schemas or code generation
150
+ 3. **🚀 Native Speed** - Zig-powered core bypasses JavaScript overhead
151
+ 4. **🛡️ Anti-Bot Protection** - Bypass Cloudflare, TLS fingerprinting, and bot detection with curl-impersonate
152
+ 5. **⚡ HTTP/3 Support** - First-class QUIC support for modern protocols
153
+
154
+ ## Anti-Bot Protection
155
+
156
+ The `antibot` option uses curl-impersonate to mimic Chrome's TLS fingerprint:
157
+
158
+ - Bypass TLS fingerprinting protections (JA3/JA4) like Cloudflare
159
+ - Chrome 120 browser impersonation
160
+ - Proper header ordering and HTTP/2 settings
161
+ - Automatic gzip decompression
162
+
163
+ ```typescript
164
+ const res = await client.url.site.get({
165
+ antibot: true, // Enable for protected sites
166
+ });
167
+ ```
168
+
169
+ **Performance**: ~1-2s for first request, faster with connection reuse.
170
+
171
+ ## API Reference
172
+
173
+ ### `JirenClient`
174
+
175
+ ```typescript
176
+ // Constructor options
177
+ interface JirenClientOptions {
178
+ warmup: Record<string, string>; // Required! Map of key -> URL
179
+ }
180
+
181
+ // Create client (warmup is mandatory)
182
+ const client = new JirenClient({
183
+ warmup: {
184
+ api: "https://api.example.com",
185
+ cdn: "https://cdn.example.com",
186
+ },
187
+ });
188
+
189
+ // Type-safe URL access
190
+ client.url[key].get(options?)
191
+ client.url[key].post(body?, options?)
192
+ client.url[key].put(body?, options?)
193
+ client.url[key].patch(body?, options?)
194
+ client.url[key].delete(body?, options?)
195
+ client.url[key].head(options?)
196
+ client.url[key].options(options?)
197
+
198
+ // Cleanup
199
+ client.close()
200
+ ```
201
+
202
+ ### Request Options
69
203
 
70
204
  ```typescript
71
- // Prefetch connection (DNS + TLS Handshake)
72
- client.prefetch(["https://google.com", "https://cloudflare.com"]);
205
+ interface UrlRequestOptions {
206
+ path?: string; // Path to append to base URL
207
+ headers?: Record<string, string>;
208
+ maxRedirects?: number;
209
+ responseType?: "json" | "text" | "arraybuffer" | "blob";
210
+ antibot?: boolean; // Enable curl-impersonate (default: false)
211
+ }
212
+ ```
213
+
214
+ ### Response Object
73
215
 
74
- // ... later, requests are instant
75
- const res = client.get("https://google.com");
216
+ ```typescript
217
+ interface JirenResponse<T> {
218
+ status: number;
219
+ statusText: string;
220
+ headers: Record<string, string>;
221
+ ok: boolean;
222
+ body: {
223
+ text(): Promise<string>;
224
+ json<R = T>(): Promise<R>;
225
+ arrayBuffer(): Promise<ArrayBuffer>;
226
+ blob(): Promise<Blob>;
227
+ };
228
+ }
76
229
  ```
77
230
 
78
- ## Benchmarks
231
+ ## Performance
232
+
233
+ Benchmark results:
234
+
235
+ - **Bun fetch**: ~950-1780ms
236
+ - **JirenClient**: ~480-1630ms
79
237
 
80
- **jiren** delivers native performance by bypassing the JavaScript engine overhead for network I/O.
238
+ JirenClient is often **faster than Bun's native fetch** thanks to optimized connection pooling and native Zig implementation.
81
239
 
82
- | Client | Requests/sec | Relative Speed |
83
- | ----------------- | ------------- | -------------- |
84
- | **jiren** | **1,550,000** | **1.0x** |
85
- | Bun `fetch` | 45,000 | 34x Slower |
86
- | Node `http` | 32,000 | 48x Slower |
87
- | Python `requests` | 6,500 | 238x Slower |
240
+ ## License
88
241
 
89
- > Benchmarks run on MacBook Pro M3 Max, localhost loopback.
242
+ MIT