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.
Files changed (3) hide show
  1. package/README.md +43 -73
  2. package/README.zh-CN.md +47 -75
  3. 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
- // If you need to cancel the request
83
- // cancel();
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
- If you need independent configuration or interceptors:
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. SSE Parsing Helper
118
+ ### 4. Attach Stream to Existing Axios Instance
109
119
 
110
- If you are handling SSE (Server-Sent Events) format data:
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 { createInstance, parseSSEChunk } from "stream-axios";
123
+ import axios from "axios";
124
+ import { attachStream } from "stream-axios";
114
125
 
115
- const request = createInstance();
126
+ const instance = axios.create({ baseURL: "https://api.example.com" });
127
+ attachStream(instance);
116
128
 
117
- // Simple usage - parse data field only
118
- request.stream({ url: "/sse-endpoint", method: "GET" }, (chunk) => {
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
- For production environments, use `createSSEParser` which handles chunks that may be split across multiple packets:
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 object contains: { event?, data?, id?, retry? }
135
- console.log("Event type:", event.event);
136
- console.log("Data:", event.data);
137
- console.log("ID:", event.id);
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-endpoint", method: "GET" },
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
- ### 5. Cancel with External AbortSignal
157
+ #### `parseSSEChunk` (stateless, full chunks only)
149
158
 
150
- You can pass an external `AbortSignal` to control the stream request:
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 { createInstance } from "stream-axios";
162
+ import { parseSSEChunk } from "stream-axios";
154
163
 
155
- const request = createInstance();
156
- const controller = new AbortController();
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 request from "stream-axios";
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
- // cancel();
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. SSE 解析助手
118
+ ### 4. 为已有 axios 实例挂载 stream
107
119
 
108
- 如果你处理的是 SSE (Server-Sent Events) 格式的数据:
120
+ 若已有 axios 实例,可用 `attachStream` 为其添加 `stream` 方法,无需新建实例:
109
121
 
110
122
  ```javascript
111
- import { createInstance, parseSSEChunk } from "stream-axios";
123
+ import axios from "axios";
124
+ import { attachStream } from "stream-axios";
112
125
 
113
- const request = createInstance();
126
+ const instance = axios.create({ baseURL: "https://api.example.com" });
127
+ attachStream(instance);
114
128
 
115
- // 简单用法 - 仅解析 data 字段
116
- request.stream({ url: "/sse-endpoint", method: "GET" }, (chunk) => {
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
- 对于生产环境,建议使用 `createSSEParser`,它可以处理跨数据包拆分的 chunk:
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 对象包含: { event?, data?, id?, retry? }
133
- console.log("事件类型:", event.event);
134
- console.log("数据:", event.data);
135
- console.log("ID:", event.id);
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-endpoint", method: "GET" },
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
- ### 6. 使用现有的 Axios 实例
157
+ #### `parseSSEChunk`(无状态,仅完整块)
175
158
 
176
- 如果你项目中已经有了配置好的 axios 实例,你可以将 stream 方法挂载到该实例上:
159
+ 当已有完整的一段 SSE 文本且只需取出 data 内容时使用。回调仅接收每条消息的 data 字符串:
177
160
 
178
161
  ```javascript
179
- import axios from "axios";
180
- import { attachStream } from "stream-axios";
162
+ import { parseSSEChunk } from "stream-axios";
181
163
 
182
- // 你现有的 axios 实例
183
- const myAxios = axios.create({
184
- baseURL: "https://api.myproject.com",
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) 开发
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stream-axios",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "二次封装 axios,保留原始配置,提供流式接口,提升开发效率",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",