httix-http 1.0.0 → 1.0.1
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 +32 -32
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<img src="https://img.shields.io/badge/coverage-100%25-success?style=flat-square" alt="100% Coverage" />
|
|
8
8
|
</p>
|
|
9
9
|
|
|
10
|
-
<h1 align="center">httix</h1>
|
|
10
|
+
<h1 align="center">httix-http</h1>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
13
|
<strong>Ultra-lightweight, type-safe, zero-dependency HTTP client built on native Fetch.</strong><br/>
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
## Why httix?
|
|
19
|
+
## Why httix-http?
|
|
20
20
|
|
|
21
|
-
| Feature | **httix** | axios | got | ky | ofetch |
|
|
21
|
+
| Feature | **httix-http** | axios | got | ky | ofetch |
|
|
22
22
|
|---|---|---|---|---|---|
|
|
23
23
|
| Dependencies | **0** | 2 | 11 | 2 | 5 |
|
|
24
24
|
| Size (min+gzip) | **~5 kB** | ~28 kB | ~67 kB | ~9 kB | ~12 kB |
|
|
@@ -84,7 +84,7 @@ console.log(data.id); // created user id
|
|
|
84
84
|
### 3. Create a configured client
|
|
85
85
|
|
|
86
86
|
```ts
|
|
87
|
-
import { createHttix } from 'httix';
|
|
87
|
+
import { createHttix } from 'httix-http';
|
|
88
88
|
|
|
89
89
|
const api = createHttix({
|
|
90
90
|
baseURL: 'https://api.example.com',
|
|
@@ -98,7 +98,7 @@ const { data } = await api.get('/users/me');
|
|
|
98
98
|
### 4. Error handling
|
|
99
99
|
|
|
100
100
|
```ts
|
|
101
|
-
import httix, { HttixResponseError, HttixTimeoutError, HttixAbortError } from 'httix';
|
|
101
|
+
import httix, { HttixResponseError, HttixTimeoutError, HttixAbortError } from 'httix-http';
|
|
102
102
|
|
|
103
103
|
try {
|
|
104
104
|
const { data } = await httix.get('/users/999');
|
|
@@ -117,7 +117,7 @@ try {
|
|
|
117
117
|
### 5. Streaming SSE events
|
|
118
118
|
|
|
119
119
|
```ts
|
|
120
|
-
import httix from 'httix';
|
|
120
|
+
import httix from 'httix-http';
|
|
121
121
|
|
|
122
122
|
for await (const event of httix.stream.sse('/events')) {
|
|
123
123
|
console.log(`[${event.type}] ${event.data}`);
|
|
@@ -136,7 +136,7 @@ for await (const event of httix.stream.sse('/events')) {
|
|
|
136
136
|
Create a new client instance with the given configuration. This is the recommended entry-point for creating dedicated API clients.
|
|
137
137
|
|
|
138
138
|
```ts
|
|
139
|
-
import { createHttix } from 'httix';
|
|
139
|
+
import { createHttix } from 'httix-http';
|
|
140
140
|
|
|
141
141
|
const api = createHttix({
|
|
142
142
|
baseURL: 'https://api.example.com/v2',
|
|
@@ -157,7 +157,7 @@ const { data } = await api.get('/users');
|
|
|
157
157
|
Create a derived client from the default instance, merging new configuration with the defaults:
|
|
158
158
|
|
|
159
159
|
```ts
|
|
160
|
-
import httix from 'httix';
|
|
160
|
+
import httix from 'httix-http';
|
|
161
161
|
|
|
162
162
|
const adminApi = httix.create({
|
|
163
163
|
baseURL: 'https://admin.api.example.com',
|
|
@@ -170,7 +170,7 @@ const adminApi = httix.create({
|
|
|
170
170
|
A pre-configured default instance is exported for convenience:
|
|
171
171
|
|
|
172
172
|
```ts
|
|
173
|
-
import httix from 'httix';
|
|
173
|
+
import httix from 'httix-http';
|
|
174
174
|
|
|
175
175
|
// Use directly
|
|
176
176
|
await httix.get('/users');
|
|
@@ -361,7 +361,7 @@ httix.interceptors.request.clear();
|
|
|
361
361
|
Automatic retry with configurable backoff strategies is built-in and enabled by default.
|
|
362
362
|
|
|
363
363
|
```ts
|
|
364
|
-
import { createHttix } from 'httix';
|
|
364
|
+
import { createHttix } from 'httix-http';
|
|
365
365
|
|
|
366
366
|
const client = createHttix({
|
|
367
367
|
baseURL: 'https://api.example.com',
|
|
@@ -452,7 +452,7 @@ try {
|
|
|
452
452
|
Stream SSE events as an async iterable:
|
|
453
453
|
|
|
454
454
|
```ts
|
|
455
|
-
import httix from 'httix';
|
|
455
|
+
import httix from 'httix-http';
|
|
456
456
|
|
|
457
457
|
for await (const event of httix.stream.sse('https://api.example.com/events', {
|
|
458
458
|
headers: { 'Accept': 'text/event-stream' },
|
|
@@ -472,7 +472,7 @@ for await (const event of httix.stream.sse('https://api.example.com/events', {
|
|
|
472
472
|
Stream newline-delimited JSON objects:
|
|
473
473
|
|
|
474
474
|
```ts
|
|
475
|
-
import httix from 'httix';
|
|
475
|
+
import httix from 'httix-http';
|
|
476
476
|
|
|
477
477
|
interface LogEntry {
|
|
478
478
|
timestamp: string;
|
|
@@ -490,7 +490,7 @@ for await (const entry of httix.stream.ndjson<LogEntry>('/logs/stream')) {
|
|
|
490
490
|
Automatically deduplicate identical in-flight requests. When enabled, if multiple calls are made with the same config before the first resolves, they share the same promise.
|
|
491
491
|
|
|
492
492
|
```ts
|
|
493
|
-
import { createHttix } from 'httix';
|
|
493
|
+
import { createHttix } from 'httix-http';
|
|
494
494
|
|
|
495
495
|
const client = createHttix({
|
|
496
496
|
baseURL: 'https://api.example.com',
|
|
@@ -518,7 +518,7 @@ const client2 = createHttix({
|
|
|
518
518
|
Client-side rate limiting to avoid overwhelming APIs:
|
|
519
519
|
|
|
520
520
|
```ts
|
|
521
|
-
import { createHttix } from 'httix';
|
|
521
|
+
import { createHttix } from 'httix-http';
|
|
522
522
|
|
|
523
523
|
const client = createHttix({
|
|
524
524
|
baseURL: 'https://rate-limited-api.example.com',
|
|
@@ -542,7 +542,7 @@ const results = await Promise.all([
|
|
|
542
542
|
Middleware functions have access to both the request and response, and can modify either:
|
|
543
543
|
|
|
544
544
|
```ts
|
|
545
|
-
import httix, { type MiddlewareFn, type MiddlewareContext } from 'httix';
|
|
545
|
+
import httix, { type MiddlewareFn, type MiddlewareContext } from 'httix-http';
|
|
546
546
|
|
|
547
547
|
// Timing middleware
|
|
548
548
|
const timingMiddleware: MiddlewareFn = async (ctx, next) => {
|
|
@@ -576,7 +576,7 @@ const client = httix.create({
|
|
|
576
576
|
#### Bearer Auth
|
|
577
577
|
|
|
578
578
|
```ts
|
|
579
|
-
import { createHttix } from 'httix';
|
|
579
|
+
import { createHttix } from 'httix-http';
|
|
580
580
|
|
|
581
581
|
// Static token
|
|
582
582
|
const client = createHttix({
|
|
@@ -647,7 +647,7 @@ const client2 = createHttix({
|
|
|
647
647
|
Automatically fetch all pages of a paginated resource:
|
|
648
648
|
|
|
649
649
|
```ts
|
|
650
|
-
import { createHttix } from 'httix';
|
|
650
|
+
import { createHttix } from 'httix-http';
|
|
651
651
|
|
|
652
652
|
const client = createHttix({ baseURL: 'https://api.example.com' });
|
|
653
653
|
```
|
|
@@ -761,8 +761,8 @@ const { data: repo } = await httix.get('/repos/:owner/:repo', {
|
|
|
761
761
|
Plugins extend httix by registering interceptors and lifecycle hooks. Import them from `httix/plugins`.
|
|
762
762
|
|
|
763
763
|
```ts
|
|
764
|
-
import { loggerPlugin, cachePlugin, mockPlugin } from 'httix/plugins';
|
|
765
|
-
import { createHttix } from 'httix';
|
|
764
|
+
import { loggerPlugin, cachePlugin, mockPlugin } from 'httix-http/plugins';
|
|
765
|
+
import { createHttix } from 'httix-http';
|
|
766
766
|
|
|
767
767
|
const client = createHttix({ baseURL: 'https://api.example.com' });
|
|
768
768
|
|
|
@@ -776,8 +776,8 @@ const logger = loggerPlugin({ level: 'debug' });
|
|
|
776
776
|
LRU response cache with configurable TTL, stale-while-revalidate, and size limits:
|
|
777
777
|
|
|
778
778
|
```ts
|
|
779
|
-
import { cachePlugin } from 'httix/plugins';
|
|
780
|
-
import { createHttix } from 'httix';
|
|
779
|
+
import { cachePlugin } from 'httix-http/plugins';
|
|
780
|
+
import { createHttix } from 'httix-http';
|
|
781
781
|
|
|
782
782
|
const client = createHttix({ baseURL: 'https://api.example.com' });
|
|
783
783
|
|
|
@@ -802,8 +802,8 @@ console.log(cache.getStats()); // { size: 12, maxSize: 200, ttl: 300000
|
|
|
802
802
|
Structured logging of request/response lifecycle events:
|
|
803
803
|
|
|
804
804
|
```ts
|
|
805
|
-
import { loggerPlugin } from 'httix/plugins';
|
|
806
|
-
import { createHttix } from 'httix';
|
|
805
|
+
import { loggerPlugin } from 'httix-http/plugins';
|
|
806
|
+
import { createHttix } from 'httix-http';
|
|
807
807
|
|
|
808
808
|
const client = createHttix({ baseURL: 'https://api.example.com' });
|
|
809
809
|
|
|
@@ -827,8 +827,8 @@ loggerPlugin({
|
|
|
827
827
|
Replace `fetch` with an in-memory mock adapter — perfect for unit tests:
|
|
828
828
|
|
|
829
829
|
```ts
|
|
830
|
-
import { mockPlugin } from 'httix/plugins';
|
|
831
|
-
import { createHttix } from 'httix';
|
|
830
|
+
import { mockPlugin } from 'httix-http/plugins';
|
|
831
|
+
import { createHttix } from 'httix-http';
|
|
832
832
|
|
|
833
833
|
const mock = mockPlugin();
|
|
834
834
|
const client = createHttix({ baseURL: 'https://api.example.com' });
|
|
@@ -868,8 +868,8 @@ mock.restore();
|
|
|
868
868
|
|
|
869
869
|
```ts
|
|
870
870
|
import { describe, it, expect, afterEach } from 'vitest';
|
|
871
|
-
import { mockPlugin } from 'httix/plugins';
|
|
872
|
-
import { createHttix } from 'httix';
|
|
871
|
+
import { mockPlugin } from 'httix-http/plugins';
|
|
872
|
+
import { createHttix } from 'httix-http';
|
|
873
873
|
|
|
874
874
|
describe('Users API', () => {
|
|
875
875
|
const mock = mockPlugin();
|
|
@@ -924,7 +924,7 @@ import {
|
|
|
924
924
|
HttixTimeoutError,
|
|
925
925
|
HttixAbortError,
|
|
926
926
|
HttixRetryError,
|
|
927
|
-
} from 'httix';
|
|
927
|
+
} from 'httix-http';
|
|
928
928
|
|
|
929
929
|
try {
|
|
930
930
|
await httix.get('/unstable-endpoint');
|
|
@@ -999,7 +999,7 @@ const { data: user } = await httix.post<User>('/users', { name: 'Jane' });
|
|
|
999
999
|
#### Typing request config
|
|
1000
1000
|
|
|
1001
1001
|
```ts
|
|
1002
|
-
import type { HttixRequestConfig, HttixResponse, RetryConfig } from 'httix';
|
|
1002
|
+
import type { HttixRequestConfig, HttixResponse, RetryConfig } from 'httix-http';
|
|
1003
1003
|
|
|
1004
1004
|
const config: HttixRequestConfig = {
|
|
1005
1005
|
url: '/users',
|
|
@@ -1016,7 +1016,7 @@ const config: HttixRequestConfig = {
|
|
|
1016
1016
|
#### Typing middleware
|
|
1017
1017
|
|
|
1018
1018
|
```ts
|
|
1019
|
-
import type { MiddlewareFn, MiddlewareContext, HttixResponse } from 'httix';
|
|
1019
|
+
import type { MiddlewareFn, MiddlewareContext, HttixResponse } from 'httix-http';
|
|
1020
1020
|
|
|
1021
1021
|
const myMiddleware: MiddlewareFn<User, HttixRequestConfig, HttixResponse<User>> = async (
|
|
1022
1022
|
ctx: MiddlewareContext<HttixRequestConfig, HttixResponse<User>>,
|
|
@@ -1034,7 +1034,7 @@ const myMiddleware: MiddlewareFn<User, HttixRequestConfig, HttixResponse<User>>
|
|
|
1034
1034
|
#### Typing plugins
|
|
1035
1035
|
|
|
1036
1036
|
```ts
|
|
1037
|
-
import type { HttixPlugin } from 'httix';
|
|
1037
|
+
import type { HttixPlugin } from 'httix-http';
|
|
1038
1038
|
|
|
1039
1039
|
const myPlugin: HttixPlugin = {
|
|
1040
1040
|
name: 'my-plugin',
|
|
@@ -1061,7 +1061,7 @@ import axios from 'axios';
|
|
|
1061
1061
|
const { data } = await axios.get('/users');
|
|
1062
1062
|
|
|
1063
1063
|
// httix
|
|
1064
|
-
import httix from 'httix';
|
|
1064
|
+
import httix from 'httix-http';
|
|
1065
1065
|
const { data } = await httix.get('/users');
|
|
1066
1066
|
```
|
|
1067
1067
|
|