react-csv-autopilot 0.0.1 β 0.0.3
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 +275 -0
- package/package.json +14 -2
package/README.md
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# react-csv-autopilot
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/react-csv-autopilot)
|
|
4
|
+
[](https://www.npmjs.com/package/react-csv-autopilot)
|
|
5
|
+
[](https://bundlephobia.com/package/react-csv-autopilot)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
**Drop the function, we handle the rest.**
|
|
10
|
+
|
|
11
|
+
A React library for exporting large datasets to CSV with automatic pagination, streaming, and progress tracking. Built with Web Workers for non-blocking performance and File System Access API for efficient file writing.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- **Automatic Pagination** - Just provide a `getNextPage` function, we handle the rest
|
|
18
|
+
- **Streaming Export** - Uses ReadableStream for memory-efficient large file exports
|
|
19
|
+
- **Non-blocking** - Web Workers for CSV conversion without freezing the UI
|
|
20
|
+
- **Progress Tracking** - Real-time progress updates via BroadcastChannel
|
|
21
|
+
- **TypeScript** - Full type safety with TypeScript definitions
|
|
22
|
+
- **Zero Dependencies** - Only React as peer dependency
|
|
23
|
+
- **Framework Agnostic Core** - Use the core logic in any JavaScript environment
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install react-csv-autopilot
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
yarn add react-csv-autopilot
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pnpm add react-csv-autopilot
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { useExportCSV, useMessageExportCSV } from 'react-csv-autopilot';
|
|
47
|
+
|
|
48
|
+
function ExportButton() {
|
|
49
|
+
const { handler } = useExportCSV();
|
|
50
|
+
|
|
51
|
+
// Track export progress
|
|
52
|
+
useMessageExportCSV((progress) => {
|
|
53
|
+
if (progress.type === 'progress') {
|
|
54
|
+
console.log(`${progress.loadedItemsCount}/${progress.total}`);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const handleExport = async () => {
|
|
59
|
+
await handler.start({
|
|
60
|
+
fileName: 'users-export',
|
|
61
|
+
columns: [
|
|
62
|
+
{ key: 'id', label: 'ID' },
|
|
63
|
+
{ key: 'name', label: 'Full Name' },
|
|
64
|
+
{ key: 'email', label: 'Email Address' },
|
|
65
|
+
],
|
|
66
|
+
getNextPage: async (offset) => {
|
|
67
|
+
// Fetch your data - this will be called automatically
|
|
68
|
+
const response = await fetch(`/api/users?page=${offset}&limit=100`);
|
|
69
|
+
const data = await response.json();
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
rows: data.users,
|
|
73
|
+
total: data.totalCount,
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return <button onClick={handleExport}>Export to CSV</button>;
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## π API Reference
|
|
86
|
+
|
|
87
|
+
### `useExportCSV()`
|
|
88
|
+
|
|
89
|
+
Hook that provides access to the CSV export controller.
|
|
90
|
+
|
|
91
|
+
**Returns:**
|
|
92
|
+
```typescript
|
|
93
|
+
{
|
|
94
|
+
handler: ExportController // Controller instance for executing exports
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Example:**
|
|
99
|
+
```typescript
|
|
100
|
+
const { handler } = useExportCSV();
|
|
101
|
+
|
|
102
|
+
await handler.start({
|
|
103
|
+
fileName: 'data-export',
|
|
104
|
+
columns: [...],
|
|
105
|
+
getNextPage: async (offset) => {...}
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### `useMessageExportCSV(callback, channelName?)`
|
|
112
|
+
|
|
113
|
+
Hook for tracking export progress in real-time.
|
|
114
|
+
|
|
115
|
+
**Parameters:**
|
|
116
|
+
- `callback: (payload: ExportProgressPayload) => void` - Called on each progress update
|
|
117
|
+
- `channelName?: string` - Optional custom channel name (default: `'EXPORT_CSV_CHANNEL'`)
|
|
118
|
+
|
|
119
|
+
**Payload Type:**
|
|
120
|
+
```typescript
|
|
121
|
+
type ExportProgressPayload = {
|
|
122
|
+
total: number;
|
|
123
|
+
loadedItemsCount: number;
|
|
124
|
+
type: 'progress' | 'done' | 'failed';
|
|
125
|
+
};
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Example:**
|
|
129
|
+
```typescript
|
|
130
|
+
const [progress, setProgress] = useState({ loaded: 0, total: 0 });
|
|
131
|
+
|
|
132
|
+
useMessageExportCSV((payload) => {
|
|
133
|
+
setProgress({
|
|
134
|
+
loaded: payload.loadedItemsCount,
|
|
135
|
+
total: payload.total,
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
if (payload.type === 'done') {
|
|
139
|
+
console.log('Export completed!');
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### Types
|
|
147
|
+
|
|
148
|
+
#### `ExportParams`
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
type ExportParams = {
|
|
152
|
+
fileName: string;
|
|
153
|
+
columns: Column[];
|
|
154
|
+
getNextPage: (offset: number) => Promise<{ rows: any[]; total: number }>;
|
|
155
|
+
};
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### `Column`
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
type Column = {
|
|
162
|
+
key: string;
|
|
163
|
+
label: string;
|
|
164
|
+
timezone?: 'UTC' | string;
|
|
165
|
+
formatType?: 'dateFull' | 'dateMediumTime' | 'timeShort' | 'numDecimal' | 'numCompact' | 'numCurrency' | 'numPercent';
|
|
166
|
+
};
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
### Pagination Strategies
|
|
171
|
+
|
|
172
|
+
**API with page numbers:**
|
|
173
|
+
```typescript
|
|
174
|
+
getNextPage: async (offset) => {
|
|
175
|
+
const page = offset + 1; // Convert to 1-based pagination
|
|
176
|
+
const response = await fetch(`/api/data?page=${page}&size=100`);
|
|
177
|
+
return await response.json();
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**API with cursor-based pagination:**
|
|
182
|
+
```typescript
|
|
183
|
+
let nextCursor = null;
|
|
184
|
+
|
|
185
|
+
getNextPage: async (offset) => {
|
|
186
|
+
const url = offset === 0
|
|
187
|
+
? '/api/data?limit=100'
|
|
188
|
+
: `/api/data?cursor=${nextCursor}&limit=100`;
|
|
189
|
+
|
|
190
|
+
const response = await fetch(url);
|
|
191
|
+
const data = await response.json();
|
|
192
|
+
|
|
193
|
+
nextCursor = data.nextCursor;
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
rows: data.items,
|
|
197
|
+
total: data.totalCount,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Architecture
|
|
205
|
+
|
|
206
|
+
### How It Works
|
|
207
|
+
|
|
208
|
+
1. **Stream-based Export** - Uses `ReadableStream` and File System Access API for efficient file writing
|
|
209
|
+
2. **Web Workers** - CSV conversion happens in a separate thread to keep UI responsive
|
|
210
|
+
3. **Automatic Pagination** - Calls your `getNextPage` function repeatedly until all data is fetched
|
|
211
|
+
4. **Progress Tracking** - Uses `BroadcastChannel` to communicate progress across components
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
βββββββββββββββββββ
|
|
215
|
+
β React Hook β
|
|
216
|
+
β useExportCSV() β
|
|
217
|
+
ββββββββββ¬βββββββββ
|
|
218
|
+
β
|
|
219
|
+
βΌ
|
|
220
|
+
βββββββββββββββββββ ββββββββββββββββ
|
|
221
|
+
β Export βββββββΆβ Web Worker β
|
|
222
|
+
β Controller β β (CSV Convert)β
|
|
223
|
+
ββββββββββ¬βββββββββ ββββββββββββββββ
|
|
224
|
+
β
|
|
225
|
+
βΌ
|
|
226
|
+
βββββββββββββββββββ ββββββββββββββββ
|
|
227
|
+
β ReadableStream βββββββΆβ File System β
|
|
228
|
+
β (Pagination) β β Access API β
|
|
229
|
+
βββββββββββββββββββ ββββββββββββββββ
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Browser Compatibility
|
|
235
|
+
|
|
236
|
+
Requires browsers with support for:
|
|
237
|
+
- **File System Access API** (Chrome 86+, Edge 86+)
|
|
238
|
+
- **Web Workers** (All modern browsers)
|
|
239
|
+
- **ReadableStream** (All modern browsers)
|
|
240
|
+
|
|
241
|
+
> **Note:** For browsers without File System Access API, the library will fall back to Blob-based download.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Contributing
|
|
246
|
+
|
|
247
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## π License
|
|
252
|
+
|
|
253
|
+
MIT Β© [Pavlo Kuzina](../../LICENSE)
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## π Links
|
|
258
|
+
|
|
259
|
+
- **npm Package**: [react-csv-autopilot](https://www.npmjs.com/package/react-csv-autopilot)
|
|
260
|
+
- **Repository**: [GitHub - utils-kit](https://github.com/PashaSchool/utils-kit)
|
|
261
|
+
- **Issues**: [GitHub Issues](https://github.com/PashaSchool/utils-kit/issues)
|
|
262
|
+
- **Monorepo**: Part of [utils-kit](../../README.md) collection
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Related Packages
|
|
267
|
+
|
|
268
|
+
- [**react-url-query-params**](../react-url-query-params) - Type-safe URL query parameter management
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
<div align="center">
|
|
273
|
+
<sub>Built with β€οΈ by <a href="https://github.com/PashaSchool">Pavlo Kuzina</a></sub>
|
|
274
|
+
</div>
|
|
275
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-csv-autopilot",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "React hooks for CSV export with automatic pagination - drop the function, we handle the rest",
|
|
5
5
|
"author": "Pavlo Kuzina",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/react": "^18",
|
|
33
|
+
"@types/wicg-file-system-access": "^2023.10.7",
|
|
33
34
|
"react": "^19.2.3",
|
|
34
35
|
"tsup": "^8.0.0",
|
|
35
36
|
"typescript": "^5.0.0"
|
|
@@ -39,6 +40,10 @@
|
|
|
39
40
|
"url": "git+https://github.com/PashaSchool/utils-kit.git",
|
|
40
41
|
"directory": "packages/react-csv-autopilot"
|
|
41
42
|
},
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/PashaSchool/utils-kit/issues"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/PashaSchool/utils-kit/blob/main/packages/react-csv-autopilot/README.md",
|
|
42
47
|
"keywords": [
|
|
43
48
|
"react",
|
|
44
49
|
"csv",
|
|
@@ -47,6 +52,13 @@
|
|
|
47
52
|
"autopilot",
|
|
48
53
|
"pagination",
|
|
49
54
|
"streaming",
|
|
50
|
-
"typescript"
|
|
55
|
+
"typescript",
|
|
56
|
+
"download",
|
|
57
|
+
"file-export",
|
|
58
|
+
"web-workers",
|
|
59
|
+
"progress-tracking",
|
|
60
|
+
"file-system-access",
|
|
61
|
+
"large-datasets",
|
|
62
|
+
"data-export"
|
|
51
63
|
]
|
|
52
64
|
}
|