stream-axios 1.2.0 → 1.2.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 +43 -73
- package/README.zh-CN.md +47 -75
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ request
|
|
|
52
52
|
|
|
53
53
|
### 2. Streaming Request
|
|
54
54
|
|
|
55
|
-
Suitable for scenarios like receiving large files or AI conversation streams.
|
|
55
|
+
Suitable for scenarios like receiving large files or AI conversation streams. The `stream` method returns a **cancel function** that you can call to abort the request.
|
|
56
56
|
|
|
57
57
|
```javascript
|
|
58
58
|
import { createInstance } from "stream-axios";
|
|
@@ -79,13 +79,26 @@ const cancel = await request.stream(
|
|
|
79
79
|
},
|
|
80
80
|
);
|
|
81
81
|
|
|
82
|
-
//
|
|
83
|
-
|
|
82
|
+
// Cancel the stream manually when needed
|
|
83
|
+
cancel();
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Optional: use `AbortSignal`** to cancel from outside (e.g. React cleanup):
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
const controller = new AbortController();
|
|
90
|
+
await request.stream(
|
|
91
|
+
{ url: "/api/chat", signal: controller.signal },
|
|
92
|
+
onChunk,
|
|
93
|
+
onComplete,
|
|
94
|
+
onError,
|
|
95
|
+
);
|
|
96
|
+
// controller.abort(); // cancels the request
|
|
84
97
|
```
|
|
85
98
|
|
|
86
99
|
### 3. Custom Instance
|
|
87
100
|
|
|
88
|
-
|
|
101
|
+
`createInstance` merges your config with the default (timeout 15s, `Content-Type: application/json;charset=utf-8`). Override as needed:
|
|
89
102
|
|
|
90
103
|
```javascript
|
|
91
104
|
import { createInstance } from "stream-axios";
|
|
@@ -100,102 +113,59 @@ myRequest.interceptors.request.use((config) => {
|
|
|
100
113
|
config.headers["Authorization"] = "Bearer token";
|
|
101
114
|
return config;
|
|
102
115
|
});
|
|
103
|
-
|
|
104
|
-
// Use stream method
|
|
105
|
-
myRequest.stream({ url: "/stream" }, (chunk) => console.log(chunk));
|
|
106
116
|
```
|
|
107
117
|
|
|
108
|
-
### 4.
|
|
118
|
+
### 4. Attach Stream to Existing Axios Instance
|
|
109
119
|
|
|
110
|
-
If you
|
|
120
|
+
If you already have an axios instance, use `attachStream` to add the `stream` method without creating a new instance:
|
|
111
121
|
|
|
112
122
|
```javascript
|
|
113
|
-
import
|
|
123
|
+
import axios from "axios";
|
|
124
|
+
import { attachStream } from "stream-axios";
|
|
114
125
|
|
|
115
|
-
const
|
|
126
|
+
const instance = axios.create({ baseURL: "https://api.example.com" });
|
|
127
|
+
attachStream(instance);
|
|
116
128
|
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
parseSSEChunk(chunk, (content) => {
|
|
120
|
-
console.log("SSE Message:", content);
|
|
121
|
-
});
|
|
122
|
-
});
|
|
129
|
+
// instance.stream() is now available
|
|
130
|
+
const cancel = await instance.stream({ url: "/api/stream" }, onChunk, onComplete, onError);
|
|
123
131
|
```
|
|
124
132
|
|
|
125
|
-
|
|
133
|
+
### 5. Helper Functions
|
|
134
|
+
|
|
135
|
+
#### `createSSEParser` (stateful, handles split chunks)
|
|
136
|
+
|
|
137
|
+
Use for robust SSE parsing when chunks may be split across reads. Callback receives the full event object:
|
|
126
138
|
|
|
127
139
|
```javascript
|
|
128
140
|
import { createInstance, createSSEParser } from "stream-axios";
|
|
129
141
|
|
|
130
142
|
const request = createInstance();
|
|
131
143
|
|
|
132
|
-
// Create a stateful parser with buffer
|
|
133
144
|
const parser = createSSEParser((event) => {
|
|
134
|
-
// event
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
145
|
+
// event: { event?: string, data?: string, id?: string, retry?: number }
|
|
146
|
+
if (event.data) {
|
|
147
|
+
console.log("SSE Data:", event.data);
|
|
148
|
+
}
|
|
138
149
|
});
|
|
139
150
|
|
|
140
|
-
request.stream(
|
|
141
|
-
{ url: "/sse-
|
|
142
|
-
parser,
|
|
143
|
-
() => console.log("Completed"),
|
|
144
|
-
(error) => console.error("Error:", error),
|
|
151
|
+
await request.stream(
|
|
152
|
+
{ url: "/api/sse-stream" },
|
|
153
|
+
(chunk) => parser(chunk),
|
|
145
154
|
);
|
|
146
155
|
```
|
|
147
156
|
|
|
148
|
-
|
|
157
|
+
#### `parseSSEChunk` (stateless, full chunks only)
|
|
149
158
|
|
|
150
|
-
|
|
159
|
+
Use when you have a complete SSE text chunk and only need the data content. Callback receives each message's data string:
|
|
151
160
|
|
|
152
161
|
```javascript
|
|
153
|
-
import {
|
|
162
|
+
import { parseSSEChunk } from "stream-axios";
|
|
154
163
|
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
request.stream(
|
|
159
|
-
{
|
|
160
|
-
url: "/api/chat",
|
|
161
|
-
method: "POST",
|
|
162
|
-
data: { message: "Hello" },
|
|
163
|
-
signal: controller.signal, // Pass external signal
|
|
164
|
-
},
|
|
165
|
-
(chunk) => console.log(chunk),
|
|
166
|
-
() => console.log("Completed"),
|
|
167
|
-
(error) => console.error(error),
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
// Cancel from external controller
|
|
171
|
-
setTimeout(() => {
|
|
172
|
-
controller.abort();
|
|
173
|
-
}, 5000);
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
### 6. Use with Existing Axios Instance
|
|
177
|
-
|
|
178
|
-
If you already have a configured axios instance in your project, you can attach the stream method to it:
|
|
179
|
-
|
|
180
|
-
```javascript
|
|
181
|
-
import axios from "axios";
|
|
182
|
-
import { attachStream } from "stream-axios";
|
|
183
|
-
|
|
184
|
-
// Your existing axios instance
|
|
185
|
-
const myAxios = axios.create({
|
|
186
|
-
baseURL: "https://api.myproject.com",
|
|
187
|
-
headers: { "X-Custom-Header": "foobar" },
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
// Attach stream method
|
|
191
|
-
attachStream(myAxios);
|
|
192
|
-
|
|
193
|
-
// Now you can use .stream() on your instance
|
|
194
|
-
myAxios.stream({ url: "/chat" }, (chunk) => {
|
|
195
|
-
console.log(chunk);
|
|
164
|
+
const sseText = "data: hello\n\ndata: world\n\n";
|
|
165
|
+
parseSSEChunk(sseText, (data) => {
|
|
166
|
+
console.log("Message:", data); // "hello", then "world"
|
|
196
167
|
});
|
|
197
168
|
```
|
|
198
|
-
|
|
199
169
|
## License
|
|
200
170
|
|
|
201
171
|
MIT
|
package/README.zh-CN.md
CHANGED
|
@@ -52,10 +52,12 @@ request
|
|
|
52
52
|
|
|
53
53
|
### 2. 流式请求 (Streaming)
|
|
54
54
|
|
|
55
|
-
适用于接收大文件或 AI
|
|
55
|
+
适用于接收大文件或 AI 对话流等场景。`stream` 方法会返回一个**取消函数**,调用即可中止请求。
|
|
56
56
|
|
|
57
57
|
```javascript
|
|
58
|
-
import
|
|
58
|
+
import { createInstance } from "stream-axios";
|
|
59
|
+
|
|
60
|
+
const request = createInstance();
|
|
59
61
|
|
|
60
62
|
const cancel = await request.stream(
|
|
61
63
|
{
|
|
@@ -77,13 +79,26 @@ const cancel = await request.stream(
|
|
|
77
79
|
},
|
|
78
80
|
);
|
|
79
81
|
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
+
// 需要时手动取消流
|
|
83
|
+
cancel();
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**可选:使用 `AbortSignal`** 从外部取消(例如 React 清理时):
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
const controller = new AbortController();
|
|
90
|
+
await request.stream(
|
|
91
|
+
{ url: "/api/chat", signal: controller.signal },
|
|
92
|
+
onChunk,
|
|
93
|
+
onComplete,
|
|
94
|
+
onError,
|
|
95
|
+
);
|
|
96
|
+
// controller.abort(); // 取消请求
|
|
82
97
|
```
|
|
83
98
|
|
|
84
99
|
### 3. 自定义实例
|
|
85
100
|
|
|
86
|
-
|
|
101
|
+
`createInstance` 会将你的配置与默认配置(超时 15 秒、`Content-Type: application/json;charset=utf-8`)合并,可按需覆盖:
|
|
87
102
|
|
|
88
103
|
```javascript
|
|
89
104
|
import { createInstance } from "stream-axios";
|
|
@@ -98,106 +113,63 @@ myRequest.interceptors.request.use((config) => {
|
|
|
98
113
|
config.headers["Authorization"] = "Bearer token";
|
|
99
114
|
return config;
|
|
100
115
|
});
|
|
101
|
-
|
|
102
|
-
// 使用流式方法
|
|
103
|
-
myRequest.stream({ url: "/stream" }, (chunk) => console.log(chunk));
|
|
104
116
|
```
|
|
105
117
|
|
|
106
|
-
### 4.
|
|
118
|
+
### 4. 为已有 axios 实例挂载 stream
|
|
107
119
|
|
|
108
|
-
|
|
120
|
+
若已有 axios 实例,可用 `attachStream` 为其添加 `stream` 方法,无需新建实例:
|
|
109
121
|
|
|
110
122
|
```javascript
|
|
111
|
-
import
|
|
123
|
+
import axios from "axios";
|
|
124
|
+
import { attachStream } from "stream-axios";
|
|
112
125
|
|
|
113
|
-
const
|
|
126
|
+
const instance = axios.create({ baseURL: "https://api.example.com" });
|
|
127
|
+
attachStream(instance);
|
|
114
128
|
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
parseSSEChunk(chunk, (content) => {
|
|
118
|
-
console.log("SSE Message:", content);
|
|
119
|
-
});
|
|
120
|
-
});
|
|
129
|
+
// instance.stream() 现已可用
|
|
130
|
+
const cancel = await instance.stream({ url: "/api/stream" }, onChunk, onComplete, onError);
|
|
121
131
|
```
|
|
122
132
|
|
|
123
|
-
|
|
133
|
+
### 5. 辅助函数
|
|
134
|
+
|
|
135
|
+
#### `createSSEParser`(有状态,可处理分片)
|
|
136
|
+
|
|
137
|
+
当 SSE 数据可能被拆成多段时,用此解析器更稳妥。回调会收到完整事件对象:
|
|
124
138
|
|
|
125
139
|
```javascript
|
|
126
140
|
import { createInstance, createSSEParser } from "stream-axios";
|
|
127
141
|
|
|
128
142
|
const request = createInstance();
|
|
129
143
|
|
|
130
|
-
// 创建带缓冲区的有状态解析器
|
|
131
144
|
const parser = createSSEParser((event) => {
|
|
132
|
-
// event
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
145
|
+
// event: { event?: string, data?: string, id?: string, retry?: number }
|
|
146
|
+
if (event.data) {
|
|
147
|
+
console.log("SSE Data:", event.data);
|
|
148
|
+
}
|
|
136
149
|
});
|
|
137
150
|
|
|
138
|
-
request.stream(
|
|
139
|
-
{ url: "/sse-
|
|
140
|
-
parser,
|
|
141
|
-
() => console.log("完成"),
|
|
142
|
-
(error) => console.error("错误:", error),
|
|
143
|
-
);
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### 5. 使用外部 AbortSignal 取消请求
|
|
147
|
-
|
|
148
|
-
你可以传入外部的 `AbortSignal` 来控制流式请求:
|
|
149
|
-
|
|
150
|
-
```javascript
|
|
151
|
-
import { createInstance } from "stream-axios";
|
|
152
|
-
|
|
153
|
-
const request = createInstance();
|
|
154
|
-
const controller = new AbortController();
|
|
155
|
-
|
|
156
|
-
request.stream(
|
|
157
|
-
{
|
|
158
|
-
url: "/api/chat",
|
|
159
|
-
method: "POST",
|
|
160
|
-
data: { message: "Hello" },
|
|
161
|
-
signal: controller.signal, // 传入外部信号
|
|
162
|
-
},
|
|
163
|
-
(chunk) => console.log(chunk),
|
|
164
|
-
() => console.log("完成"),
|
|
165
|
-
(error) => console.error(error),
|
|
151
|
+
await request.stream(
|
|
152
|
+
{ url: "/api/sse-stream" },
|
|
153
|
+
(chunk) => parser(chunk),
|
|
166
154
|
);
|
|
167
|
-
|
|
168
|
-
// 从外部控制器取消请求
|
|
169
|
-
setTimeout(() => {
|
|
170
|
-
controller.abort();
|
|
171
|
-
}, 5000);
|
|
172
155
|
```
|
|
173
156
|
|
|
174
|
-
|
|
157
|
+
#### `parseSSEChunk`(无状态,仅完整块)
|
|
175
158
|
|
|
176
|
-
|
|
159
|
+
当已有完整的一段 SSE 文本且只需取出 data 内容时使用。回调仅接收每条消息的 data 字符串:
|
|
177
160
|
|
|
178
161
|
```javascript
|
|
179
|
-
import
|
|
180
|
-
import { attachStream } from "stream-axios";
|
|
162
|
+
import { parseSSEChunk } from "stream-axios";
|
|
181
163
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
headers: { "X-Custom-Header": "foobar" },
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
// 挂载 stream 方法
|
|
189
|
-
attachStream(myAxios);
|
|
190
|
-
|
|
191
|
-
// 现在你可以在实例上使用 .stream() 方法了
|
|
192
|
-
myAxios.stream({ url: "/chat" }, (chunk) => {
|
|
193
|
-
console.log(chunk);
|
|
164
|
+
const sseText = "data: hello\n\ndata: world\n\n";
|
|
165
|
+
parseSSEChunk(sseText, (data) => {
|
|
166
|
+
console.log("Message:", data); // "hello", 然后 "world"
|
|
194
167
|
});
|
|
195
168
|
```
|
|
196
|
-
|
|
197
169
|
## License
|
|
198
170
|
|
|
199
171
|
MIT
|
|
200
172
|
|
|
201
173
|
## 致谢
|
|
202
174
|
|
|
203
|
-
本项目基于 [Axios](https://github.com/axios/axios)
|
|
175
|
+
本项目基于 [Axios](https://github.com/axios/axios) 开发
|