jiren 1.0.13 → 1.0.15

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 (3) hide show
  1. package/dist/index.js +182 -0
  2. package/package.json +11 -8
  3. package/index.ts +0 -29
package/dist/index.js ADDED
@@ -0,0 +1,182 @@
1
+ // @bun
2
+ // components/client.ts
3
+ import { CString } from "bun:ffi";
4
+
5
+ // components/native.ts
6
+ import { dlopen, FFIType, suffix } from "bun:ffi";
7
+ import { join } from "path";
8
+ var libPath = join(import.meta.dir, `../lib/libhttpclient.${suffix}`);
9
+ var ffiDef = {
10
+ zclient_new: {
11
+ args: [],
12
+ returns: FFIType.ptr
13
+ },
14
+ zclient_free: {
15
+ args: [FFIType.ptr],
16
+ returns: FFIType.void
17
+ },
18
+ zclient_get: {
19
+ args: [FFIType.ptr, FFIType.cstring],
20
+ returns: FFIType.ptr
21
+ },
22
+ zclient_post: {
23
+ args: [FFIType.ptr, FFIType.cstring, FFIType.cstring],
24
+ returns: FFIType.ptr
25
+ },
26
+ zclient_prefetch: {
27
+ args: [FFIType.ptr, FFIType.cstring],
28
+ returns: FFIType.void
29
+ },
30
+ zclient_response_status: {
31
+ args: [FFIType.ptr],
32
+ returns: FFIType.u16
33
+ },
34
+ zclient_response_body: {
35
+ args: [FFIType.ptr],
36
+ returns: FFIType.ptr
37
+ },
38
+ zclient_response_body_len: {
39
+ args: [FFIType.ptr],
40
+ returns: FFIType.u64
41
+ },
42
+ zclient_response_headers: {
43
+ args: [FFIType.ptr],
44
+ returns: FFIType.ptr
45
+ },
46
+ zclient_response_headers_len: {
47
+ args: [FFIType.ptr],
48
+ returns: FFIType.u64
49
+ },
50
+ zclient_response_free: {
51
+ args: [FFIType.ptr],
52
+ returns: FFIType.void
53
+ },
54
+ zclient_request: {
55
+ args: [
56
+ FFIType.ptr,
57
+ FFIType.cstring,
58
+ FFIType.cstring,
59
+ FFIType.cstring,
60
+ FFIType.cstring
61
+ ],
62
+ returns: FFIType.ptr
63
+ }
64
+ };
65
+ var lib = dlopen(libPath, ffiDef);
66
+
67
+ // components/client.ts
68
+ class JirenClient {
69
+ ptr;
70
+ constructor() {
71
+ this.ptr = lib.symbols.zclient_new();
72
+ if (!this.ptr)
73
+ throw new Error("Failed to create native client instance");
74
+ }
75
+ close() {
76
+ if (this.ptr) {
77
+ lib.symbols.zclient_free(this.ptr);
78
+ this.ptr = null;
79
+ }
80
+ }
81
+ request(url, options = {}) {
82
+ if (!this.ptr)
83
+ throw new Error("Client is closed");
84
+ const method = options.method || "GET";
85
+ const methodBuffer = Buffer.from(method + "\x00");
86
+ const urlBuffer = Buffer.from(url + "\x00");
87
+ let headersBuffer = null;
88
+ if (options.headers) {
89
+ const headerStr = Object.entries(options.headers).map(([k, v]) => `${k.toLowerCase()}: ${v}`).join(`\r
90
+ `);
91
+ if (headerStr.length > 0) {
92
+ headersBuffer = Buffer.from(headerStr + "\x00");
93
+ }
94
+ }
95
+ let bodyBuffer = null;
96
+ if (options.body) {
97
+ const bodyStr = typeof options.body === "string" ? options.body : JSON.stringify(options.body);
98
+ bodyBuffer = Buffer.from(bodyStr + "\x00");
99
+ }
100
+ const respPtr = lib.symbols.zclient_request(this.ptr, methodBuffer, urlBuffer, headersBuffer, bodyBuffer);
101
+ const response = this.parseResponse(respPtr);
102
+ if (options.maxRedirects && options.maxRedirects > 0 && response.status >= 300 && response.status < 400 && response.headers && response.headers["location"]) {
103
+ const location = response.headers["location"];
104
+ const newUrl = new URL(location, url).toString();
105
+ const newOptions = { ...options, maxRedirects: options.maxRedirects - 1 };
106
+ return this.request(newUrl, newOptions);
107
+ }
108
+ return response;
109
+ }
110
+ get(url, options = {}) {
111
+ return this.request(url, { ...options, method: "GET" });
112
+ }
113
+ post(url, body, options = {}) {
114
+ return this.request(url, { ...options, method: "POST", body });
115
+ }
116
+ put(url, body, options = {}) {
117
+ return this.request(url, { ...options, method: "PUT", body });
118
+ }
119
+ delete(url, options = {}) {
120
+ return this.request(url, { ...options, method: "DELETE" });
121
+ }
122
+ patch(url, body, options = {}) {
123
+ return this.request(url, { ...options, method: "PATCH", body });
124
+ }
125
+ head(url, options = {}) {
126
+ return this.request(url, { ...options, method: "HEAD" });
127
+ }
128
+ prefetch(urls) {
129
+ if (!this.ptr)
130
+ throw new Error("Client is closed");
131
+ for (const url of urls) {
132
+ const urlBuffer = Buffer.from(url + "\x00");
133
+ lib.symbols.zclient_prefetch(this.ptr, urlBuffer);
134
+ }
135
+ }
136
+ parseResponse(respPtr) {
137
+ if (!respPtr)
138
+ throw new Error("Native request failed (returned null pointer)");
139
+ try {
140
+ const status = lib.symbols.zclient_response_status(respPtr);
141
+ const bodyLen = Number(lib.symbols.zclient_response_body_len(respPtr));
142
+ const bodyPtr = lib.symbols.zclient_response_body(respPtr);
143
+ const headersLen = Number(lib.symbols.zclient_response_headers_len(respPtr));
144
+ const headersPtr = lib.symbols.zclient_response_headers(respPtr);
145
+ let bodyString = "";
146
+ if (bodyLen > 0 && bodyPtr) {
147
+ bodyString = new CString(bodyPtr).toString();
148
+ }
149
+ const headers = {};
150
+ if (headersLen > 0 && headersPtr) {
151
+ const headersStr = new CString(headersPtr).toString();
152
+ const lines = headersStr.split(`\r
153
+ `);
154
+ for (const line of lines) {
155
+ if (!line)
156
+ continue;
157
+ const colonIdx = line.indexOf(":");
158
+ if (colonIdx !== -1) {
159
+ const key = line.substring(0, colonIdx).trim().toLowerCase();
160
+ const val = line.substring(colonIdx + 1).trim();
161
+ headers[key] = val;
162
+ }
163
+ }
164
+ }
165
+ return {
166
+ status,
167
+ body: bodyString,
168
+ headers,
169
+ json: () => {
170
+ if (!bodyString)
171
+ return null;
172
+ return JSON.parse(bodyString);
173
+ }
174
+ };
175
+ } finally {
176
+ lib.symbols.zclient_response_free(respPtr);
177
+ }
178
+ }
179
+ }
180
+ export {
181
+ JirenClient
182
+ };
package/package.json CHANGED
@@ -1,22 +1,23 @@
1
1
  {
2
2
  "name": "jiren",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "author": "",
5
- "main": "index.ts",
6
- "module": "index.ts",
7
- "types": "index.ts",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
+ "types": "types/index.ts",
8
8
  "devDependencies": {
9
- "@types/bun": "^1.3.4"
9
+ "@types/bun": "^1.3.4",
10
+ "bun-types": "^1.3.4"
10
11
  },
11
12
  "peerDependencies": {
12
13
  "typescript": "^5"
13
14
  },
14
15
  "description": "Jiren is a high-performance HTTP/HTTPS client, Faster than any other HTTP/HTTPS client.",
15
16
  "files": [
16
- "index.ts",
17
- "types",
17
+ "dist",
18
18
  "lib",
19
- "components"
19
+ "components",
20
+ "types"
20
21
  ],
21
22
  "keywords": [
22
23
  "http",
@@ -33,6 +34,8 @@
33
34
  "license": "MIT",
34
35
  "scripts": {
35
36
  "build:zig": "cd .. && zig build --release=fast",
37
+ "build": "bun build ./index.ts --outdir dist --target bun",
38
+ "prepare": "bun run build",
36
39
  "test": "bun run examples/basic.ts"
37
40
  },
38
41
  "engines": {
package/index.ts DELETED
@@ -1,29 +0,0 @@
1
- /**
2
- * jiren - Ultra-fast HTTP/HTTPS client powered by native Zig
3
- *
4
- * Faster than any other HTTP/HTTPS client | 1.5M+ requests/sec
5
- *
6
- * @example
7
- * ```typescript
8
- * import { JirenClient } from 'jiren';
9
- *
10
- * const client = new JirenClient();
11
- *
12
- * // High-performance batch requests
13
- * const result = client.batch('http://localhost:3000/', {
14
- * count: 10000,
15
- * threads: 100
16
- * });
17
- *
18
- * console.log(`Success: ${result.success}/${result.total}`);
19
- * console.log(`Speed: ${result.requestsPerSecond.toFixed(0)} req/sec`);
20
- * ```
21
- *
22
- * @packageDocumentation
23
- */
24
-
25
- // Main client
26
- export { JirenClient } from "./components";
27
-
28
- // Types
29
- export * from "./types";