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.
Files changed (37) hide show
  1. package/README.md +49 -4
  2. package/dist/browser-stream-controller.d.ts +107 -0
  3. package/dist/browser-stream-controller.js +226 -0
  4. package/dist/browser-stream-controller.js.map +1 -0
  5. package/dist/browser.d.ts +16 -195
  6. package/dist/browser.js +78 -339
  7. package/dist/browser.js.map +1 -1
  8. package/dist/index-BpUN6Tdz.d.ts +440 -0
  9. package/dist/index.d.ts +1 -271
  10. package/dist/index.js +34 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/node-stream-controller.d.ts +133 -0
  13. package/dist/node-stream-controller.js +274 -0
  14. package/dist/node-stream-controller.js.map +1 -0
  15. package/dist/node.d.ts +3 -2
  16. package/dist/node.js +2 -0
  17. package/dist/node.js.map +1 -1
  18. package/dist/stream-controller.d.ts +1 -0
  19. package/dist/stream-controller.js +277 -0
  20. package/dist/stream-controller.js.map +1 -0
  21. package/dist/streaming-worker.js +1 -1
  22. package/dist/streaming-worker.js.map +1 -1
  23. package/dist/tests/stream-controller.test.js +237 -0
  24. package/dist/tests/stream-controller.test.js.map +1 -0
  25. package/dist/wasm/nodejs/convert_buddy.d.ts +6 -0
  26. package/dist/wasm/nodejs/convert_buddy.js +58 -28
  27. package/dist/wasm/nodejs/convert_buddy_bg.wasm +0 -0
  28. package/dist/wasm/nodejs/convert_buddy_bg.wasm.d.ts +4 -3
  29. package/dist/wasm/web/convert_buddy.d.ts +10 -3
  30. package/dist/wasm/web/convert_buddy.js +55 -27
  31. package/dist/wasm/web/convert_buddy_bg.wasm +0 -0
  32. package/dist/wasm/web/convert_buddy_bg.wasm.d.ts +4 -3
  33. package/package.json +3 -5
  34. package/dist/browser-core.d.ts +0 -196
  35. package/dist/browser-core.js +0 -787
  36. package/dist/browser-core.js.map +0 -1
  37. package/dist/wasm/nodejs/convert_buddy.cjs +0 -712
