@ahoo-wang/fetcher-eventstream 0.3.8 → 0.5.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 +92 -87
- package/README.zh-CN.md +87 -87
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -6,39 +6,35 @@
|
|
|
6
6
|
[](https://github.com/Ahoo-Wang/fetcher/blob/main/LICENSE)
|
|
7
7
|
[](https://www.npmjs.com/package/@ahoo-wang/fetcher-eventstream)
|
|
8
8
|
|
|
9
|
-
Support for text/event-stream in Fetcher, enabling Server-Sent Events (SSE) functionality.
|
|
9
|
+
Support for text/event-stream in Fetcher, enabling Server-Sent Events (SSE) functionality for real-time data streaming.
|
|
10
10
|
|
|
11
|
-
## Features
|
|
11
|
+
## 🌟 Features
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
-
|
|
13
|
+
- **📡 Event Stream Conversion**: Converts `text/event-stream` responses to async generators of `ServerSentEvent` objects
|
|
14
|
+
- **🔌 Interceptor Integration**: Automatically adds `eventStream()` method to responses with `text/event-stream` content
|
|
15
|
+
type
|
|
16
|
+
- **📋 SSE Parsing**: Parses Server-Sent Events according to the specification, including data, event, id, and retry
|
|
17
|
+
fields
|
|
18
|
+
- **🔄 Streaming Support**: Handles chunked data and multi-line events correctly
|
|
19
|
+
- **💬 Comment Handling**: Properly ignores comment lines (lines starting with `:`) as per SSE specification
|
|
20
|
+
- **🛡️ TypeScript Support**: Complete TypeScript type definitions
|
|
21
|
+
- **⚡ Performance Optimized**: Efficient parsing and streaming for high-performance applications
|
|
19
22
|
|
|
20
|
-
##
|
|
23
|
+
## 🚀 Quick Start
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
pnpm add @ahoo-wang/fetcher-eventstream
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Using npm:
|
|
25
|
+
### Installation
|
|
29
26
|
|
|
30
27
|
```bash
|
|
28
|
+
# Using npm
|
|
31
29
|
npm install @ahoo-wang/fetcher-eventstream
|
|
32
|
-
```
|
|
33
30
|
|
|
34
|
-
Using
|
|
31
|
+
# Using pnpm
|
|
32
|
+
pnpm add @ahoo-wang/fetcher-eventstream
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
# Using yarn
|
|
37
35
|
yarn add @ahoo-wang/fetcher-eventstream
|
|
38
36
|
```
|
|
39
37
|
|
|
40
|
-
## Usage
|
|
41
|
-
|
|
42
38
|
### Basic Usage with Interceptor
|
|
43
39
|
|
|
44
40
|
```typescript
|
|
@@ -83,70 +79,36 @@ try {
|
|
|
83
79
|
}
|
|
84
80
|
```
|
|
85
81
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
import { Fetcher } from '@ahoo-wang/fetcher';
|
|
90
|
-
import { EventStreamInterceptor } from '@ahoo-wang/fetcher-eventstream';
|
|
91
|
-
|
|
92
|
-
const fetcher = new Fetcher({
|
|
93
|
-
baseURL: 'https://api.example.com',
|
|
94
|
-
interceptors: {
|
|
95
|
-
response: [new EventStreamInterceptor()],
|
|
96
|
-
},
|
|
97
|
-
});
|
|
82
|
+
## 📚 API Reference
|
|
98
83
|
|
|
99
|
-
|
|
100
|
-
const response = await fetcher.get('/events');
|
|
101
|
-
if (response.eventStream) {
|
|
102
|
-
for await (const event of response.eventStream()) {
|
|
103
|
-
switch (event.event) {
|
|
104
|
-
case 'message':
|
|
105
|
-
console.log('Message:', event.data);
|
|
106
|
-
break;
|
|
107
|
-
case 'notification':
|
|
108
|
-
console.log('Notification:', event.data);
|
|
109
|
-
break;
|
|
110
|
-
default:
|
|
111
|
-
console.log('Unknown event:', event);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
```
|
|
84
|
+
### EventStreamInterceptor
|
|
116
85
|
|
|
117
|
-
|
|
86
|
+
A response interceptor that automatically adds an `eventStream()` method to responses with `text/event-stream` content
|
|
87
|
+
type.
|
|
118
88
|
|
|
119
|
-
|
|
89
|
+
#### Usage
|
|
120
90
|
|
|
121
|
-
|
|
91
|
+
```typescript
|
|
92
|
+
fetcher.interceptors.response.use(new EventStreamInterceptor());
|
|
93
|
+
```
|
|
122
94
|
|
|
123
|
-
|
|
95
|
+
### toServerSentEventStream
|
|
124
96
|
|
|
125
97
|
Converts a Response object with a `text/event-stream` body to a readable stream of ServerSentEvent objects.
|
|
126
98
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
- `response`: The HTTP response with `text/event-stream` content type
|
|
130
|
-
|
|
131
|
-
**Returns:**
|
|
132
|
-
|
|
133
|
-
- `ServerEventStream`: A readable stream of ServerSentEvent objects
|
|
99
|
+
#### Signature
|
|
134
100
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
#### `intercept(exchange: FetchExchange): FetchExchange`
|
|
140
|
-
|
|
141
|
-
Intercepts a response and adds the `eventStream()` method if the content type is `text/event-stream`.
|
|
101
|
+
```typescript
|
|
102
|
+
function toServerSentEventStream(response: Response): ServerSentEventStream;
|
|
103
|
+
```
|
|
142
104
|
|
|
143
|
-
|
|
105
|
+
#### Parameters
|
|
144
106
|
|
|
145
|
-
- `
|
|
107
|
+
- `response`: The HTTP response with `text/event-stream` content type
|
|
146
108
|
|
|
147
|
-
|
|
109
|
+
#### Returns
|
|
148
110
|
|
|
149
|
-
- `
|
|
111
|
+
- `ServerSentEventStream`: A readable stream of ServerSentEvent objects
|
|
150
112
|
|
|
151
113
|
### ServerSentEvent
|
|
152
114
|
|
|
@@ -169,18 +131,7 @@ Type alias for a readable stream of ServerSentEvent objects.
|
|
|
169
131
|
type ServerSentEventStream = ReadableStream<ServerSentEvent>;
|
|
170
132
|
```
|
|
171
133
|
|
|
172
|
-
##
|
|
173
|
-
|
|
174
|
-
This package fully implements the [Server-Sent Events specification](https://html.spec.whatwg.org/multipage/server-sent-events.html):
|
|
175
|
-
|
|
176
|
-
- **Data field**: Supports multi-line data fields
|
|
177
|
-
- **Event field**: Custom event types
|
|
178
|
-
- **ID field**: Last event ID tracking
|
|
179
|
-
- **Retry field**: Automatic reconnection timeout
|
|
180
|
-
- **Comment lines**: Lines starting with `:` are ignored
|
|
181
|
-
- **Event dispatching**: Proper event dispatching with default event type 'message'
|
|
182
|
-
|
|
183
|
-
## Examples
|
|
134
|
+
## 🛠️ Examples
|
|
184
135
|
|
|
185
136
|
### Real-time Notifications
|
|
186
137
|
|
|
@@ -207,6 +158,8 @@ if (response.eventStream) {
|
|
|
207
158
|
case 'update':
|
|
208
159
|
handleUpdate(JSON.parse(event.data));
|
|
209
160
|
break;
|
|
161
|
+
default:
|
|
162
|
+
console.log('Unknown event:', event);
|
|
210
163
|
}
|
|
211
164
|
}
|
|
212
165
|
}
|
|
@@ -238,12 +191,41 @@ if (response.eventStream) {
|
|
|
238
191
|
}
|
|
239
192
|
```
|
|
240
193
|
|
|
241
|
-
|
|
194
|
+
### Chat Application
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
import { Fetcher } from '@ahoo-wang/fetcher';
|
|
198
|
+
import { EventStreamInterceptor } from '@ahoo-wang/fetcher-eventstream';
|
|
199
|
+
|
|
200
|
+
const fetcher = new Fetcher({
|
|
201
|
+
baseURL: 'https://chat-api.example.com',
|
|
202
|
+
});
|
|
203
|
+
fetcher.interceptors.response.use(new EventStreamInterceptor());
|
|
204
|
+
|
|
205
|
+
// Real-time chat messages
|
|
206
|
+
const response = await fetcher.get('/rooms/123/messages');
|
|
207
|
+
if (response.eventStream) {
|
|
208
|
+
for await (const event of response.eventStream()) {
|
|
209
|
+
if (event.event === 'message') {
|
|
210
|
+
const message = JSON.parse(event.data);
|
|
211
|
+
displayMessage(message);
|
|
212
|
+
} else if (event.event === 'user-joined') {
|
|
213
|
+
showUserJoined(event.data);
|
|
214
|
+
} else if (event.event === 'user-left') {
|
|
215
|
+
showUserLeft(event.data);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
242
220
|
|
|
243
|
-
|
|
221
|
+
## 🧪 Testing
|
|
244
222
|
|
|
245
223
|
```bash
|
|
224
|
+
# Run tests
|
|
246
225
|
pnpm test
|
|
226
|
+
|
|
227
|
+
# Run tests with coverage
|
|
228
|
+
pnpm test --coverage
|
|
247
229
|
```
|
|
248
230
|
|
|
249
231
|
The test suite includes:
|
|
@@ -253,6 +235,29 @@ The test suite includes:
|
|
|
253
235
|
- Edge case handling (malformed events, chunked data, etc.)
|
|
254
236
|
- Performance tests for large event streams
|
|
255
237
|
|
|
256
|
-
##
|
|
238
|
+
## 📋 Server-Sent Events Specification Compliance
|
|
239
|
+
|
|
240
|
+
This package fully implements
|
|
241
|
+
the [Server-Sent Events specification](https://html.spec.whatwg.org/multipage/server-sent-events.html):
|
|
242
|
+
|
|
243
|
+
- **Data field**: Supports multi-line data fields
|
|
244
|
+
- **Event field**: Custom event types
|
|
245
|
+
- **ID field**: Last event ID tracking
|
|
246
|
+
- **Retry field**: Automatic reconnection timeout
|
|
247
|
+
- **Comment lines**: Lines starting with `:` are ignored
|
|
248
|
+
- **Event dispatching**: Proper event dispatching with default event type 'message'
|
|
249
|
+
|
|
250
|
+
## 🤝 Contributing
|
|
251
|
+
|
|
252
|
+
Contributions are welcome! Please see
|
|
253
|
+
the [contributing guide](https://github.com/Ahoo-Wang/fetcher/blob/main/CONTRIBUTING.md) for more details.
|
|
254
|
+
|
|
255
|
+
## 📄 License
|
|
257
256
|
|
|
258
257
|
This project is licensed under the [Apache-2.0 License](../../LICENSE).
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
<p align="center">
|
|
262
|
+
Part of the <a href="https://github.com/Ahoo-Wang/fetcher">Fetcher</a> ecosystem
|
|
263
|
+
</p>
|
package/README.zh-CN.md
CHANGED
|
@@ -6,39 +6,33 @@
|
|
|
6
6
|
[](https://github.com/Ahoo-Wang/fetcher/blob/main/LICENSE)
|
|
7
7
|
[](https://www.npmjs.com/package/@ahoo-wang/fetcher-eventstream)
|
|
8
8
|
|
|
9
|
-
为 Fetcher 提供 text/event-stream 支持,实现服务器发送事件(SSE
|
|
9
|
+
为 Fetcher 提供 text/event-stream 支持,实现服务器发送事件(SSE)功能,用于实时数据流。
|
|
10
10
|
|
|
11
|
-
## 特性
|
|
11
|
+
## 🌟 特性
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
13
|
+
- **📡 事件流转换**:将 `text/event-stream` 响应转换为 `ServerSentEvent` 对象的异步生成器
|
|
14
|
+
- **🔌 拦截器集成**:自动为 `text/event-stream` 内容类型的响应添加 `eventStream()` 方法
|
|
15
|
+
- **📋 SSE 解析**:根据规范解析服务器发送事件,包括数据、事件、ID 和重试字段
|
|
16
|
+
- **🔄 流支持**:正确处理分块数据和多行事件
|
|
17
|
+
- **💬 注释处理**:正确忽略注释行(以 `:` 开头的行)
|
|
18
|
+
- **🛡️ TypeScript 支持**:完整的 TypeScript 类型定义
|
|
19
|
+
- **⚡ 性能优化**:高效的解析和流处理,适用于高性能应用
|
|
19
20
|
|
|
20
|
-
##
|
|
21
|
+
## 🚀 快速开始
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
pnpm add @ahoo-wang/fetcher-eventstream
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
使用 npm:
|
|
23
|
+
### 安装
|
|
29
24
|
|
|
30
25
|
```bash
|
|
26
|
+
# 使用 npm
|
|
31
27
|
npm install @ahoo-wang/fetcher-eventstream
|
|
32
|
-
```
|
|
33
28
|
|
|
34
|
-
使用
|
|
29
|
+
# 使用 pnpm
|
|
30
|
+
pnpm add @ahoo-wang/fetcher-eventstream
|
|
35
31
|
|
|
36
|
-
|
|
32
|
+
# 使用 yarn
|
|
37
33
|
yarn add @ahoo-wang/fetcher-eventstream
|
|
38
34
|
```
|
|
39
35
|
|
|
40
|
-
## 使用
|
|
41
|
-
|
|
42
36
|
### 带拦截器的基本用法
|
|
43
37
|
|
|
44
38
|
```typescript
|
|
@@ -83,70 +77,35 @@ try {
|
|
|
83
77
|
}
|
|
84
78
|
```
|
|
85
79
|
|
|
86
|
-
|
|
80
|
+
## 📚 API 参考
|
|
87
81
|
|
|
88
|
-
|
|
89
|
-
import { Fetcher } from '@ahoo-wang/fetcher';
|
|
90
|
-
import { EventStreamInterceptor } from '@ahoo-wang/fetcher-eventstream';
|
|
91
|
-
|
|
92
|
-
const fetcher = new Fetcher({
|
|
93
|
-
baseURL: 'https://api.example.com',
|
|
94
|
-
interceptors: {
|
|
95
|
-
response: [new EventStreamInterceptor()],
|
|
96
|
-
},
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
// 使用异步迭代
|
|
100
|
-
const response = await fetcher.get('/events');
|
|
101
|
-
if (response.eventStream) {
|
|
102
|
-
for await (const event of response.eventStream()) {
|
|
103
|
-
switch (event.event) {
|
|
104
|
-
case 'message':
|
|
105
|
-
console.log('消息:', event.data);
|
|
106
|
-
break;
|
|
107
|
-
case 'notification':
|
|
108
|
-
console.log('通知:', event.data);
|
|
109
|
-
break;
|
|
110
|
-
default:
|
|
111
|
-
console.log('未知事件:', event);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
```
|
|
82
|
+
### EventStreamInterceptor
|
|
116
83
|
|
|
117
|
-
|
|
84
|
+
响应拦截器,自动为 `text/event-stream` 内容类型的响应添加 `eventStream()` 方法。
|
|
118
85
|
|
|
119
|
-
|
|
86
|
+
#### 用法
|
|
120
87
|
|
|
121
|
-
|
|
88
|
+
```typescript
|
|
89
|
+
fetcher.interceptors.response.use(new EventStreamInterceptor());
|
|
90
|
+
```
|
|
122
91
|
|
|
123
|
-
|
|
92
|
+
### toServerSentEventStream
|
|
124
93
|
|
|
125
94
|
将带有 `text/event-stream` 主体的 Response 对象转换为 ServerSentEvent 对象的可读流。
|
|
126
95
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
- `response`:带有 `text/event-stream` 内容类型的 HTTP 响应
|
|
130
|
-
|
|
131
|
-
**返回:**
|
|
132
|
-
|
|
133
|
-
- `ServerEventStream`:ServerSentEvent 对象的可读流
|
|
96
|
+
#### 签名
|
|
134
97
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
#### `intercept(exchange: FetchExchange): FetchExchange`
|
|
140
|
-
|
|
141
|
-
拦截响应,如果内容类型是 `text/event-stream` 则添加 `eventStream()` 方法。
|
|
98
|
+
```typescript
|
|
99
|
+
function toServerSentEventStream(response: Response): ServerSentEventStream;
|
|
100
|
+
```
|
|
142
101
|
|
|
143
|
-
|
|
102
|
+
#### 参数
|
|
144
103
|
|
|
145
|
-
- `
|
|
104
|
+
- `response`:带有 `text/event-stream` 内容类型的 HTTP 响应
|
|
146
105
|
|
|
147
|
-
|
|
106
|
+
#### 返回
|
|
148
107
|
|
|
149
|
-
- `
|
|
108
|
+
- `ServerSentEventStream`:ServerSentEvent 对象的可读流
|
|
150
109
|
|
|
151
110
|
### ServerSentEvent
|
|
152
111
|
|
|
@@ -169,18 +128,7 @@ ServerSentEvent 对象的可读流的类型别名。
|
|
|
169
128
|
type ServerSentEventStream = ReadableStream<ServerSentEvent>;
|
|
170
129
|
```
|
|
171
130
|
|
|
172
|
-
##
|
|
173
|
-
|
|
174
|
-
此包完全实现了 [服务器发送事件规范](https://html.spec.whatwg.org/multipage/server-sent-events.html):
|
|
175
|
-
|
|
176
|
-
- **数据字段**:支持多行数据字段
|
|
177
|
-
- **事件字段**:自定义事件类型
|
|
178
|
-
- **ID 字段**:最后事件 ID 跟踪
|
|
179
|
-
- **重试字段**:自动重连超时
|
|
180
|
-
- **注释行**:忽略以 `:` 开头的行
|
|
181
|
-
- **事件分发**:正确的事件分发,默认事件类型为 'message'
|
|
182
|
-
|
|
183
|
-
## 示例
|
|
131
|
+
## 🛠️ 示例
|
|
184
132
|
|
|
185
133
|
### 实时通知
|
|
186
134
|
|
|
@@ -207,6 +155,8 @@ if (response.eventStream) {
|
|
|
207
155
|
case 'update':
|
|
208
156
|
handleUpdate(JSON.parse(event.data));
|
|
209
157
|
break;
|
|
158
|
+
default:
|
|
159
|
+
console.log('未知事件:', event);
|
|
210
160
|
}
|
|
211
161
|
}
|
|
212
162
|
}
|
|
@@ -238,12 +188,41 @@ if (response.eventStream) {
|
|
|
238
188
|
}
|
|
239
189
|
```
|
|
240
190
|
|
|
241
|
-
|
|
191
|
+
### 聊天应用
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
import { Fetcher } from '@ahoo-wang/fetcher';
|
|
195
|
+
import { EventStreamInterceptor } from '@ahoo-wang/fetcher-eventstream';
|
|
196
|
+
|
|
197
|
+
const fetcher = new Fetcher({
|
|
198
|
+
baseURL: 'https://chat-api.example.com',
|
|
199
|
+
});
|
|
200
|
+
fetcher.interceptors.response.use(new EventStreamInterceptor());
|
|
201
|
+
|
|
202
|
+
// 实时聊天消息
|
|
203
|
+
const response = await fetcher.get('/rooms/123/messages');
|
|
204
|
+
if (response.eventStream) {
|
|
205
|
+
for await (const event of response.eventStream()) {
|
|
206
|
+
if (event.event === 'message') {
|
|
207
|
+
const message = JSON.parse(event.data);
|
|
208
|
+
displayMessage(message);
|
|
209
|
+
} else if (event.event === 'user-joined') {
|
|
210
|
+
showUserJoined(event.data);
|
|
211
|
+
} else if (event.event === 'user-left') {
|
|
212
|
+
showUserLeft(event.data);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
242
217
|
|
|
243
|
-
|
|
218
|
+
## 🧪 测试
|
|
244
219
|
|
|
245
220
|
```bash
|
|
221
|
+
# 运行测试
|
|
246
222
|
pnpm test
|
|
223
|
+
|
|
224
|
+
# 运行带覆盖率的测试
|
|
225
|
+
pnpm test --coverage
|
|
247
226
|
```
|
|
248
227
|
|
|
249
228
|
测试套件包括:
|
|
@@ -253,6 +232,27 @@ pnpm test
|
|
|
253
232
|
- 边界情况处理(畸形事件、分块数据等)
|
|
254
233
|
- 大事件流的性能测试
|
|
255
234
|
|
|
256
|
-
##
|
|
235
|
+
## 📋 服务器发送事件规范合规性
|
|
236
|
+
|
|
237
|
+
此包完全实现了 [服务器发送事件规范](https://html.spec.whatwg.org/multipage/server-sent-events.html):
|
|
238
|
+
|
|
239
|
+
- **数据字段**:支持多行数据字段
|
|
240
|
+
- **事件字段**:自定义事件类型
|
|
241
|
+
- **ID 字段**:最后事件 ID 跟踪
|
|
242
|
+
- **重试字段**:自动重连超时
|
|
243
|
+
- **注释行**:忽略以 `:` 开头的行
|
|
244
|
+
- **事件分发**:正确的事件分发,默认事件类型为 'message'
|
|
245
|
+
|
|
246
|
+
## 🤝 贡献
|
|
247
|
+
|
|
248
|
+
欢迎贡献!请查看 [贡献指南](https://github.com/Ahoo-Wang/fetcher/blob/main/CONTRIBUTING.md) 了解更多详情。
|
|
249
|
+
|
|
250
|
+
## 📄 许可证
|
|
257
251
|
|
|
258
252
|
本项目采用 [Apache-2.0 许可证](../../LICENSE)。
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
<p align="center">
|
|
257
|
+
Fetcher 生态系统的一部分
|
|
258
|
+
</p>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ahoo-wang/fetcher-eventstream",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Support for text/event-stream in Fetcher",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fetch",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"dist"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@ahoo-wang/fetcher": "0.
|
|
36
|
+
"@ahoo-wang/fetcher": "0.5.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@vitest/coverage-v8": "^3.2.4",
|