convert-buddy-js 0.10.18 → 0.11.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 +49 -4
- package/dist/browser-stream-controller.d.ts +107 -0
- package/dist/browser-stream-controller.js +226 -0
- package/dist/browser-stream-controller.js.map +1 -0
- package/dist/browser.d.ts +16 -195
- package/dist/browser.js +78 -339
- package/dist/browser.js.map +1 -1
- package/dist/index-BpUN6Tdz.d.ts +440 -0
- package/dist/index.d.ts +1 -271
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -1
- package/dist/node-stream-controller.d.ts +133 -0
- package/dist/node-stream-controller.js +274 -0
- package/dist/node-stream-controller.js.map +1 -0
- package/dist/node.d.ts +3 -2
- package/dist/node.js +2 -0
- package/dist/node.js.map +1 -1
- package/dist/stream-controller.d.ts +1 -0
- package/dist/stream-controller.js +277 -0
- package/dist/stream-controller.js.map +1 -0
- package/dist/streaming-worker.js +1 -1
- package/dist/streaming-worker.js.map +1 -1
- package/dist/tests/stream-controller.test.js +237 -0
- package/dist/tests/stream-controller.test.js.map +1 -0
- package/dist/wasm/nodejs/convert_buddy.d.ts +6 -0
- package/dist/wasm/nodejs/convert_buddy.js +58 -28
- package/dist/wasm/nodejs/convert_buddy_bg.wasm +0 -0
- package/dist/wasm/nodejs/convert_buddy_bg.wasm.d.ts +4 -3
- package/dist/wasm/web/convert_buddy.d.ts +10 -3
- package/dist/wasm/web/convert_buddy.js +55 -27
- package/dist/wasm/web/convert_buddy_bg.wasm +0 -0
- package/dist/wasm/web/convert_buddy_bg.wasm.d.ts +4 -3
- package/package.json +3 -5
- package/dist/browser-core.d.ts +0 -196
- package/dist/browser-core.js +0 -787
- package/dist/browser-core.js.map +0 -1
- package/dist/wasm/nodejs/convert_buddy.cjs +0 -712
package/README.md
CHANGED
|
@@ -111,9 +111,9 @@ const json = await convertToString("input.csv", {
|
|
|
111
111
|
|
|
112
112
|
## API Overview
|
|
113
113
|
|
|
114
|
-
Convert Buddy offers
|
|
114
|
+
Convert Buddy offers multiple layers of control, from one-liners to fully manual streaming.
|
|
115
115
|
|
|
116
|
-
1. Ultra-simple API
|
|
116
|
+
### 1. Ultra-simple API
|
|
117
117
|
|
|
118
118
|
```ts
|
|
119
119
|
import { convert, convertToString } from "convert-buddy-js";
|
|
@@ -130,7 +130,52 @@ Supported input types
|
|
|
130
130
|
- `ReadableStream<Uint8Array>`
|
|
131
131
|
- Node file paths
|
|
132
132
|
|
|
133
|
-
2.
|
|
133
|
+
### 2. StreamController API (NEW! 🎉)
|
|
134
|
+
|
|
135
|
+
**Per-record processing with backpressure management**
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { NodeStreamController } from "convert-buddy-js/node";
|
|
139
|
+
|
|
140
|
+
const controller = new NodeStreamController({
|
|
141
|
+
inputFormat: "csv",
|
|
142
|
+
outputFormat: "ndjson",
|
|
143
|
+
onRecord: async (record, index) => {
|
|
144
|
+
// Process each record as it's converted
|
|
145
|
+
await saveToDatabase(record);
|
|
146
|
+
},
|
|
147
|
+
onStreamProgress: (stats, recordCount) => {
|
|
148
|
+
console.log(`Processed ${recordCount} records`);
|
|
149
|
+
},
|
|
150
|
+
progressBatchSize: 1000,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Option 1: Await (wait for completion)
|
|
154
|
+
await controller.process("large-file.csv");
|
|
155
|
+
|
|
156
|
+
// Option 2: Fire-and-forget (non-blocking, runs in background)
|
|
157
|
+
controller.process("large-file.csv").then(() => {
|
|
158
|
+
console.log("Done!");
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Browser version**
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
import { BrowserStreamController } from "convert-buddy-js/browser";
|
|
166
|
+
|
|
167
|
+
const controller = new BrowserStreamController({
|
|
168
|
+
inputFormat: "csv",
|
|
169
|
+
outputFormat: "ndjson",
|
|
170
|
+
onRecord: (record) => displayRecord(record),
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
await controller.process(fileInput.files[0]);
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
📚 **[See Full StreamController Documentation](./STREAM_CONTROLLER_GUIDE.md)**
|
|
177
|
+
|
|
178
|
+
### 3. Instance-based API
|
|
134
179
|
|
|
135
180
|
```ts
|
|
136
181
|
import { ConvertBuddy } from "convert-buddy-js";
|
|
@@ -144,7 +189,7 @@ const buddy = new ConvertBuddy({
|
|
|
144
189
|
const out = await buddy.convert(file, { outputFormat: "ndjson" });
|
|
145
190
|
```
|
|
146
191
|
|
|
147
|
-
|
|
192
|
+
### 4. High-level helpers
|
|
148
193
|
|
|
149
194
|
**Browser helpers**
|
|
150
195
|
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { A as StreamControllerOptions, i as Stats } from './index-BpUN6Tdz.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Browser-specific StreamController implementation
|
|
5
|
+
*
|
|
6
|
+
* Provides high-level streaming API for browser environments with ReadableStream support.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
type BrowserStreamInput = ReadableStream<Uint8Array> | string | Blob | File;
|
|
10
|
+
/**
|
|
11
|
+
* BrowserStreamController - High-level streaming API for browser environments
|
|
12
|
+
*
|
|
13
|
+
* Features:
|
|
14
|
+
* - Per-record callbacks with backpressure management
|
|
15
|
+
* - Pause/resume/abort controls
|
|
16
|
+
* - Progress tracking
|
|
17
|
+
* - Automatic NDJSON/CSV/JSON/XML splitting and parsing
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const controller = new BrowserStreamController({
|
|
22
|
+
* inputFormat: "csv",
|
|
23
|
+
* outputFormat: "ndjson",
|
|
24
|
+
* onRecord: async (record, index) => {
|
|
25
|
+
* await processRecord(record);
|
|
26
|
+
* },
|
|
27
|
+
* onProgress: (stats, recordCount) => {
|
|
28
|
+
* console.log(`Processed ${recordCount} records`);
|
|
29
|
+
* }
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* await controller.process(fetch('/data.csv').then(r => r.body!));
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
declare class BrowserStreamController {
|
|
36
|
+
private options;
|
|
37
|
+
private buddy;
|
|
38
|
+
private reader;
|
|
39
|
+
private aborted;
|
|
40
|
+
private paused;
|
|
41
|
+
private recordCount;
|
|
42
|
+
private splitter;
|
|
43
|
+
constructor(options: StreamControllerOptions);
|
|
44
|
+
/**
|
|
45
|
+
* Process a stream/URL/File/Blob and invoke callbacks for each record
|
|
46
|
+
*/
|
|
47
|
+
process(input: BrowserStreamInput): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Convert various input types to ReadableStream
|
|
50
|
+
*/
|
|
51
|
+
private inputToStream;
|
|
52
|
+
/**
|
|
53
|
+
* Process the stream chunk by chunk
|
|
54
|
+
*/
|
|
55
|
+
private processStream;
|
|
56
|
+
/**
|
|
57
|
+
* Process output bytes and split into records
|
|
58
|
+
*/
|
|
59
|
+
private processOutput;
|
|
60
|
+
/**
|
|
61
|
+
* Invoke the onRecord callback with proper backpressure handling
|
|
62
|
+
*/
|
|
63
|
+
private invokeRecordCallback;
|
|
64
|
+
/**
|
|
65
|
+
* Pause the stream processing
|
|
66
|
+
*/
|
|
67
|
+
pause(): void;
|
|
68
|
+
/**
|
|
69
|
+
* Resume the stream processing
|
|
70
|
+
*/
|
|
71
|
+
resume(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Abort the stream processing
|
|
74
|
+
*/
|
|
75
|
+
abort(): void;
|
|
76
|
+
/**
|
|
77
|
+
* Get current statistics
|
|
78
|
+
*/
|
|
79
|
+
stats(): Stats | null;
|
|
80
|
+
/**
|
|
81
|
+
* Get current record count
|
|
82
|
+
*/
|
|
83
|
+
getRecordCount(): number;
|
|
84
|
+
/**
|
|
85
|
+
* Check if processing is paused
|
|
86
|
+
*/
|
|
87
|
+
isPaused(): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Check if processing is aborted
|
|
90
|
+
*/
|
|
91
|
+
isAborted(): boolean;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Convenience function to process a stream with a simple callback
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* await processStream('/data.csv', {
|
|
99
|
+
* inputFormat: 'csv',
|
|
100
|
+
* outputFormat: 'ndjson',
|
|
101
|
+
* onRecord: (record) => console.log(record),
|
|
102
|
+
* });
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
declare function processStream(input: BrowserStreamInput, options: StreamControllerOptions): Promise<void>;
|
|
106
|
+
|
|
107
|
+
export { BrowserStreamController, type BrowserStreamInput, processStream };
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { ConvertBuddy } from "./index.js";
|
|
2
|
+
import { createSplitter } from "./stream-controller.js";
|
|
3
|
+
class BrowserStreamController {
|
|
4
|
+
options;
|
|
5
|
+
buddy = null;
|
|
6
|
+
reader = null;
|
|
7
|
+
aborted = false;
|
|
8
|
+
paused = false;
|
|
9
|
+
recordCount = 0;
|
|
10
|
+
splitter;
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.options = {
|
|
13
|
+
outputFormat: "ndjson",
|
|
14
|
+
progressBatchSize: 1e3,
|
|
15
|
+
autoPause: true,
|
|
16
|
+
...options
|
|
17
|
+
};
|
|
18
|
+
this.splitter = createSplitter(this.options.outputFormat, this.options);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Process a stream/URL/File/Blob and invoke callbacks for each record
|
|
22
|
+
*/
|
|
23
|
+
async process(input) {
|
|
24
|
+
try {
|
|
25
|
+
const stream = await this.inputToStream(input);
|
|
26
|
+
this.buddy = await ConvertBuddy.create({
|
|
27
|
+
...this.options,
|
|
28
|
+
profile: true
|
|
29
|
+
// Enable stats for progress tracking
|
|
30
|
+
});
|
|
31
|
+
this.reader = stream.getReader();
|
|
32
|
+
await this.processStream();
|
|
33
|
+
} finally {
|
|
34
|
+
if (this.reader) {
|
|
35
|
+
try {
|
|
36
|
+
await this.reader.cancel();
|
|
37
|
+
} catch (e) {
|
|
38
|
+
}
|
|
39
|
+
this.reader = null;
|
|
40
|
+
}
|
|
41
|
+
this.buddy = null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Convert various input types to ReadableStream
|
|
46
|
+
*/
|
|
47
|
+
async inputToStream(input) {
|
|
48
|
+
if (typeof input === "string") {
|
|
49
|
+
if (input.startsWith("http://") || input.startsWith("https://")) {
|
|
50
|
+
const response = await fetch(input);
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
throw new Error(`Failed to fetch ${input}: ${response.statusText}`);
|
|
53
|
+
}
|
|
54
|
+
if (!response.body) {
|
|
55
|
+
throw new Error("Response body is null");
|
|
56
|
+
}
|
|
57
|
+
return response.body;
|
|
58
|
+
} else {
|
|
59
|
+
const encoder = new TextEncoder();
|
|
60
|
+
const bytes = encoder.encode(input);
|
|
61
|
+
return new ReadableStream({
|
|
62
|
+
start(controller) {
|
|
63
|
+
controller.enqueue(bytes);
|
|
64
|
+
controller.close();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
} else if (typeof ReadableStream !== "undefined" && input instanceof ReadableStream) {
|
|
69
|
+
return input;
|
|
70
|
+
} else if (typeof Blob !== "undefined" && input instanceof Blob || typeof File !== "undefined" && input instanceof File) {
|
|
71
|
+
return input.stream();
|
|
72
|
+
} else {
|
|
73
|
+
throw new Error("Unsupported input type for BrowserStreamController");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Process the stream chunk by chunk
|
|
78
|
+
*/
|
|
79
|
+
async processStream() {
|
|
80
|
+
if (!this.buddy || !this.reader) {
|
|
81
|
+
throw new Error("Stream not initialized");
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
while (true) {
|
|
85
|
+
if (this.aborted) {
|
|
86
|
+
this.buddy.abort();
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
while (this.paused && !this.aborted) {
|
|
90
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
91
|
+
}
|
|
92
|
+
const { done, value } = await this.reader.read();
|
|
93
|
+
if (done) {
|
|
94
|
+
const finalOutput = this.buddy.finish();
|
|
95
|
+
if (finalOutput.length > 0) {
|
|
96
|
+
await this.processOutput(finalOutput);
|
|
97
|
+
}
|
|
98
|
+
const finalRecords = this.splitter.flush();
|
|
99
|
+
for (const record of finalRecords) {
|
|
100
|
+
await this.invokeRecordCallback(record);
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
const needsRecords = !!this.options.onRecord;
|
|
105
|
+
const result = this.buddy.pushWithRecords(value, needsRecords);
|
|
106
|
+
if (typeof result === "object" && "output" in result) {
|
|
107
|
+
if (result.output.length > 0) {
|
|
108
|
+
await this.processOutput(result.output, result.records);
|
|
109
|
+
}
|
|
110
|
+
} else if (result.length > 0) {
|
|
111
|
+
await this.processOutput(result);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
} catch (error) {
|
|
115
|
+
if (this.aborted) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Process output bytes and split into records
|
|
123
|
+
*/
|
|
124
|
+
async processOutput(output, wasmRecords) {
|
|
125
|
+
if (this.options.onData) {
|
|
126
|
+
this.options.onData(output);
|
|
127
|
+
}
|
|
128
|
+
const records = wasmRecords && wasmRecords.length > 0 ? wasmRecords : this.splitter.push(output);
|
|
129
|
+
for (const record of records) {
|
|
130
|
+
if (this.aborted) break;
|
|
131
|
+
await this.invokeRecordCallback(record);
|
|
132
|
+
if (this.options.onStreamProgress && this.recordCount % (this.options.progressBatchSize || 1e3) === 0) {
|
|
133
|
+
const stats = this.buddy.stats();
|
|
134
|
+
this.options.onStreamProgress(stats, this.recordCount);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Invoke the onRecord callback with proper backpressure handling
|
|
140
|
+
*/
|
|
141
|
+
async invokeRecordCallback(record) {
|
|
142
|
+
if (!this.options.onRecord) {
|
|
143
|
+
this.recordCount++;
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
const result = this.options.onRecord(record, this.recordCount);
|
|
148
|
+
if (this.options.autoPause && result instanceof Promise) {
|
|
149
|
+
const shouldContinue = await result;
|
|
150
|
+
if (shouldContinue === false) {
|
|
151
|
+
this.pause();
|
|
152
|
+
}
|
|
153
|
+
} else if (result === false) {
|
|
154
|
+
this.pause();
|
|
155
|
+
}
|
|
156
|
+
this.recordCount++;
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error("[BrowserStreamController] Error in onRecord callback:", error);
|
|
159
|
+
throw error;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Pause the stream processing
|
|
164
|
+
*/
|
|
165
|
+
pause() {
|
|
166
|
+
this.paused = true;
|
|
167
|
+
if (this.buddy) {
|
|
168
|
+
this.buddy.pause();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Resume the stream processing
|
|
173
|
+
*/
|
|
174
|
+
resume() {
|
|
175
|
+
this.paused = false;
|
|
176
|
+
if (this.buddy) {
|
|
177
|
+
this.buddy.resume();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Abort the stream processing
|
|
182
|
+
*/
|
|
183
|
+
abort() {
|
|
184
|
+
this.aborted = true;
|
|
185
|
+
if (this.buddy) {
|
|
186
|
+
this.buddy.abort();
|
|
187
|
+
}
|
|
188
|
+
if (this.reader) {
|
|
189
|
+
this.reader.cancel().catch(() => {
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Get current statistics
|
|
195
|
+
*/
|
|
196
|
+
stats() {
|
|
197
|
+
return this.buddy ? this.buddy.stats() : null;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Get current record count
|
|
201
|
+
*/
|
|
202
|
+
getRecordCount() {
|
|
203
|
+
return this.recordCount;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Check if processing is paused
|
|
207
|
+
*/
|
|
208
|
+
isPaused() {
|
|
209
|
+
return this.paused;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Check if processing is aborted
|
|
213
|
+
*/
|
|
214
|
+
isAborted() {
|
|
215
|
+
return this.aborted;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async function processStream(input, options) {
|
|
219
|
+
const controller = new BrowserStreamController(options);
|
|
220
|
+
await controller.process(input);
|
|
221
|
+
}
|
|
222
|
+
export {
|
|
223
|
+
BrowserStreamController,
|
|
224
|
+
processStream
|
|
225
|
+
};
|
|
226
|
+
//# sourceMappingURL=browser-stream-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/browser-stream-controller.ts"],"sourcesContent":["/**\r\n * Browser-specific StreamController implementation\r\n * \r\n * Provides high-level streaming API for browser environments with ReadableStream support.\r\n */\r\n\r\nimport { ConvertBuddy } from \"./index.js\";\r\nimport type { Stats } from \"./index.js\";\r\nimport { StreamControllerOptions, createSplitter } from \"./stream-controller.js\";\r\n\r\nexport type BrowserStreamInput = ReadableStream<Uint8Array> | string | Blob | File;\r\n\r\n/**\r\n * BrowserStreamController - High-level streaming API for browser environments\r\n * \r\n * Features:\r\n * - Per-record callbacks with backpressure management\r\n * - Pause/resume/abort controls\r\n * - Progress tracking\r\n * - Automatic NDJSON/CSV/JSON/XML splitting and parsing\r\n * \r\n * @example\r\n * ```ts\r\n * const controller = new BrowserStreamController({\r\n * inputFormat: \"csv\",\r\n * outputFormat: \"ndjson\",\r\n * onRecord: async (record, index) => {\r\n * await processRecord(record);\r\n * },\r\n * onProgress: (stats, recordCount) => {\r\n * console.log(`Processed ${recordCount} records`);\r\n * }\r\n * });\r\n * \r\n * await controller.process(fetch('/data.csv').then(r => r.body!));\r\n * ```\r\n */\r\nexport class BrowserStreamController {\r\n private options: StreamControllerOptions;\r\n private buddy: ConvertBuddy | null = null;\r\n private reader: ReadableStreamDefaultReader<Uint8Array> | null = null;\r\n private aborted = false;\r\n private paused = false;\r\n private recordCount = 0;\r\n private splitter: any;\r\n\r\n constructor(options: StreamControllerOptions) {\r\n this.options = {\r\n outputFormat: \"ndjson\",\r\n progressBatchSize: 1000,\r\n autoPause: true,\r\n ...options,\r\n };\r\n\r\n // Create appropriate splitter for output format\r\n this.splitter = createSplitter(this.options.outputFormat!, this.options);\r\n }\r\n\r\n /**\r\n * Process a stream/URL/File/Blob and invoke callbacks for each record\r\n */\r\n async process(input: BrowserStreamInput): Promise<void> {\r\n try {\r\n // Convert input to ReadableStream\r\n const stream = await this.inputToStream(input);\r\n\r\n // Create ConvertBuddy instance\r\n this.buddy = await ConvertBuddy.create({\r\n ...this.options,\r\n profile: true, // Enable stats for progress tracking\r\n });\r\n\r\n // Get reader\r\n this.reader = stream.getReader();\r\n\r\n // Process stream\r\n await this.processStream();\r\n\r\n } finally {\r\n // Cleanup\r\n if (this.reader) {\r\n try {\r\n await this.reader.cancel();\r\n } catch (e) {\r\n // Ignore cancel errors\r\n }\r\n this.reader = null;\r\n }\r\n this.buddy = null;\r\n }\r\n }\r\n\r\n /**\r\n * Convert various input types to ReadableStream\r\n */\r\n private async inputToStream(input: BrowserStreamInput): Promise<ReadableStream<Uint8Array>> {\r\n if (typeof input === \"string\") {\r\n // URL\r\n if (input.startsWith(\"http://\") || input.startsWith(\"https://\")) {\r\n const response = await fetch(input);\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch ${input}: ${response.statusText}`);\r\n }\r\n if (!response.body) {\r\n throw new Error(\"Response body is null\");\r\n }\r\n return response.body;\r\n } else {\r\n // Raw string data\r\n const encoder = new TextEncoder();\r\n const bytes = encoder.encode(input);\r\n return new ReadableStream({\r\n start(controller) {\r\n controller.enqueue(bytes);\r\n controller.close();\r\n },\r\n });\r\n }\r\n } else if (typeof ReadableStream !== \"undefined\" && input instanceof ReadableStream) {\r\n return input;\r\n } else if ((typeof Blob !== \"undefined\" && input instanceof Blob) || \r\n (typeof File !== \"undefined\" && input instanceof File)) {\r\n return (input as Blob | File).stream() as ReadableStream<Uint8Array>;\r\n } else {\r\n throw new Error(\"Unsupported input type for BrowserStreamController\");\r\n }\r\n }\r\n\r\n /**\r\n * Process the stream chunk by chunk\r\n */\r\n private async processStream(): Promise<void> {\r\n if (!this.buddy || !this.reader) {\r\n throw new Error(\"Stream not initialized\");\r\n }\r\n\r\n try {\r\n while (true) {\r\n // Check if aborted\r\n if (this.aborted) {\r\n this.buddy.abort();\r\n break;\r\n }\r\n\r\n // Wait while paused\r\n while (this.paused && !this.aborted) {\r\n await new Promise((resolve) => setTimeout(resolve, 100));\r\n }\r\n\r\n // Read next chunk\r\n const { done, value } = await this.reader!.read();\r\n\r\n if (done) {\r\n // Finish conversion and process final output\r\n const finalOutput = this.buddy.finish();\r\n if (finalOutput.length > 0) {\r\n await this.processOutput(finalOutput);\r\n }\r\n\r\n // Flush splitter\r\n const finalRecords = this.splitter.flush();\r\n for (const record of finalRecords) {\r\n await this.invokeRecordCallback(record);\r\n }\r\n\r\n break;\r\n }\r\n\r\n // Push chunk to ConvertBuddy with record parsing\r\n const needsRecords = !!this.options.onRecord;\r\n const result = this.buddy.pushWithRecords(value, needsRecords);\r\n\r\n // Process output if any\r\n if (typeof result === 'object' && 'output' in result) {\r\n // Dual output with records\r\n if (result.output.length > 0) {\r\n await this.processOutput(result.output, result.records);\r\n }\r\n } else if (result.length > 0) {\r\n // Fallback: just bytes\r\n await this.processOutput(result);\r\n }\r\n }\r\n } catch (error) {\r\n if (this.aborted) {\r\n // Ignore errors after abort\r\n return;\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Process output bytes and split into records\r\n */\r\n private async processOutput(output: Uint8Array, wasmRecords?: any[]): Promise<void> {\r\n // Call onData callback with raw bytes if provided\r\n if (this.options.onData) {\r\n this.options.onData(output);\r\n }\r\n\r\n // Use WASM-parsed records if available, otherwise use TypeScript splitter\r\n const records = wasmRecords && wasmRecords.length > 0 ? wasmRecords : this.splitter.push(output);\r\n\r\n // Process each record\r\n for (const record of records) {\r\n if (this.aborted) break;\r\n\r\n await this.invokeRecordCallback(record);\r\n\r\n // Check progress callback\r\n if (\r\n this.options.onStreamProgress &&\r\n this.recordCount % (this.options.progressBatchSize || 1000) === 0\r\n ) {\r\n const stats = this.buddy!.stats();\r\n this.options.onStreamProgress(stats, this.recordCount);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Invoke the onRecord callback with proper backpressure handling\r\n */\r\n private async invokeRecordCallback(record: any): Promise<void> {\r\n if (!this.options.onRecord) {\r\n this.recordCount++;\r\n return;\r\n }\r\n\r\n try {\r\n // Call the callback\r\n const result = this.options.onRecord(record, this.recordCount);\r\n\r\n // If autoPause is enabled and callback returns a Promise, wait for it\r\n if (this.options.autoPause && result instanceof Promise) {\r\n const shouldContinue = await result;\r\n \r\n // If callback returns false, pause\r\n if (shouldContinue === false) {\r\n this.pause();\r\n }\r\n } else if (result === false) {\r\n // If callback returns false synchronously, pause\r\n this.pause();\r\n }\r\n\r\n this.recordCount++;\r\n } catch (error) {\r\n console.error(\"[BrowserStreamController] Error in onRecord callback:\", error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Pause the stream processing\r\n */\r\n pause(): void {\r\n this.paused = true;\r\n if (this.buddy) {\r\n this.buddy.pause();\r\n }\r\n }\r\n\r\n /**\r\n * Resume the stream processing\r\n */\r\n resume(): void {\r\n this.paused = false;\r\n if (this.buddy) {\r\n this.buddy.resume();\r\n }\r\n }\r\n\r\n /**\r\n * Abort the stream processing\r\n */\r\n abort(): void {\r\n this.aborted = true;\r\n if (this.buddy) {\r\n this.buddy.abort();\r\n }\r\n if (this.reader) {\r\n this.reader.cancel().catch(() => {\r\n // Ignore cancel errors\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Get current statistics\r\n */\r\n stats(): Stats | null {\r\n return this.buddy ? this.buddy.stats() : null;\r\n }\r\n\r\n /**\r\n * Get current record count\r\n */\r\n getRecordCount(): number {\r\n return this.recordCount;\r\n }\r\n\r\n /**\r\n * Check if processing is paused\r\n */\r\n isPaused(): boolean {\r\n return this.paused;\r\n }\r\n\r\n /**\r\n * Check if processing is aborted\r\n */\r\n isAborted(): boolean {\r\n return this.aborted;\r\n }\r\n}\r\n\r\n/**\r\n * Convenience function to process a stream with a simple callback\r\n * \r\n * @example\r\n * ```ts\r\n * await processStream('/data.csv', {\r\n * inputFormat: 'csv',\r\n * outputFormat: 'ndjson',\r\n * onRecord: (record) => console.log(record),\r\n * });\r\n * ```\r\n */\r\nexport async function processStream(\r\n input: BrowserStreamInput,\r\n options: StreamControllerOptions\r\n): Promise<void> {\r\n const controller = new BrowserStreamController(options);\r\n await controller.process(input);\r\n}\r\n"],"mappings":"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","names":[]}
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,209 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { Coerce, ConvertBuddy, ConvertBuddyTransformStream, Converter, CsvConfig, CsvDetection, DetectInput, DetectOptions, FieldMap, JsonDetection, NdjsonDetection, ProgressCallback, Stats, StructureDetection, TransformConfig, TransformMode, XmlConfig, XmlDetection, autoDetectConfig, convertAny, convertAnyToString, detectCsvFieldsAndDelimiter, detectFormat, detectStructure, detectXmlElements, getExtension,
|
|
1
|
+
import { C as ConvertOptions, F as Format } from './index-BpUN6Tdz.js';
|
|
2
|
+
export { G as CSVSplitter, f as Coerce, j as ConvertBuddy, a as ConvertBuddyOptions, p as ConvertBuddyTransformStream, j as Converter, d as CsvConfig, b as CsvDetection, D as DetectInput, c as DetectOptions, g as FieldMap, H as JSONSplitter, J as JsonDetection, E as NDJSONSplitter, N as NdjsonDetection, B as ParsedRecord, P as ProgressCallback, i as Stats, A as StreamControllerOptions, S as StructureDetection, h as TransformConfig, T as TransformMode, I as XMLSplitter, e as XmlConfig, X as XmlDetection, o as autoDetectConfig, q as convertAny, r as convertAnyToString, K as createSplitter, m as detectCsvFieldsAndDelimiter, k as detectFormat, l as detectStructure, n as detectXmlElements, t as getExtension, s as getMimeType, x as getOptimalThreadCount, u as getSuggestedFilename, y as getThreadingInfo, w as isWasmThreadingSupported } from './index-BpUN6Tdz.js';
|
|
3
|
+
export { BrowserStreamController, BrowserStreamInput, processStream } from './browser-stream-controller.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
* Browser
|
|
6
|
-
*
|
|
7
|
-
* WITHOUT requiring WebContainers or special worker thread support.
|
|
8
|
-
*
|
|
9
|
-
* Key differences from the main entry point:
|
|
10
|
-
* - No Node.js code paths (no worker_threads, no fs, no path)
|
|
11
|
-
* - Browser-optimized WASM loading
|
|
12
|
-
* - Web Worker functionality is optional and gracefully degrades
|
|
6
|
+
* Browser entry point for convert-buddy-js
|
|
7
|
+
* Re-exports the main API but optimized for browser environments
|
|
13
8
|
*/
|
|
14
9
|
|
|
15
|
-
type BrowserConvertOptions = ConvertBuddyOptions & {};
|
|
16
10
|
/**
|
|
17
|
-
*
|
|
18
|
-
* Auto-detects input type (File, URL, string, etc.) and format.
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* // From File
|
|
22
|
-
* const file = fileInput.files[0];
|
|
23
|
-
* const result = await convert(file, { outputFormat: "json" });
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* // From URL
|
|
27
|
-
* const result = await convert("https://example.com/data.csv", { outputFormat: "json" });
|
|
28
|
-
*
|
|
29
|
-
* @example
|
|
30
|
-
* // From string
|
|
31
|
-
* const result = await convert(csvString, { outputFormat: "json" });
|
|
32
|
-
*/
|
|
33
|
-
declare function convert(input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>, opts: ConvertOptions): Promise<Uint8Array>;
|
|
34
|
-
/**
|
|
35
|
-
* Ultra-simple convert function that returns a string.
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* const json = await convertToString(file, { outputFormat: "json" });
|
|
39
|
-
* console.log(JSON.parse(json));
|
|
11
|
+
* Browser-optimized convert function for strings
|
|
40
12
|
*/
|
|
41
13
|
declare function convertToString(input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>, opts: ConvertOptions): Promise<string>;
|
|
42
14
|
/**
|
|
43
|
-
*
|
|
44
|
-
* Handles streaming internally using FileReader and web streams.
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* // From file input
|
|
48
|
-
* const fileInput = document.querySelector('input[type="file"]');
|
|
49
|
-
* const file = fileInput.files[0];
|
|
50
|
-
* const result = await convertFileToString(file, {
|
|
51
|
-
* inputFormat: "csv",
|
|
52
|
-
* outputFormat: "json"
|
|
53
|
-
* });
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* // With auto-detection
|
|
57
|
-
* const result = await convertFileToString(file, {
|
|
58
|
-
* inputFormat: "auto",
|
|
59
|
-
* outputFormat: "ndjson"
|
|
60
|
-
* });
|
|
61
|
-
*/
|
|
62
|
-
declare function convertFileToString(file: File | Blob, opts?: BrowserConvertOptions): Promise<string>;
|
|
63
|
-
/**
|
|
64
|
-
* Convert a browser File or Blob object to a Uint8Array.
|
|
65
|
-
* Handles streaming internally using FileReader and web streams.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* const file = fileInput.files[0];
|
|
69
|
-
* const result = await convertFile(file, {
|
|
70
|
-
* inputFormat: "csv",
|
|
71
|
-
* outputFormat: "json",
|
|
72
|
-
* onProgress: (stats) => {
|
|
73
|
-
* console.log(`Progress: ${stats.bytesIn} bytes processed`);
|
|
74
|
-
* }
|
|
75
|
-
* });
|
|
76
|
-
*/
|
|
77
|
-
declare function convertFile(file: File | Blob, opts?: BrowserConvertOptions): Promise<Uint8Array>;
|
|
78
|
-
/**
|
|
79
|
-
* Convert a browser File or Blob and download the result as a file.
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* const fileInput = document.querySelector('input[type="file"]');
|
|
83
|
-
* const file = fileInput.files[0];
|
|
84
|
-
* await convertFileToFile(file, "output.json", {
|
|
85
|
-
* inputFormat: "csv",
|
|
86
|
-
* outputFormat: "json"
|
|
87
|
-
* });
|
|
88
|
-
*/
|
|
89
|
-
declare function convertFileToFile(inputFile: File | Blob, outputFilename: string, opts?: BrowserConvertOptions): Promise<void>;
|
|
90
|
-
/**
|
|
91
|
-
* Create a ReadableStream that converts data on-the-fly from a File or Blob.
|
|
92
|
-
* Useful for piping through other stream processors.
|
|
93
|
-
*
|
|
94
|
-
* @example
|
|
95
|
-
* const file = fileInput.files[0];
|
|
96
|
-
* const stream = convertFileStream(file, {
|
|
97
|
-
* inputFormat: "csv",
|
|
98
|
-
* outputFormat: "ndjson"
|
|
99
|
-
* });
|
|
100
|
-
*
|
|
101
|
-
* const reader = stream.getReader();
|
|
102
|
-
* while (true) {
|
|
103
|
-
* const { done, value } = await reader.read();
|
|
104
|
-
* if (done) break;
|
|
105
|
-
* // Process each chunk as it's converted
|
|
106
|
-
* console.log(new TextDecoder().decode(value));
|
|
107
|
-
* }
|
|
15
|
+
* Browser-optimized convert function for bytes
|
|
108
16
|
*/
|
|
109
|
-
declare function
|
|
110
|
-
/**
|
|
111
|
-
* Auto-detect format and create a ReadableStream for conversion.
|
|
112
|
-
* This is a convenience helper that combines format detection with streaming conversion.
|
|
113
|
-
*
|
|
114
|
-
* @example
|
|
115
|
-
* const file = fileInput.files[0];
|
|
116
|
-
* const stream = await autoConvertStream(file, { outputFormat: "json" });
|
|
117
|
-
*
|
|
118
|
-
* // Pipe to response
|
|
119
|
-
* return new Response(stream);
|
|
120
|
-
*/
|
|
121
|
-
declare function autoConvertStream(file: File | Blob, opts: Omit<BrowserConvertOptions, "inputFormat"> & {
|
|
122
|
-
outputFormat: Format;
|
|
123
|
-
}): Promise<ReadableStream<Uint8Array>>;
|
|
124
|
-
/**
|
|
125
|
-
* Stream a file conversion directly to a writable destination.
|
|
126
|
-
* This is useful for streaming large conversions to disk using File System Access API
|
|
127
|
-
* or to other writable streams.
|
|
128
|
-
*
|
|
129
|
-
* @example
|
|
130
|
-
* // Using File System Access API
|
|
131
|
-
* const fileInput = document.querySelector('input[type="file"]');
|
|
132
|
-
* const file = fileInput.files[0];
|
|
133
|
-
*
|
|
134
|
-
* const fileHandle = await window.showSaveFilePicker({
|
|
135
|
-
* suggestedName: "output.json",
|
|
136
|
-
* types: [{ description: "JSON", accept: { "application/json": [".json"] } }]
|
|
137
|
-
* });
|
|
138
|
-
* const writable = await fileHandle.createWritable();
|
|
139
|
-
*
|
|
140
|
-
* await convertStreamToWritable(file, writable, {
|
|
141
|
-
* inputFormat: "csv",
|
|
142
|
-
* outputFormat: "json",
|
|
143
|
-
* onProgress: (stats) => console.log(`${stats.bytesIn} bytes processed`)
|
|
144
|
-
* });
|
|
145
|
-
*/
|
|
146
|
-
declare function convertStreamToWritable(file: File | Blob, writable: WritableStream<Uint8Array> | FileSystemWritableFileStream, opts?: BrowserConvertOptions): Promise<void>;
|
|
147
|
-
/**
|
|
148
|
-
* Check if File System Access API is supported in the current browser.
|
|
149
|
-
* Use this to determine if you can use File System Access API features.
|
|
150
|
-
*
|
|
151
|
-
* @example
|
|
152
|
-
* if (isFileSystemAccessSupported()) {
|
|
153
|
-
* // Use File System Access API
|
|
154
|
-
* const handle = await window.showSaveFilePicker();
|
|
155
|
-
* } else {
|
|
156
|
-
* // Fall back to download link
|
|
157
|
-
* await convertFileToFile(file, "output.json", opts);
|
|
158
|
-
* }
|
|
159
|
-
*/
|
|
160
|
-
declare function isFileSystemAccessSupported(): boolean;
|
|
161
|
-
/**
|
|
162
|
-
* Convert a file and save it using File System Access API with a user-selected location.
|
|
163
|
-
* This provides a better UX than automatic downloads by letting users choose where to save.
|
|
164
|
-
* Falls back to regular download if File System Access API is not supported.
|
|
165
|
-
*
|
|
166
|
-
* @example
|
|
167
|
-
* const file = fileInput.files[0];
|
|
168
|
-
* await convertAndSave(file, {
|
|
169
|
-
* inputFormat: "csv",
|
|
170
|
-
* outputFormat: "json",
|
|
171
|
-
* suggestedName: "output.json"
|
|
172
|
-
* });
|
|
173
|
-
*/
|
|
174
|
-
declare function convertAndSave(file: File | Blob, opts?: BrowserConvertOptions & {
|
|
175
|
-
suggestedName?: string;
|
|
176
|
-
}): Promise<void>;
|
|
17
|
+
declare function convert(input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>, opts: ConvertOptions): Promise<Uint8Array>;
|
|
177
18
|
/**
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
* NOTE: This function requires Web Worker support and may not work in all environments
|
|
181
|
-
* (e.g., StackBlitz without WebContainers). For maximum compatibility, use the
|
|
182
|
-
* non-worker versions: convertFile(), convertFileStream(), etc.
|
|
183
|
-
*
|
|
184
|
-
* @param file File or Blob to convert
|
|
185
|
-
* @param opts Convert options (inputFormat, outputFormat, etc)
|
|
186
|
-
* @param onProgress Callback for progress updates
|
|
187
|
-
* @returns Promise<Uint8Array> with the converted result
|
|
19
|
+
* Convert a browser File or Blob and trigger download of the result
|
|
188
20
|
*/
|
|
189
|
-
declare function
|
|
190
|
-
bytesRead: number;
|
|
191
|
-
bytesWritten: number;
|
|
192
|
-
percentComplete: number;
|
|
193
|
-
recordsProcessed: number;
|
|
194
|
-
}) => void): Promise<Uint8Array>;
|
|
21
|
+
declare function convertFileToFile(inputFile: File | Blob, outputFilename: string, opts: ConvertOptions): Promise<void>;
|
|
195
22
|
/**
|
|
196
|
-
*
|
|
197
|
-
* This is useful for saving directly to disk using File System Access API.
|
|
198
|
-
*
|
|
199
|
-
* NOTE: This function requires Web Worker support and may not work in all environments.
|
|
200
|
-
* For maximum compatibility, use convertStreamToWritable() instead.
|
|
23
|
+
* Get file type configuration for browser file pickers
|
|
201
24
|
*/
|
|
202
|
-
declare function
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
recordsProcessed: number;
|
|
207
|
-
}) => void): Promise<void>;
|
|
25
|
+
declare function getFileTypeConfig(format: Format): Array<{
|
|
26
|
+
description: string;
|
|
27
|
+
accept: Record<string, string[]>;
|
|
28
|
+
}>;
|
|
208
29
|
|
|
209
|
-
export {
|
|
30
|
+
export { ConvertOptions, Format, convert, convertFileToFile, convertToString, getFileTypeConfig };
|