@@ -0,0 +1,440 @@
1
+ /**
2
+ * StreamController: High-level streaming API for ConvertBuddy
3
+ *
4
+ * Provides per-record callbacks, backpressure management, and pause/resume/abort
5
+ * controls for both browser and Node.js environments.
6
+ */
7
+
8
+ /**
9
+ * Options for StreamController
10
+ */
11
+ interface StreamControllerOptions extends Omit<ConvertBuddyOptions, 'onProgress'> {
12
+ /**
13
+ * Called with raw converted bytes before parsing into records.
14
+ * Useful for capturing the actual output format (CSV, XML, etc.)
15
+ */
16
+ onData?: (bytes: Uint8Array) => void;
17
+ /**
18
+ * Called for each parsed record (object) from the output stream.
19
+ * If the callback returns a Promise, the controller will await it before processing the next record.
20
+ * Return false to pause the stream (can resume later with resume()).
21
+ */
22
+ onRecord?: (record: any, index: number) => void | Promise<void> | boolean | Promise<boolean>;
23
+ /**
24
+ * Called periodically with statistics and record count.
25
+ * Use progressBatchSize to control how often this is called (every N records).
26
+ * This is different from ConvertBuddyOptions.onProgress which only provides stats.
27
+ */
28
+ onStreamProgress?: (stats: Stats, recordCount: number) => void;
29
+ /**
30
+ * Number of records to process before triggering onStreamProgress callback.
31
+ * Default: 1000
32
+ */
33
+ progressBatchSize?: number;
34
+ /**
35
+ * Auto-pause the stream while onRecord callback is executing.
36
+ * Default: true
37
+ */
38
+ autoPause?: boolean;
39
+ /**
40
+ * Output format for conversion. Recommended: "ndjson" for per-record streaming.
41
+ * Default: "ndjson"
42
+ */
43
+ outputFormat?: Format;
44
+ }
45
+ /**
46
+ * Represents a parsed record with metadata
47
+ */
48
+ interface ParsedRecord {
49
+ record: any;
50
+ index: number;
51
+ }
52
+ /**
53
+ * NDJSONSplitter - Splits a stream of bytes into complete NDJSON lines
54
+ *
55
+ * Handles partial lines across chunk boundaries and yields complete JSON objects.
56
+ * Optimized with pre-allocated growing buffer to avoid O(n²) allocations.
57
+ */
58
+ declare class NDJSONSplitter {
59
+ private buffer;
60
+ private bufferUsed;
61
+ private bufferCapacity;
62
+ private decoder;
63
+ constructor(initialCapacity?: number);
64
+ /**
65
+ * Push a chunk of bytes and get complete records
66
+ * @param chunk - Chunk of bytes to process
67
+ * @returns Array of parsed records
68
+ */
69
+ push(chunk: Uint8Array): any[];
70
+ /**
71
+ * Flush remaining buffer and get final records
72
+ * @returns Array of parsed records from remaining buffer
73
+ */
74
+ flush(): any[];
75
+ /**
76
+ * Reset the splitter state
77
+ */
78
+ reset(): void;
79
+ }
80
+ /**
81
+ * CSVSplitter - Splits CSV output into lines
82
+ *
83
+ * For CSV output, we yield each line as a string (header + data rows).
84
+ */
85
+ declare class CSVSplitter {
86
+ private buffer;
87
+ private decoder;
88
+ /**
89
+ * Push a chunk of bytes and get complete CSV lines
90
+ */
91
+ push(chunk: Uint8Array): string[];
92
+ /**
93
+ * Flush remaining buffer and get final lines
94
+ */
95
+ flush(): string[];
96
+ /**
97
+ * Reset the splitter state
98
+ */
99
+ reset(): void;
100
+ }
101
+ /**
102
+ * JSONSplitter - Handles JSON array output
103
+ *
104
+ * For JSON output, we expect an array of objects. We'll parse the complete
105
+ * JSON once and yield all records.
106
+ */
107
+ declare class JSONSplitter {
108
+ private buffer;
109
+ private decoder;
110
+ private yielded;
111
+ /**
112
+ * Push a chunk of bytes and accumulate
113
+ */
114
+ push(chunk: Uint8Array): any[];
115
+ /**
116
+ * Flush and parse complete JSON
117
+ */
118
+ flush(): any[];
119
+ /**
120
+ * Reset the splitter state
121
+ */
122
+ reset(): void;
123
+ }
124
+ /**
125
+ * XMLSplitter - Handles XML output by splitting on record elements
126
+ *
127
+ * This is a simplified splitter that looks for complete XML elements.
128
+ * For more robust XML parsing, consider using a proper XML parser.
129
+ */
130
+ declare class XMLSplitter {
131
+ private buffer;
132
+ private decoder;
133
+ private recordElement;
134
+ constructor(recordElement?: string);
135
+ /**
136
+ * Push a chunk of bytes and extract complete XML elements
137
+ */
138
+ push(chunk: Uint8Array): any[];
139
+ /**
140
+ * Very basic XML to JSON converter (for demonstration)
141
+ * In production, use a proper XML parser library
142
+ */
143
+ private xmlToJson;
144
+ /**
145
+ * Flush remaining buffer
146
+ */
147
+ flush(): any[];
148
+ /**
149
+ * Reset the splitter state
150
+ */
151
+ reset(): void;
152
+ }
153
+ /**
154
+ * Factory function to create appropriate splitter based on output format
155
+ */
156
+ declare function createSplitter(outputFormat: Format, config?: any): NDJSONSplitter | CSVSplitter | JSONSplitter | XMLSplitter;
157
+
158
+ type Format = "csv" | "ndjson" | "json" | "xml";
159
+ type DetectInput = Uint8Array | ArrayBuffer | string | ReadableStream<Uint8Array> | AsyncIterable<Uint8Array>;
160
+ type CsvDetection = {
161
+ delimiter: string;
162
+ fields: string[];
163
+ };
164
+ type XmlDetection = {
165
+ elements: string[];
166
+ recordElement?: string;
167
+ };
168
+ type JsonDetection = {
169
+ fields: string[];
170
+ };
171
+ type NdjsonDetection = {
172
+ fields: string[];
173
+ };
174
+ type StructureDetection = {
175
+ format: Format;
176
+ fields: string[];
177
+ delimiter?: string;
178
+ recordElement?: string;
179
+ };
180
+ type DetectOptions = {
181
+ maxBytes?: number;
182
+ debug?: boolean;
183
+ };
184
+ type ProgressCallback = (stats: Stats) => void;
185
+ type ConvertBuddyOptions = {
186
+ debug?: boolean;
187
+ profile?: boolean;
188
+ inputFormat?: Format | "auto";
189
+ outputFormat?: Format;
190
+ chunkTargetBytes?: number;
191
+ parallelism?: number;
192
+ maxMemoryMB?: number;
193
+ csvConfig?: CsvConfig;
194
+ xmlConfig?: XmlConfig;
195
+ transform?: TransformConfig;
196
+ onProgress?: ProgressCallback;
197
+ progressIntervalBytes?: number;
198
+ };
199
+ type ConvertOptions = {
200
+ inputFormat?: Format | "auto";
201
+ outputFormat: Format;
202
+ csvConfig?: CsvConfig;
203
+ xmlConfig?: XmlConfig;
204
+ transform?: TransformConfig;
205
+ onProgress?: ProgressCallback;
206
+ };
207
+ type CsvConfig = {
208
+ delimiter?: string;
209
+ quote?: string;
210
+ hasHeaders?: boolean;
211
+ trimWhitespace?: boolean;
212
+ };
213
+ type XmlConfig = {
214
+ recordElement?: string;
215
+ trimText?: boolean;
216
+ includeAttributes?: boolean;
217
+ expandEntities?: boolean;
218
+ };
219
+ type TransformMode = "replace" | "augment";
220
+ type Coerce = {
221
+ type: "string";
222
+ } | {
223
+ type: "i64";
224
+ } | {
225
+ type: "f64";
226
+ } | {
227
+ type: "bool";
228
+ } | {
229
+ type: "timestamp_ms";
230
+ format?: "iso8601" | "unix_ms" | "unix_s";
231
+ };
232
+ type FieldMap = {
233
+ targetFieldName: string;
234
+ originFieldName?: string;
235
+ required?: boolean;
236
+ defaultValue?: string | number | boolean | null;
237
+ coerce?: Coerce;
238
+ compute?: string;
239
+ };
240
+ type TransformConfig = {
241
+ mode?: TransformMode;
242
+ fields: FieldMap[];
243
+ onMissingField?: "error" | "null" | "drop";
244
+ onMissingRequired?: "error" | "abort";
245
+ onCoerceError?: "error" | "null" | "dropRecord";
246
+ };
247
+ type Stats = {
248
+ bytesIn: number;
249
+ bytesOut: number;
250
+ chunksIn: number;
251
+ recordsProcessed: number;
252
+ parseTimeMs: number;
253
+ transformTimeMs: number;
254
+ writeTimeMs: number;
255
+ maxBufferSize: number;
256
+ currentPartialSize: number;
257
+ throughputMbPerSec: number;
258
+ };
259
+ declare class ConvertBuddy {
260
+ private converter;
261
+ private debug;
262
+ private profile;
263
+ private aborted;
264
+ private paused;
265
+ private onProgress?;
266
+ private progressIntervalBytes;
267
+ private lastProgressBytes;
268
+ private globalConfig;
269
+ private initialized;
270
+ simd: boolean;
271
+ /**
272
+ * Create a new ConvertBuddy instance with global configuration.
273
+ * This is useful when you want to set memory limits, debug mode, or other global settings.
274
+ *
275
+ * @example
276
+ * const buddy = new ConvertBuddy({ maxMemoryMB: 512, debug: true });
277
+ * const result = await buddy.convert(input, { outputFormat: "json" });
278
+ */
279
+ constructor(opts?: ConvertBuddyOptions);
280
+ /**
281
+ * Convert input (string, Buffer, File, URL, etc.) to the desired output format.
282
+ * This is the main method for the new simplified API.
283
+ *
284
+ * @example
285
+ * // Auto-detect everything
286
+ * const buddy = new ConvertBuddy();
287
+ * const result = await buddy.convert("https://example.com/data.csv", { outputFormat: "json" });
288
+ *
289
+ * @example
290
+ * // With configuration
291
+ * const buddy = new ConvertBuddy({ maxMemoryMB: 512 });
292
+ * const result = await buddy.convert(file, { inputFormat: "csv", outputFormat: "json" });
293
+ */
294
+ convert(input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>, opts: ConvertOptions): Promise<Uint8Array>;
295
+ private convertFromUrl;
296
+ private convertFromString;
297
+ private convertFromBuffer;
298
+ private convertFromBufferParallel;
299
+ private convertUsingNodejsThreadPool;
300
+ private convertUsingWasmThreadPool;
301
+ private convertUsingJsParallelism;
302
+ private splitIntoChunks;
303
+ private convertFromFile;
304
+ private convertFromBlob;
305
+ private convertFromStream;
306
+ /**
307
+ * Legacy create method for backward compatibility.
308
+ * Prefer using the constructor: new ConvertBuddy(opts)
309
+ */
310
+ static create(opts?: ConvertBuddyOptions): Promise<ConvertBuddy>;
311
+ push(chunk: Uint8Array): Uint8Array;
312
+ /**
313
+ * Push a chunk and optionally get pre-parsed records.
314
+ * This is more efficient than parsing the output yourself.
315
+ *
316
+ * @param chunk - Input chunk to process
317
+ * @param includeRecords - If true, returns { output, records }, otherwise just output bytes
318
+ * @returns Either Uint8Array or { output: Uint8Array, records: any[] }
319
+ */
320
+ pushWithRecords(chunk: Uint8Array, includeRecords?: boolean): Uint8Array | {
321
+ output: Uint8Array;
322
+ records: any[];
323
+ };
324
+ finish(): Uint8Array;
325
+ stats(): Stats;
326
+ abort(): void;
327
+ pause(): void;
328
+ resume(): void;
329
+ isAborted(): boolean;
330
+ isPaused(): boolean;
331
+ }
332
+ declare function detectFormat(input: DetectInput, opts?: DetectOptions): Promise<Format | "unknown">;
333
+ declare function detectStructure(input: DetectInput, formatHint?: Format, opts?: DetectOptions): Promise<StructureDetection | null>;
334
+ declare function detectCsvFieldsAndDelimiter(input: DetectInput, opts?: DetectOptions): Promise<CsvDetection | null>;
335
+ declare function detectXmlElements(input: DetectInput, opts?: DetectOptions): Promise<XmlDetection | null>;
336
+ declare function autoDetectConfig(input: DetectInput, opts?: DetectOptions): Promise<{
337
+ format: Format | "unknown";
338
+ csvConfig?: CsvConfig;
339
+ xmlConfig?: XmlConfig;
340
+ }>;
341
+ declare class ConvertBuddyTransformStream extends TransformStream<Uint8Array, Uint8Array> {
342
+ constructor(opts?: ConvertBuddyOptions);
343
+ }
344
+ declare function convert(input: Uint8Array | string, opts?: ConvertBuddyOptions): Promise<Uint8Array>;
345
+ declare function convertToString(input: Uint8Array | string, opts?: ConvertBuddyOptions): Promise<string>;
346
+ /**
347
+ * Ultra-simple standalone convert function with auto-detection.
348
+ * Accepts any input type (URL, File, Buffer, string, stream) and automatically detects format.
349
+ *
350
+ * @example
351
+ * // From URL
352
+ * import { convertAny } from "convert-buddy-js";
353
+ * const result = await convertAny("https://example.com/data.csv", { outputFormat: "json" });
354
+ *
355
+ * @example
356
+ * // From File (browser)
357
+ * const file = fileInput.files[0];
358
+ * const result = await convertAny(file, { outputFormat: "ndjson" });
359
+ *
360
+ * @example
361
+ * // From string data
362
+ * const result = await convertAny('{"name":"Ada"}', { outputFormat: "csv" });
363
+ */
364
+ declare function convertAny(input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>, opts: ConvertOptions): Promise<Uint8Array>;
365
+ /**
366
+ * Ultra-simple standalone convert function that returns a string.
367
+ * Same as convertAny but decodes the output to a string.
368
+ *
369
+ * @example
370
+ * import { convertAnyToString } from "convert-buddy-js";
371
+ * const json = await convertAnyToString("https://example.com/data.csv", { outputFormat: "json" });
372
+ * console.log(JSON.parse(json));
373
+ */
374
+ declare function convertAnyToString(input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>, opts: ConvertOptions): Promise<string>;
375
+ /**
376
+ * Get MIME type for a given format
377
+ *
378
+ * @example
379
+ * const mimeType = getMimeType("json"); // "application/json"
380
+ */
381
+ declare function getMimeType(format: Format): string;
382
+ /**
383
+ * Get file extension for a given format (without the dot)
384
+ *
385
+ * @example
386
+ * const ext = getExtension("json"); // "json"
387
+ */
388
+ declare function getExtension(format: Format): string;
389
+ /**
390
+ * Get suggested filename for a converted file
391
+ *
392
+ * @param originalName - Original filename
393
+ * @param outputFormat - Target format
394
+ * @param includeTimestamp - Whether to include a timestamp (default: false)
395
+ *
396
+ * @example
397
+ * const name = getSuggestedFilename("data.csv", "json"); // "data.json"
398
+ * const name = getSuggestedFilename("data.csv", "json", true); // "data_converted_1234567890.json"
399
+ */
400
+ declare function getSuggestedFilename(originalName: string, outputFormat: Format, includeTimestamp?: boolean): string;
401
+ /**
402
+ * Get File System Access API file type configuration for showSaveFilePicker
403
+ *
404
+ * @example
405
+ * const types = getFileTypeConfig("json");
406
+ * const handle = await showSaveFilePicker({ types });
407
+ */
408
+ declare function getFileTypeConfig(format: Format): Array<{
409
+ description: string;
410
+ accept: Record<string, string[]>;
411
+ }>;
412
+ /**
413
+ * Check if WASM threading is supported in the current environment
414
+ * @returns true if SharedArrayBuffer and Atomics are available (required for WASM threads)
415
+ */
416
+ declare function isWasmThreadingSupported(): boolean;
417
+ /**
418
+ * Get the optimal number of worker threads based on CPU cores and WASM capabilities
419
+ * @returns Recommended thread count for optimal performance
420
+ */
421
+ declare function getOptimalThreadCount(): number;
422
+ /**
423
+ * Get current threading capabilities and configuration
424
+ * @returns Object with threading information
425
+ */
426
+ declare function getThreadingInfo(): {
427
+ wasmThreadingSupported: boolean;
428
+ customThreadPoolAvailable: boolean;
429
+ nodejsWasmThreading: boolean;
430
+ recommendedThreads: number;
431
+ currentThreads: number;
432
+ approach: string;
433
+ };
434
+ /**
435
+ * Backward compatibility alias for ConvertBuddy
436
+ * @deprecated Use ConvertBuddy instead
437
+ */
438
+ declare const Converter: typeof ConvertBuddy;
439
+
440
+ export { type StreamControllerOptions as A, type ParsedRecord as B, type ConvertOptions as C, type DetectInput as D, NDJSONSplitter as E, type Format as F, CSVSplitter as G, JSONSplitter as H, XMLSplitter as I, type JsonDetection as J, createSplitter as K, convert as L, convertToString as M, type NdjsonDetection as N, type ProgressCallback as P, type StructureDetection as S, type TransformMode as T, type XmlDetection as X, type ConvertBuddyOptions as a, type CsvDetection as b, type DetectOptions as c, type CsvConfig as d, type XmlConfig as e, type Coerce as f, type FieldMap as g, type TransformConfig as h, type Stats as i, ConvertBuddy as j, detectFormat as k, detectStructure as l, detectCsvFieldsAndDelimiter as m, detectXmlElements as n, autoDetectConfig as o, ConvertBuddyTransformStream as p, convertAny as q, convertAnyToString as r, getMimeType as s, getExtension as t, getSuggestedFilename as u, getFileTypeConfig as v, isWasmThreadingSupported as w, getOptimalThreadCount as x, getThreadingInfo as y, Converter as z };