convert-buddy-js 1.0.2 → 1.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/dist/index.d.ts CHANGED
@@ -115,6 +115,8 @@ interface BuddyStreamOptions<T = unknown> {
115
115
  csvConfig?: CsvConfig;
116
116
  xmlConfig?: XmlConfig;
117
117
  transform?: TransformConfig;
118
+ /** Pretty-print JSON array output. Default: true */
119
+ pretty?: boolean;
118
120
  /**
119
121
  * Number of records per batch. Default: 1000
120
122
  * Lower = more responsive, Higher = better throughput
@@ -226,6 +228,7 @@ type ConvertBuddyOptions = {
226
228
  csvConfig?: CsvConfig;
227
229
  xmlConfig?: XmlConfig;
228
230
  transform?: TransformConfig;
231
+ pretty?: boolean;
229
232
  onProgress?: ProgressCallback;
230
233
  progressIntervalBytes?: number;
231
234
  };
@@ -235,6 +238,7 @@ type ConvertOptions = {
235
238
  csvConfig?: CsvConfig;
236
239
  xmlConfig?: XmlConfig;
237
240
  transform?: TransformConfig;
241
+ pretty?: boolean;
238
242
  onProgress?: ProgressCallback;
239
243
  };
240
244
  declare class ConvertBuddy {
package/dist/index.js CHANGED
@@ -135,7 +135,8 @@ class ConvertBuddy {
135
135
  const mergedOpts = {
136
136
  ...this.globalConfig,
137
137
  ...opts,
138
- inputFormat: opts.inputFormat || this.globalConfig.inputFormat || "auto"
138
+ inputFormat: opts.inputFormat || this.globalConfig.inputFormat || "auto",
139
+ pretty: opts.pretty ?? this.globalConfig.pretty ?? true
139
140
  };
140
141
  if (typeof input === "string") {
141
142
  if (input.startsWith("http://") || input.startsWith("https://")) {
@@ -206,6 +207,7 @@ class ConvertBuddy {
206
207
  csvConfig: opts.csvConfig || this.globalConfig.csvConfig,
207
208
  xmlConfig: opts.xmlConfig || this.globalConfig.xmlConfig,
208
209
  transform: opts.transform || this.globalConfig.transform,
210
+ pretty: opts.pretty ?? this.globalConfig.pretty ?? true,
209
211
  debug: opts.debug ?? this.globalConfig.debug,
210
212
  profile: opts.profile ?? this.globalConfig.profile ?? true
211
213
  // Stats always enabled by default
@@ -217,6 +219,7 @@ class ConvertBuddy {
217
219
  csvConfig: mergedOpts.csvConfig,
218
220
  xmlConfig: mergedOpts.xmlConfig,
219
221
  transform: mergedOpts.transform,
222
+ pretty: mergedOpts.pretty,
220
223
  debug: mergedOpts.debug,
221
224
  profile: mergedOpts.profile
222
225
  });
@@ -634,7 +637,8 @@ class ConvertBuddy {
634
637
  // Enable stats tracking when profile is enabled
635
638
  csvConfig || null,
636
639
  opts.xmlConfig || null,
637
- opts.transform || null
640
+ opts.transform || null,
641
+ opts.pretty ?? true
638
642
  );
639
643
  } catch (err) {
640
644
  const errorMsg = typeof err === "string" ? err : err?.message || String(err);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Import types from shared types module\r\nimport type { \r\n Format, \r\n CsvConfig, \r\n XmlConfig, \r\n TransformConfig, \r\n TransformMode, \r\n Coerce, \r\n FieldMap, \r\n Stats,\r\n ConverterInterface,\r\n} from './types.js';\r\n\r\n// Import streaming types (will be re-exported at bottom of file)\r\nimport type { \r\n BuddyStreamOptions,\r\n BuddyController,\r\n BuddyStats,\r\n BuddyInput,\r\n} from './types.js';\r\n\r\n// Export core types for public API\r\nexport type { \r\n Format, \r\n CsvConfig, \r\n XmlConfig, \r\n TransformConfig, \r\n TransformMode, \r\n Coerce, \r\n FieldMap, \r\n Stats,\r\n BuddyStats,\r\n BuddyController,\r\n BuddyStreamOptions,\r\n} from './types.js';\r\n\r\n// Export stream controller types (implementation is platform-specific)\r\nexport type DetectInput =\r\n | Uint8Array\r\n | ArrayBuffer\r\n | string\r\n | ReadableStream<Uint8Array>\r\n | AsyncIterable<Uint8Array>;\r\n\r\nexport type CsvDetection = {\r\n delimiter: string;\r\n fields: string[];\r\n};\r\n\r\nexport type XmlDetection = {\r\n elements: string[];\r\n recordElement?: string;\r\n};\r\n\r\nexport type JsonDetection = {\r\n fields: string[];\r\n};\r\n\r\nexport type NdjsonDetection = {\r\n fields: string[];\r\n};\r\n\r\nexport type StructureDetection = {\r\n format: Format;\r\n fields: string[];\r\n delimiter?: string; // For CSV\r\n recordElement?: string; // For XML\r\n};\r\n\r\nexport type DetectOptions = {\r\n maxBytes?: number;\r\n debug?: boolean;\r\n};\r\n\r\nexport type ProgressCallback = (stats: Stats) => void;\r\n\r\nexport type ConvertBuddyOptions = {\r\n debug?: boolean;\r\n profile?: boolean;\r\n inputFormat?: Format | \"auto\";\r\n outputFormat?: Format;\r\n chunkTargetBytes?: number;\r\n parallelism?: number; // Node only - number of worker threads\r\n maxMemoryMB?: number; // Memory limit for conversions (future use)\r\n csvConfig?: CsvConfig;\r\n xmlConfig?: XmlConfig;\r\n transform?: TransformConfig;\r\n onProgress?: ProgressCallback;\r\n progressIntervalBytes?: number; // Trigger progress callback every N bytes (default: 1MB)\r\n};\r\n\r\nexport type ConvertOptions = {\r\n inputFormat?: Format | \"auto\";\r\n outputFormat: Format;\r\n csvConfig?: CsvConfig;\r\n xmlConfig?: XmlConfig;\r\n transform?: TransformConfig;\r\n onProgress?: ProgressCallback;\r\n};\r\n\r\ntype WasmModule = {\r\n default?: unknown;\r\n init: (debugEnabled: boolean) => void;\r\n Converter: new (debug: boolean) => {\r\n push: (chunk: Uint8Array) => Uint8Array;\r\n pushWithRecords: (chunk: Uint8Array, includeRecords: boolean) => Uint8Array | { output: Uint8Array; records: any[] };\r\n finish: () => Uint8Array;\r\n getStats: () => Stats;\r\n };\r\n detectFormat?: (sample: Uint8Array) => string | null | undefined;\r\n detectCsvFields?: (sample: Uint8Array) => CsvDetection | null | undefined;\r\n detectXmlElements?: (sample: Uint8Array) => XmlDetection | null | undefined;\r\n detectJsonFields?: (sample: Uint8Array) => JsonDetection | null | undefined;\r\n detectNdjsonFields?: (sample: Uint8Array) => NdjsonDetection | null | undefined;\r\n detectStructure?: (sample: Uint8Array, formatHint?: string) => StructureDetection | null | undefined;\r\n getSimdEnabled?: () => boolean;\r\n __wbg_set_wasm?: (wasm: unknown) => void;\r\n};\r\n\r\nlet wasmModuleInstance: WasmModule | null = null;\r\nlet wasmModuleLoadPromise: Promise<WasmModule> | null = null;\r\nlet wasmThreadingSupported = false;\r\nlet threadPool: any = null; // Custom WASM thread pool (browser)\r\nlet nodejsThreadPool: any = null; // Node.js specific thread pool\r\nconst utf8Decoder = new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true });\r\n\r\nfunction decodeUtf8(bytes: Uint8Array): string {\r\n return utf8Decoder.decode(bytes);\r\n}\r\n\r\n// Detect SharedArrayBuffer support for WASM threading\r\nfunction detectWasmThreadingSupport(): boolean {\r\n if (typeof SharedArrayBuffer === 'undefined') {\r\n return false;\r\n }\r\n \r\n // Test if we can actually create a SharedArrayBuffer\r\n try {\r\n new SharedArrayBuffer(1);\r\n return true;\r\n } catch (e) {\r\n return false;\r\n }\r\n}\r\n\r\nasync function loadWasmModule(): Promise<WasmModule> {\r\n // Return cached instance if already loaded\r\n if (wasmModuleInstance) {\r\n return wasmModuleInstance;\r\n }\r\n\r\n // If load is in progress, wait for it\r\n if (wasmModuleLoadPromise) {\r\n return wasmModuleLoadPromise;\r\n }\r\n\r\n // Start loading\r\n wasmModuleLoadPromise = (async () => {\r\n const isNode =\r\n typeof process !== \"undefined\" &&\r\n !!(process as any).versions?.node;\r\n\r\n // Detect threading support\r\n wasmThreadingSupported = detectWasmThreadingSupport();\r\n \r\n if (isNode) {\r\n // Use dynamic string construction to prevent bundlers (Vite, webpack, etc.) \r\n // from statically analyzing and trying to resolve the Node.js module.\r\n // This pattern makes the import string opaque to static analysis.\r\n const nodeModuleName = [\"node\", \"module\"].join(\":\");\r\n const nodeModule: any = await (new Function(\"m\", \"return import(m)\")(nodeModuleName));\r\n const createRequire = nodeModule.createRequire as any;\r\n const requireFn = createRequire ? createRequire(import.meta.url) : (module as any).createRequire?.(import.meta.url);\r\n const require = requireFn ?? (globalThis as any).require;\r\n const mod = require(\"../wasm-node.cjs\");\r\n return mod as WasmModule;\r\n }\r\n\r\n // @ts-expect-error - WASM module will be available at runtime in dist/wasm/web/\r\n const mod = (await import(\"./wasm/web/convert_buddy.js\")) as unknown as WasmModule;\r\n \r\n // Initialize threading if supported\r\n if (wasmThreadingSupported && (mod as any).initThreadPool) {\r\n try {\r\n const numThreads = Math.min(navigator.hardwareConcurrency || 4, 8);\r\n await (mod as any).initThreadPool(numThreads);\r\n console.log(`[convert-buddy] WASM threading initialized with ${numThreads} threads`);\r\n } catch (e) {\r\n console.warn('[convert-buddy] WASM threading initialization failed, using single-thread:', e);\r\n wasmThreadingSupported = false;\r\n }\r\n }\r\n \r\n return mod;\r\n })();\r\n\r\n try {\r\n wasmModuleInstance = await wasmModuleLoadPromise;\r\n return wasmModuleInstance;\r\n } finally {\r\n wasmModuleLoadPromise = null;\r\n }\r\n}\r\n\r\nlet wasmInitialized = false;\r\nlet wasmInitPromise: Promise<void> | null = null;\r\n\r\nasync function initWasm(debug: boolean): Promise<void> {\r\n // If already initialized, return immediately\r\n if (wasmInitialized) {\r\n return;\r\n }\r\n\r\n // If initialization is in progress, wait for it\r\n if (wasmInitPromise) {\r\n return wasmInitPromise;\r\n }\r\n\r\n // Start initialization\r\n wasmInitPromise = (async () => {\r\n const wasmModule = await loadWasmModule();\r\n\r\n if (typeof wasmModule.default === \"function\") {\r\n await (wasmModule.default as () => Promise<void>)();\r\n }\r\n\r\n wasmModule.init(debug);\r\n \r\n // Note: Node.js enhanced threading is handled at the JavaScript level\r\n // No WASM thread pool initialization needed\r\n \r\n wasmInitialized = true;\r\n })();\r\n\r\n try {\r\n await wasmInitPromise;\r\n } finally {\r\n wasmInitPromise = null;\r\n }\r\n}\r\n\r\n/**\r\n * Warn if using non-streaming approach with large files\r\n */\r\nfunction warnIfLargeFile(sizeBytes: number, methodName: string = \"convert\"): void {\r\n const SIZE_THRESHOLD = 10 * 1024 * 1024; // 10MB\r\n \r\n if (sizeBytes >= SIZE_THRESHOLD) {\r\n const sizeMB = (sizeBytes / 1024 / 1024).toFixed(1);\r\n console.warn(\r\n `[convert-buddy-js] WARNING: Using ${methodName}() with a large file (${sizeMB}MB). ` +\r\n `This method is intended for small files and may cause memory issues with large files. ` +\r\n `For better performance and memory management with files of any size, use the streaming API: ` +\r\n `ConvertBuddy.create() with push()/finish() methods.`\r\n );\r\n }\r\n}\r\n\r\nexport class ConvertBuddy {\r\n private converter: any;\r\n private debug: boolean;\r\n private aborted: boolean = false;\r\n private paused: boolean = false;\r\n private onProgress?: ProgressCallback;\r\n private progressIntervalBytes: number;\r\n private lastProgressBytes: number = 0;\r\n private globalConfig: ConvertBuddyOptions;\r\n private initialized: boolean = false;\r\n public simd: boolean;\r\n\r\n /**\r\n * Create a new ConvertBuddy instance with global configuration.\r\n * This is useful when you want to set memory limits, debug mode, or other global settings.\r\n * \r\n * @example\r\n * const buddy = new ConvertBuddy({ maxMemoryMB: 512, debug: true });\r\n * const result = await buddy.convert(input, { outputFormat: \"json\" });\r\n */\r\n constructor(opts: ConvertBuddyOptions = {}) {\r\n // Initialize basic properties\r\n this.debug = !!opts.debug;\r\n this.simd = false; // Will be set on first convert\r\n this.globalConfig = opts;\r\n this.progressIntervalBytes = opts.progressIntervalBytes || 1024 * 1024;\r\n this.onProgress = opts.onProgress;\r\n this.converter = null; // Will be initialized lazily\r\n this.initialized = false;\r\n }\r\n\r\n /**\r\n * Convert input (string, Buffer, File, URL, etc.) to the desired output format.\r\n * This is the main method for the new simplified API.\r\n * \r\n * @example\r\n * // Auto-detect everything\r\n * const buddy = new ConvertBuddy();\r\n * const result = await buddy.convert(\"https://example.com/data.csv\", { outputFormat: \"json\" });\r\n * \r\n * @example\r\n * // With configuration\r\n * const buddy = new ConvertBuddy({ maxMemoryMB: 512 });\r\n * const result = await buddy.convert(file, { inputFormat: \"csv\", outputFormat: \"json\" });\r\n */\r\n async convert(\r\n input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>,\r\n opts: ConvertOptions\r\n ): Promise<Uint8Array> {\r\n // Merge global and local options\r\n const mergedOpts: ConvertBuddyOptions = {\r\n ...this.globalConfig,\r\n ...opts,\r\n inputFormat: opts.inputFormat || this.globalConfig.inputFormat || \"auto\",\r\n };\r\n\r\n // Detect input type and convert accordingly\r\n if (typeof input === \"string\") {\r\n // Could be URL or raw data\r\n if (input.startsWith(\"http://\") || input.startsWith(\"https://\")) {\r\n // Fetch from URL\r\n return this.convertFromUrl(input, mergedOpts);\r\n } else {\r\n // Treat as raw data\r\n return this.convertFromString(input, mergedOpts);\r\n }\r\n } else if (input instanceof Uint8Array) {\r\n return this.convertFromBuffer(input, mergedOpts);\r\n } else if (typeof File !== \"undefined\" && input instanceof File) {\r\n return this.convertFromFile(input as File, mergedOpts);\r\n } else if (typeof Blob !== \"undefined\" && input instanceof Blob) {\r\n return this.convertFromBlob(input as Blob, mergedOpts);\r\n } else if (typeof ReadableStream !== \"undefined\" && input instanceof ReadableStream) {\r\n return this.convertFromStream(input, mergedOpts);\r\n } else {\r\n throw new Error(\"Unsupported input type\");\r\n }\r\n }\r\n\r\n /**\r\n * Stream conversion: returns controller immediately with done promise.\r\n * \r\n * Features:\r\n * - Fire-and-forget: call stream() and ignore done\r\n * - Await completion: await controller.done\r\n * - Automatic backpressure: if onRecords returns a Promise, processing waits\r\n * - Manual pause/resume also supported\r\n * \r\n * @example\r\n * // Primary pattern: onRecords callback with automatic backpressure\r\n * const buddy = cb.stream(csvData, {\r\n * recordBatchSize: 1000,\r\n * onRecords: async (buddy, records, stats, count) => {\r\n * console.log(`Batch of ${records.length} records, total: ${count}`);\r\n * await saveToDatabase(records); // Automatic backpressure\r\n * },\r\n * onError: (err, buddy, stats) => console.error('Failed:', err),\r\n * onDone: (stats) => console.log('Complete:', stats),\r\n * });\r\n * \r\n * // Optionally await completion\r\n * const finalStats = await buddy.done;\r\n * \r\n * @example\r\n * // Fire-and-forget (no await)\r\n * cb.stream(csvData, {\r\n * onRecords: (buddy, records) => queueForProcessing(records),\r\n * onError: (err) => console.error(err),\r\n * });\r\n * \r\n * @example\r\n * // With raw output streaming\r\n * const chunks: Uint8Array[] = [];\r\n * const buddy = cb.stream(csvData, {\r\n * outputFormat: 'ndjson',\r\n * onData: (chunk) => chunks.push(chunk),\r\n * onRecords: async (buddy, records, stats, count) => {\r\n * await processRecords(records);\r\n * },\r\n * });\r\n * await buddy.done;\r\n */\r\n stream<T = unknown>(\r\n input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>,\r\n opts: BuddyStreamOptions<T> = {}\r\n ): BuddyController {\r\n // Merge global and local options\r\n const mergedOpts: BuddyStreamOptions<T> = {\r\n ...opts,\r\n inputFormat: opts.inputFormat || this.globalConfig.inputFormat || \"auto\",\r\n outputFormat: opts.outputFormat || this.globalConfig.outputFormat,\r\n csvConfig: opts.csvConfig || this.globalConfig.csvConfig,\r\n xmlConfig: opts.xmlConfig || this.globalConfig.xmlConfig,\r\n transform: opts.transform || this.globalConfig.transform,\r\n debug: opts.debug ?? this.globalConfig.debug,\r\n profile: opts.profile ?? this.globalConfig.profile ?? true, // Stats always enabled by default\r\n };\r\n\r\n // Create converter factory that uses ConvertBuddy.create\r\n const converterFactory = async () => {\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: mergedOpts.inputFormat,\r\n outputFormat: mergedOpts.outputFormat,\r\n csvConfig: mergedOpts.csvConfig,\r\n xmlConfig: mergedOpts.xmlConfig,\r\n transform: mergedOpts.transform,\r\n debug: mergedOpts.debug,\r\n profile: mergedOpts.profile,\r\n });\r\n \r\n // Return a wrapper that implements ConverterInterface\r\n return {\r\n push: (chunk: Uint8Array) => buddy.push(chunk),\r\n pushWithRecords: (chunk: Uint8Array, includeRecords: boolean) => buddy.pushWithRecords(chunk, includeRecords),\r\n finish: () => buddy.finish(),\r\n getStats: () => buddy.stats(),\r\n } as ConverterInterface;\r\n };\r\n\r\n return __createBuddyController(input, converterFactory, mergedOpts as BuddyStreamOptions);\r\n }\r\n\r\n private async convertFromUrl(url: string, opts: ConvertBuddyOptions): Promise<Uint8Array> {\r\n const response = await fetch(url);\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch ${url}: ${response.statusText}`);\r\n }\r\n \r\n const stream = response.body;\r\n if (!stream) {\r\n throw new Error(\"Response body is null\");\r\n }\r\n\r\n return this.convertFromStream(stream, opts);\r\n }\r\n\r\n private async convertFromString(input: string, opts: ConvertBuddyOptions): Promise<Uint8Array> {\r\n const inputBytes = new TextEncoder().encode(input);\r\n // Don't warn here - will warn in convertFromBuffer\r\n return this.convertFromBuffer(inputBytes, opts);\r\n }\r\n\r\n private async convertFromBuffer(input: Uint8Array, opts: ConvertBuddyOptions, skipWarning = false): Promise<Uint8Array> {\r\n if (!skipWarning) {\r\n warnIfLargeFile(input.length, \"convert\");\r\n }\r\n \r\n // Use WASM threading for large inputs when available\r\n const useWasmThreading = wasmThreadingSupported && input.length > 256 * 1024; // 256KB threshold\r\n \r\n if (useWasmThreading && opts.debug) {\r\n console.log('[convert-buddy] Using WASM threading for parallel processing');\r\n }\r\n \r\n // Check if we should use JavaScript-level parallelism as fallback\r\n if (!useWasmThreading && opts.parallelism && opts.parallelism > 1 && input.length > 512 * 1024) {\r\n if (opts.debug) {\r\n console.log('[convert-buddy] WASM threading not available, using JavaScript parallelism');\r\n }\r\n return this.convertFromBufferParallel(input, opts);\r\n }\r\n\r\n // Handle auto-detection\r\n let actualOpts = { ...opts };\r\n \r\n if (opts.inputFormat === \"auto\") {\r\n const detected = await autoDetectConfig(input, { debug: opts.debug });\r\n \r\n if (detected.format !== \"unknown\") {\r\n actualOpts.inputFormat = detected.format as Format;\r\n \r\n if (detected.csvConfig) {\r\n actualOpts.csvConfig = opts.csvConfig ? { ...detected.csvConfig, ...opts.csvConfig } : detected.csvConfig;\r\n }\r\n \r\n if (detected.xmlConfig) {\r\n actualOpts.xmlConfig = opts.xmlConfig ? { ...detected.xmlConfig, ...opts.xmlConfig } : detected.xmlConfig;\r\n }\r\n \r\n if (opts.debug) {\r\n console.log(\"[convert-buddy] Auto-detected format:\", detected.format);\r\n }\r\n } else {\r\n throw new Error(\"Could not auto-detect input format. Please specify inputFormat explicitly.\");\r\n }\r\n }\r\n\r\n const buddy = await ConvertBuddy.create(actualOpts);\r\n const output = buddy.push(input);\r\n const final = buddy.finish();\r\n\r\n // Combine outputs\r\n const result = new Uint8Array(output.length + final.length);\r\n result.set(output, 0);\r\n result.set(final, output.length);\r\n\r\n if (opts.profile) {\r\n const stats = buddy.stats();\r\n console.log(\"[convert-buddy] Performance Stats:\", stats);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private async convertFromBufferParallel(input: Uint8Array, opts: ConvertBuddyOptions): Promise<Uint8Array> {\r\n // Only use parallel processing for large inputs and supported conversions\r\n const parallelThreshold = 512 * 1024; // 512KB (lowered threshold for better parallelism)\r\n const maxConcurrency = Math.min(\r\n typeof navigator !== \"undefined\" && navigator.hardwareConcurrency\r\n ? navigator.hardwareConcurrency\r\n : 4,\r\n 8\r\n );\r\n \r\n if (input.length < parallelThreshold || !opts.parallelism || opts.parallelism < 2) {\r\n return this.convertFromBuffer(input, { ...opts, parallelism: 1 }, true); // Skip warning on recursive call\r\n }\r\n\r\n // Extended support for parallel processing\r\n const supportedConversions = [\r\n { input: \"csv\", output: \"ndjson\" },\r\n { input: \"csv\", output: \"json\" },\r\n { input: \"ndjson\", output: \"json\" },\r\n { input: \"ndjson\", output: \"csv\" },\r\n { input: \"ndjson\", output: \"ndjson\" }, // passthrough optimization\r\n { input: \"json\", output: \"ndjson\" },\r\n { input: \"json\", output: \"csv\" },\r\n ];\r\n\r\n const isSupported = supportedConversions.some(\r\n conv => conv.input === opts.inputFormat && conv.output === opts.outputFormat\r\n );\r\n\r\n if (!isSupported) {\r\n if (opts.debug) {\r\n console.log(`[convert-buddy] Parallel processing not supported for ${opts.inputFormat} → ${opts.outputFormat}, using sequential`);\r\n }\r\n return this.convertFromBuffer(input, { ...opts, parallelism: 1 });\r\n }\r\n\r\n try {\r\n const actualThreads = Math.min(maxConcurrency, opts.parallelism || maxConcurrency);\r\n const isNodejs = typeof window === \"undefined\" && typeof process !== \"undefined\";\r\n \r\n if (opts.debug) {\r\n const threadingType = isNodejs ? 'Node.js WASM threading' : 'Browser custom threading';\r\n console.log(`[convert-buddy] Using ${threadingType} with ${actualThreads} threads`);\r\n }\r\n\r\n if (isNodejs) {\r\n // Try enhanced Node.js threading first\r\n if (!nodejsThreadPool) {\r\n try {\r\n const { NodejsThreadPool } = await import('./nodejs-thread-pool');\r\n nodejsThreadPool = new NodejsThreadPool({\r\n maxWorkers: actualThreads,\r\n wasmPath: '../wasm-node.cjs'\r\n });\r\n await nodejsThreadPool.initialize();\r\n } catch (error) {\r\n if (opts.debug) {\r\n console.log('[convert-buddy] Node.js thread pool creation failed, using JS parallelism:', error);\r\n }\r\n }\r\n }\r\n\r\n if (nodejsThreadPool) {\r\n return this.convertUsingNodejsThreadPool(input, opts, actualThreads);\r\n } else {\r\n return this.convertUsingJsParallelism(input, opts, actualThreads);\r\n }\r\n } else {\r\n // Browser: Create custom thread pool for WASM-level parallelism\r\n if (!threadPool) {\r\n const { WasmThreadPool } = await import('./thread-pool');\r\n threadPool = new WasmThreadPool({\r\n maxWorkers: actualThreads,\r\n wasmPath: './wasm/web/convert_buddy.js'\r\n });\r\n await threadPool.initialize();\r\n }\r\n\r\n return this.convertUsingWasmThreadPool(input, opts, actualThreads);\r\n }\r\n \r\n } catch (error) {\r\n if (opts.debug) {\r\n console.warn(`[convert-buddy] Parallel processing failed, falling back to sequential:`, error);\r\n }\r\n return this.convertFromBuffer(input, { ...opts, parallelism: 1 });\r\n }\r\n }\r\n\r\n private async convertUsingNodejsThreadPool(input: Uint8Array, opts: ConvertBuddyOptions, numThreads: number): Promise<Uint8Array> {\r\n const { chunkDataNodejs, mergeResultsNodejs } = await import('./nodejs-thread-pool');\r\n \r\n if (opts.debug) {\r\n console.log(`[convert-buddy] Processing with enhanced Node.js threading (${numThreads} workers)`);\r\n }\r\n\r\n // Use optimized chunking for Node.js\r\n const chunks = chunkDataNodejs(input, numThreads);\r\n \r\n // Process chunks using Node.js worker threads\r\n const results = await nodejsThreadPool!.processChunks('convert', chunks, {\r\n outputFormat: opts.outputFormat,\r\n inputFormat: opts.inputFormat,\r\n csvConfig: opts.csvConfig,\r\n xmlConfig: opts.xmlConfig,\r\n debug: false // Disable debug in workers to reduce noise\r\n });\r\n\r\n // Merge results intelligently based on output format\r\n const merged = mergeResultsNodejs(results, opts.outputFormat!);\r\n \r\n if (opts.debug) {\r\n console.log(`[convert-buddy] Node.js threading completed: ${chunks.length} chunks, ${merged.length} bytes`);\r\n }\r\n\r\n return merged;\r\n }\r\n\r\n private async convertUsingWasmThreadPool(input: Uint8Array, opts: ConvertBuddyOptions, numThreads: number): Promise<Uint8Array> {\r\n const inputStr = decodeUtf8(input);\r\n \r\n // Import chunking utilities\r\n const { chunkData, mergeResults } = await import('./thread-pool');\r\n const chunks = chunkData(inputStr, numThreads);\r\n \r\n if (opts.debug) {\r\n console.log(`[convert-buddy] Processing ${chunks.length} chunks with WASM thread pool`);\r\n }\r\n\r\n // Determine method based on conversion type\r\n let method: string;\r\n const conversion = `${opts.inputFormat}_to_${opts.outputFormat}`;\r\n switch (conversion) {\r\n case 'csv_to_ndjson':\r\n case 'csv_to_json':\r\n method = 'parseCSV';\r\n break;\r\n case 'ndjson_to_csv':\r\n case 'ndjson_to_json':\r\n method = 'parseNDJSON';\r\n break;\r\n case 'json_to_csv':\r\n case 'json_to_ndjson':\r\n method = 'parseJSON';\r\n break;\r\n default:\r\n throw new Error(`Unsupported conversion: ${conversion}`);\r\n }\r\n\r\n // Process chunks in parallel using thread pool\r\n const results = await threadPool!.processChunks(method, chunks, {\r\n outputFormat: opts.outputFormat,\r\n csvConfig: opts.csvConfig,\r\n xmlConfig: opts.xmlConfig,\r\n debug: opts.debug\r\n });\r\n\r\n // Merge results intelligently based on output format\r\n const merged = mergeResults(results, opts.outputFormat!);\r\n return new TextEncoder().encode(merged);\r\n }\r\n\r\n private async convertUsingJsParallelism(input: Uint8Array, opts: ConvertBuddyOptions, numThreads: number): Promise<Uint8Array> {\r\n // Split input into chunks based on line boundaries for CSV/NDJSON\r\n const chunks = this.splitIntoChunks(input, Math.max(1, Math.floor(input.length / numThreads)));\r\n \r\n if (opts.debug) {\r\n console.log(`[convert-buddy] Processing ${chunks.length} chunks with JS-level parallelism`);\r\n }\r\n \r\n // Process chunks in parallel with improved coordination\r\n const chunkPromises = chunks.map(async (chunk, index) => {\r\n const chunkOpts = { ...opts, parallelism: 1 }; // Disable recursion\r\n \r\n // For CSV with headers, only the first chunk should process headers\r\n if (opts.inputFormat === \"csv\" && index > 0) {\r\n chunkOpts.csvConfig = { ...chunkOpts.csvConfig, hasHeaders: false };\r\n }\r\n \r\n const chunkBuddy = await ConvertBuddy.create(chunkOpts);\r\n const output = chunkBuddy.push(chunk);\r\n const final = chunkBuddy.finish();\r\n \r\n // Combine chunk output\r\n const result = new Uint8Array(output.length + final.length);\r\n result.set(output, 0);\r\n result.set(final, output.length);\r\n \r\n return result;\r\n });\r\n\r\n const chunkResults = await Promise.all(chunkPromises);\r\n\r\n // Combine results more efficiently\r\n const totalLength = chunkResults.reduce((sum, chunk) => sum + chunk.length, 0);\r\n const result = new Uint8Array(totalLength);\r\n \r\n let offset = 0;\r\n for (const chunk of chunkResults) {\r\n result.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n\r\n if (opts.debug) {\r\n console.log(`[convert-buddy] JS parallel processing completed: ${chunks.length} chunks, ${totalLength} bytes`);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private splitIntoChunks(input: Uint8Array, targetChunkSize: number): Uint8Array[] {\r\n if (input.length <= targetChunkSize) {\r\n return [input];\r\n }\r\n\r\n const chunks: Uint8Array[] = [];\r\n let start = 0;\r\n\r\n while (start < input.length) {\r\n let end = Math.min(start + targetChunkSize, input.length);\r\n \r\n // Try to find a line boundary within a reasonable range\r\n if (end < input.length) {\r\n const searchStart = Math.max(start + targetChunkSize - 1024, start);\r\n const searchEnd = Math.min(end + 1024, input.length);\r\n \r\n // Look for newline\r\n for (let i = searchEnd - 1; i >= searchStart; i--) {\r\n if (input[i] === 0x0A) { // '\\n'\r\n end = i + 1;\r\n break;\r\n }\r\n }\r\n }\r\n \r\n chunks.push(input.slice(start, end));\r\n start = end;\r\n }\r\n\r\n return chunks;\r\n }\r\n\r\n private async convertFromFile(file: File, opts: ConvertBuddyOptions): Promise<Uint8Array> {\r\n return this.convertFromBlob(file, opts);\r\n }\r\n\r\n private async convertFromBlob(blob: Blob, opts: ConvertBuddyOptions): Promise<Uint8Array> {\r\n warnIfLargeFile(blob.size, \"convert\");\r\n \r\n // Handle auto-detection\r\n let actualOpts = { ...opts };\r\n \r\n if (opts.inputFormat === \"auto\") {\r\n const sampleSize = 256 * 1024; // 256KB\r\n const sampleBlob = blob.slice(0, sampleSize);\r\n const sampleBuffer = await sampleBlob.arrayBuffer();\r\n const sample = new Uint8Array(sampleBuffer as ArrayBuffer);\r\n \r\n const detected = await autoDetectConfig(sample, { debug: opts.debug });\r\n \r\n if (detected.format !== \"unknown\") {\r\n actualOpts.inputFormat = detected.format as Format;\r\n \r\n if (detected.csvConfig) {\r\n actualOpts.csvConfig = opts.csvConfig ? { ...detected.csvConfig, ...opts.csvConfig } : detected.csvConfig;\r\n }\r\n \r\n if (detected.xmlConfig) {\r\n actualOpts.xmlConfig = opts.xmlConfig ? { ...detected.xmlConfig, ...opts.xmlConfig } : detected.xmlConfig;\r\n }\r\n \r\n if (opts.debug) {\r\n console.log(\"[convert-buddy] Auto-detected format:\", detected.format);\r\n }\r\n } else {\r\n throw new Error(\"Could not auto-detect input format. Please specify inputFormat explicitly.\");\r\n }\r\n }\r\n\r\n const buddy = await ConvertBuddy.create(actualOpts);\r\n \r\n // Read blob as stream and process\r\n const stream = blob.stream();\r\n const reader = stream.getReader();\r\n \r\n const outputs: Uint8Array[] = [];\r\n \r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n \r\n const output = buddy.push(value);\r\n if (output.length > 0) {\r\n outputs.push(output);\r\n }\r\n }\r\n \r\n const final = buddy.finish();\r\n if (final.length > 0) {\r\n outputs.push(final);\r\n }\r\n \r\n // Combine all outputs\r\n const totalLength = outputs.reduce((sum, arr) => sum + arr.length, 0);\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const output of outputs) {\r\n result.set(output, offset);\r\n offset += output.length;\r\n }\r\n \r\n if (opts.profile) {\r\n const stats = buddy.stats();\r\n console.log(\"[convert-buddy] Performance Stats:\", stats);\r\n }\r\n \r\n return result;\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n }\r\n\r\n private async convertFromStream(stream: ReadableStream<Uint8Array>, opts: ConvertBuddyOptions): Promise<Uint8Array> {\r\n // Handle auto-detection by reading a sample first\r\n let actualOpts = { ...opts };\r\n let firstChunks: Uint8Array[] = [];\r\n let totalSampleBytes = 0;\r\n const maxSampleSize = 256 * 1024; // 256KB\r\n \r\n if (opts.inputFormat === \"auto\") {\r\n const reader = stream.getReader();\r\n \r\n try {\r\n while (totalSampleBytes < maxSampleSize) {\r\n const { done, value } = await reader.read();\r\n if (done || !value) break;\r\n \r\n firstChunks.push(value);\r\n totalSampleBytes += value.length;\r\n }\r\n \r\n // Concatenate sample\r\n const sample = new Uint8Array(totalSampleBytes);\r\n let offset = 0;\r\n for (const chunk of firstChunks) {\r\n sample.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n \r\n const detected = await autoDetectConfig(sample, { debug: opts.debug });\r\n \r\n if (detected.format !== \"unknown\") {\r\n actualOpts.inputFormat = detected.format as Format;\r\n \r\n if (detected.csvConfig) {\r\n actualOpts.csvConfig = opts.csvConfig ? { ...detected.csvConfig, ...opts.csvConfig } : detected.csvConfig;\r\n }\r\n \r\n if (detected.xmlConfig) {\r\n actualOpts.xmlConfig = opts.xmlConfig ? { ...detected.xmlConfig, ...opts.xmlConfig } : detected.xmlConfig;\r\n }\r\n \r\n if (opts.debug) {\r\n console.log(\"[convert-buddy] Auto-detected format:\", detected.format);\r\n }\r\n } else {\r\n throw new Error(\"Could not auto-detect input format. Please specify inputFormat explicitly.\");\r\n }\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n }\r\n\r\n const buddy = await ConvertBuddy.create(actualOpts);\r\n \r\n // Process buffered chunks from auto-detection\r\n const outputs: Uint8Array[] = [];\r\n for (const chunk of firstChunks) {\r\n const output = buddy.push(chunk);\r\n if (output.length > 0) {\r\n outputs.push(output);\r\n }\r\n }\r\n \r\n // Continue with the rest of the stream\r\n const reader = stream.getReader();\r\n \r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n \r\n const output = buddy.push(value);\r\n if (output.length > 0) {\r\n outputs.push(output);\r\n }\r\n }\r\n \r\n const final = buddy.finish();\r\n if (final.length > 0) {\r\n outputs.push(final);\r\n }\r\n \r\n // Combine all outputs\r\n const totalLength = outputs.reduce((sum, arr) => sum + arr.length, 0);\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const output of outputs) {\r\n result.set(output, offset);\r\n offset += output.length;\r\n }\r\n \r\n if (opts.profile) {\r\n const stats = buddy.stats();\r\n console.log(\"[convert-buddy] Performance Stats:\", stats);\r\n }\r\n \r\n return result;\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n }\r\n\r\n /**\r\n * Legacy create method for backward compatibility.\r\n * Prefer using the constructor: new ConvertBuddy(opts)\r\n */\r\n static async create(opts: ConvertBuddyOptions = {}): Promise<ConvertBuddy> {\r\n const debug = !!opts.debug;\r\n const profile = opts.profile !== false; // Stats always enabled by default\r\n\r\n // Initialize WASM once (singleton)\r\n await initWasm(debug);\r\n\r\n const wasmModule = await loadWasmModule();\r\n\r\n // Handle auto-detection\r\n let inputFormat = opts.inputFormat;\r\n let csvConfig = opts.csvConfig;\r\n\r\n // We can't auto-detect without data, so we'll defer this to push()\r\n // For now, just validate the format if it's not \"auto\"\r\n if (inputFormat === \"auto\") {\r\n // Auto-detection will be handled on first push()\r\n inputFormat = undefined;\r\n }\r\n\r\n // Optimize chunk size for better WASM performance\r\n // Larger chunks reduce boundary crossing overhead\r\n // Default: 512KB (was 1MB), but can be customized\r\n const chunkTargetBytes = opts.chunkTargetBytes || (512 * 1024);\r\n\r\n let converter;\r\n if (inputFormat && opts.outputFormat) {\r\n // Use withConfig for custom formats\r\n const Converter = (wasmModule as any).Converter;\r\n try {\r\n converter = Converter.withConfig(\r\n debug,\r\n inputFormat,\r\n opts.outputFormat,\r\n chunkTargetBytes,\r\n profile, // Enable stats tracking when profile is enabled\r\n csvConfig || null,\r\n opts.xmlConfig || null,\r\n opts.transform || null\r\n );\r\n } catch (err: any) {\r\n // Enhance error message for common issues\r\n const errorMsg = typeof err === 'string' ? err : err?.message || String(err);\r\n if (errorMsg.includes('Invalid output format')) {\r\n const validFormats = ['csv', 'json', 'ndjson', 'xml'];\r\n throw new Error(`Invalid outputFormat: \"${opts.outputFormat}\". Must be one of: ${validFormats.join(', ')}`);\r\n } else if (errorMsg.includes('Invalid input format')) {\r\n const validFormats = ['csv', 'json', 'ndjson', 'xml', 'auto'];\r\n throw new Error(`Invalid inputFormat: \"${inputFormat}\". Must be one of: ${validFormats.join(', ')}`);\r\n }\r\n throw new Error(`Configuration error: ${errorMsg}`);\r\n }\r\n } else {\r\n converter = new wasmModule.Converter(debug);\r\n }\r\n\r\n // Check if SIMD is enabled\r\n const simdEnabled = (wasmModule as any).getSimdEnabled?.() ?? false;\r\n\r\n if (debug) console.log(\"[convert-buddy-js] initialized with chunkTargetBytes:\", chunkTargetBytes, \"simd:\", simdEnabled, opts);\r\n \r\n // Create instance using constructor and set internal properties\r\n const instance = new ConvertBuddy(opts);\r\n instance.converter = converter;\r\n instance.simd = simdEnabled;\r\n instance.initialized = true;\r\n \r\n return instance;\r\n }\r\n\r\n push(chunk: Uint8Array): Uint8Array {\r\n if (this.aborted) {\r\n throw new Error(\"Conversion has been aborted\");\r\n }\r\n\r\n if (this.paused) {\r\n throw new Error(\"Conversion is paused. Call resume() before pushing more data.\");\r\n }\r\n\r\n if (this.debug) console.log(\"[convert-buddy-js] push\", chunk.byteLength);\r\n const output = this.converter.push(chunk);\r\n\r\n // Check if we should trigger progress callback\r\n if (this.onProgress) {\r\n const stats = this.stats();\r\n if (stats.bytesIn - this.lastProgressBytes >= this.progressIntervalBytes) {\r\n this.onProgress(stats);\r\n this.lastProgressBytes = stats.bytesIn;\r\n }\r\n }\r\n\r\n return output;\r\n }\r\n\r\n /**\r\n * Push a chunk and optionally get pre-parsed records.\r\n * This is more efficient than parsing the output yourself.\r\n * \r\n * @param chunk - Input chunk to process\r\n * @param includeRecords - If true, returns { output, records }, otherwise just output bytes\r\n * @returns Either Uint8Array or { output: Uint8Array, records: any[] }\r\n */\r\n pushWithRecords(chunk: Uint8Array, includeRecords: boolean = true): Uint8Array | { output: Uint8Array; records: any[] } {\r\n if (this.aborted) {\r\n throw new Error(\"Conversion has been aborted\");\r\n }\r\n\r\n if (this.paused) {\r\n throw new Error(\"Conversion is paused. Call resume() before pushing more data.\");\r\n }\r\n\r\n if (this.debug) console.log(\"[convert-buddy-js] pushWithRecords\", chunk.byteLength, \"includeRecords:\", includeRecords);\r\n \r\n // Check if WASM supports pushWithRecords\r\n if (typeof this.converter.pushWithRecords === 'function') {\r\n const result = this.converter.pushWithRecords(chunk, includeRecords);\r\n \r\n // Check if we should trigger progress callback\r\n if (this.onProgress) {\r\n const stats = this.stats();\r\n if (stats.bytesIn - this.lastProgressBytes >= this.progressIntervalBytes) {\r\n this.onProgress(stats);\r\n this.lastProgressBytes = stats.bytesIn;\r\n }\r\n }\r\n \r\n return result;\r\n } else {\r\n // Fallback to regular push if WASM doesn't support it yet\r\n const output = this.push(chunk);\r\n if (includeRecords) {\r\n return { output, records: [] }; // Caller will use splitter\r\n }\r\n return output;\r\n }\r\n }\r\n\r\n finish(): Uint8Array {\r\n if (this.aborted) {\r\n throw new Error(\"Conversion has been aborted\");\r\n }\r\n\r\n if (this.debug) console.log(\"[convert-buddy-js] finish\");\r\n const output = this.converter.finish();\r\n\r\n // Final progress callback\r\n if (this.onProgress) {\r\n this.onProgress(this.stats());\r\n }\r\n\r\n return output;\r\n }\r\n\r\n stats(): Stats {\r\n if (!this.converter || typeof this.converter.getStats !== 'function') {\r\n // Converter not initialized yet\r\n return {\r\n bytesIn: 0,\r\n bytesOut: 0,\r\n chunksIn: 0,\r\n recordsProcessed: 0,\r\n parseTimeMs: 0,\r\n transformTimeMs: 0,\r\n writeTimeMs: 0,\r\n maxBufferSize: 0,\r\n currentPartialSize: 0,\r\n throughputMbPerSec: 0,\r\n };\r\n }\r\n\r\n try {\r\n const wasmStats = this.converter.getStats();\r\n \r\n // WASM object properties are snake_case (Rust convention via wasm_bindgen getters)\r\n return {\r\n bytesIn: wasmStats.bytes_in,\r\n bytesOut: wasmStats.bytes_out,\r\n chunksIn: wasmStats.chunks_in,\r\n recordsProcessed: wasmStats.records_processed,\r\n parseTimeMs: wasmStats.parse_time_ms,\r\n transformTimeMs: wasmStats.transform_time_ms,\r\n writeTimeMs: wasmStats.write_time_ms,\r\n maxBufferSize: wasmStats.max_buffer_size,\r\n currentPartialSize: wasmStats.current_partial_size,\r\n throughputMbPerSec: wasmStats.throughput_mb_per_sec,\r\n };\r\n } catch (e) {\r\n if (this.debug) console.error(\"[convert-buddy-js] Error getting stats:\", e);\r\n return {\r\n bytesIn: 0,\r\n bytesOut: 0,\r\n chunksIn: 0,\r\n recordsProcessed: 0,\r\n parseTimeMs: 0,\r\n transformTimeMs: 0,\r\n writeTimeMs: 0,\r\n maxBufferSize: 0,\r\n currentPartialSize: 0,\r\n throughputMbPerSec: 0,\r\n };\r\n }\r\n }\r\n\r\n abort(): void {\r\n this.aborted = true;\r\n if (this.debug) console.log(\"[convert-buddy-js] aborted\");\r\n }\r\n\r\n pause(): void {\r\n this.paused = true;\r\n if (this.debug) console.log(\"[convert-buddy-js] paused\");\r\n }\r\n\r\n resume(): void {\r\n this.paused = false;\r\n if (this.debug) console.log(\"[convert-buddy-js] resumed\");\r\n }\r\n\r\n isAborted(): boolean {\r\n return this.aborted;\r\n }\r\n\r\n isPaused(): boolean {\r\n return this.paused;\r\n }\r\n}\r\n\r\nasync function readSample(\r\n input: DetectInput,\r\n maxBytes = 256 * 1024\r\n): Promise<Uint8Array> {\r\n if (typeof input === \"string\") {\r\n const encoded = new TextEncoder().encode(input);\r\n return encoded.length > maxBytes ? encoded.slice(0, maxBytes) : encoded;\r\n }\r\n\r\n if (input instanceof Uint8Array) {\r\n return input.length > maxBytes ? input.slice(0, maxBytes) : input;\r\n }\r\n\r\n if (input instanceof ArrayBuffer) {\r\n const bytes = new Uint8Array(input as ArrayBuffer);\r\n return bytes.length > maxBytes ? bytes.slice(0, maxBytes) : bytes;\r\n }\r\n\r\n if (isReadableStream(input)) {\r\n const reader = input.getReader();\r\n const chunks: Uint8Array[] = [];\r\n let total = 0;\r\n\r\n while (total < maxBytes) {\r\n const { value, done } = await reader.read();\r\n if (done || !value) break;\r\n const slice = total + value.length > maxBytes\r\n ? value.slice(0, maxBytes - total)\r\n : value;\r\n chunks.push(slice);\r\n total += slice.length;\r\n }\r\n\r\n if (total >= maxBytes) {\r\n await reader.cancel();\r\n }\r\n\r\n return concatChunks(chunks, total);\r\n }\r\n\r\n const chunks: Uint8Array[] = [];\r\n let total = 0;\r\n\r\n for await (const chunk of input as AsyncIterable<Uint8Array>) {\r\n if (total >= maxBytes) {\r\n break;\r\n }\r\n const data = chunk instanceof Uint8Array ? chunk : new Uint8Array(chunk);\r\n const slice = total + data.length > maxBytes\r\n ? data.slice(0, maxBytes - total)\r\n : data;\r\n chunks.push(slice);\r\n total += slice.length;\r\n }\r\n\r\n return concatChunks(chunks, total);\r\n}\r\n\r\nfunction concatChunks(chunks: Uint8Array[], total: number): Uint8Array {\r\n const result = new Uint8Array(total);\r\n let offset = 0;\r\n for (const chunk of chunks) {\r\n result.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n return result;\r\n}\r\n\r\nfunction isReadableStream(\r\n input: DetectInput\r\n): input is ReadableStream<Uint8Array> {\r\n return typeof (input as ReadableStream<Uint8Array>)?.getReader === \"function\";\r\n}\r\n\r\nasync function loadDetectionWasm(debug: boolean): Promise<WasmModule> {\r\n const wasmModule = await loadWasmModule();\r\n if (typeof wasmModule.default === \"function\") {\r\n await (wasmModule.default as () => Promise<void>)();\r\n }\r\n wasmModule.init(debug);\r\n return wasmModule;\r\n}\r\n\r\nexport async function detectFormat(\r\n input: DetectInput,\r\n opts: DetectOptions = {}\r\n): Promise<Format | \"unknown\"> {\r\n const wasmModule = await loadDetectionWasm(!!opts.debug);\r\n const sample = await readSample(input, opts.maxBytes);\r\n const format = wasmModule.detectFormat?.(sample);\r\n return (format as Format) ?? \"unknown\";\r\n}\r\n\r\nexport async function detectStructure(\r\n input: DetectInput,\r\n formatHint?: Format,\r\n opts: DetectOptions = {}\r\n): Promise<StructureDetection | null> {\r\n const wasmModule = await loadDetectionWasm(!!opts.debug);\r\n const sample = await readSample(input, opts.maxBytes);\r\n const result = wasmModule.detectStructure?.(sample, formatHint);\r\n return result ?? null;\r\n}\r\n\r\n// Backward compatibility functions - these now use the unified detectStructure internally\r\nexport async function detectCsvFieldsAndDelimiter(\r\n input: DetectInput,\r\n opts: DetectOptions = {}\r\n): Promise<CsvDetection | null> {\r\n const structure = await detectStructure(input, \"csv\", opts);\r\n if (structure && structure.format === \"csv\" && structure.delimiter) {\r\n return {\r\n delimiter: structure.delimiter,\r\n fields: structure.fields,\r\n };\r\n }\r\n return null;\r\n}\r\n\r\nexport async function detectXmlElements(\r\n input: DetectInput,\r\n opts: DetectOptions = {}\r\n): Promise<XmlDetection | null> {\r\n const structure = await detectStructure(input, \"xml\", opts);\r\n if (structure && structure.format === \"xml\") {\r\n return {\r\n elements: structure.fields,\r\n recordElement: structure.recordElement,\r\n };\r\n }\r\n return null;\r\n}\r\n\r\n// Helper to auto-detect format and CSV/XML configuration from sample data\r\nexport async function autoDetectConfig(\r\n input: DetectInput,\r\n opts: DetectOptions = {}\r\n): Promise<{ \r\n format: Format | \"unknown\"; \r\n csvConfig?: CsvConfig;\r\n xmlConfig?: XmlConfig;\r\n}> {\r\n const wasmModule = await loadDetectionWasm(!!opts.debug);\r\n const sample = await readSample(input, opts.maxBytes);\r\n \r\n const format = (wasmModule.detectFormat?.(sample) as Format) ?? \"unknown\";\r\n \r\n const result: { format: Format | \"unknown\"; csvConfig?: CsvConfig; xmlConfig?: XmlConfig } = { format };\r\n \r\n if (format === \"csv\") {\r\n const csvDetection = wasmModule.detectCsvFields?.(sample);\r\n if (csvDetection) {\r\n result.csvConfig = {\r\n delimiter: csvDetection.delimiter,\r\n hasHeaders: csvDetection.fields.length > 0,\r\n };\r\n }\r\n } else if (format === \"xml\") {\r\n const xmlDetection = wasmModule.detectXmlElements?.(sample);\r\n if (xmlDetection?.recordElement) {\r\n result.xmlConfig = {\r\n recordElement: xmlDetection.recordElement,\r\n };\r\n }\r\n }\r\n \r\n return result;\r\n}\r\n\r\n// Web Streams TransformStream adapter\r\nexport class ConvertBuddyTransformStream extends TransformStream<Uint8Array, Uint8Array> {\r\n constructor(opts: ConvertBuddyOptions = {}) {\r\n let buddy: ConvertBuddy | null = null;\r\n\r\n super({\r\n async start(controller) {\r\n buddy = await ConvertBuddy.create(opts);\r\n },\r\n\r\n transform(chunk, controller) {\r\n if (!buddy) {\r\n throw new Error(\"ConvertBuddy not initialized\");\r\n }\r\n\r\n const output = buddy.push(chunk);\r\n if (output.length > 0) {\r\n controller.enqueue(output);\r\n }\r\n },\r\n\r\n flush(controller) {\r\n if (!buddy) {\r\n return;\r\n }\r\n\r\n const output = buddy.finish();\r\n if (output.length > 0) {\r\n controller.enqueue(output);\r\n }\r\n\r\n if (opts.profile) {\r\n const stats = buddy.stats();\r\n console.log(\"[convert-buddy] Performance Stats:\", stats);\r\n }\r\n },\r\n });\r\n }\r\n}\r\n\r\n// Utility: Convert entire buffer/string\r\nexport async function convert(\r\n input: Uint8Array | string,\r\n opts: ConvertBuddyOptions = {}\r\n): Promise<Uint8Array> {\r\n try {\r\n // Validate outputFormat early\r\n if (opts.outputFormat) {\r\n const validFormats = ['csv', 'json', 'ndjson', 'xml'];\r\n if (!validFormats.includes(opts.outputFormat)) {\r\n throw new Error(`Invalid outputFormat: \"${opts.outputFormat}\". Must be one of: ${validFormats.join(', ')}`);\r\n }\r\n }\r\n\r\n // Validate inputFormat early (if specified)\r\n if (opts.inputFormat && opts.inputFormat !== 'auto') {\r\n const validFormats = ['csv', 'json', 'ndjson', 'xml'];\r\n if (!validFormats.includes(opts.inputFormat)) {\r\n throw new Error(`Invalid inputFormat: \"${opts.inputFormat}\". Must be one of: ${validFormats.join(', ')}, or \"auto\"`);\r\n }\r\n }\r\n\r\n const inputBytes = typeof input === \"string\" \r\n ? new TextEncoder().encode(input)\r\n : input;\r\n\r\n // If inputFormat is not specified or is \"auto\", perform auto-detection\r\n let actualOpts = opts;\r\n if (!opts.inputFormat || opts.inputFormat === \"auto\") {\r\n const sample = inputBytes.length > 256 * 1024 \r\n ? inputBytes.slice(0, 256 * 1024) \r\n : inputBytes;\r\n \r\n const detected = await autoDetectConfig(sample, { debug: opts.debug });\r\n \r\n if (detected.format !== \"unknown\") {\r\n actualOpts = { ...opts, inputFormat: detected.format as Format };\r\n \r\n if (detected.csvConfig && !opts.csvConfig) {\r\n actualOpts.csvConfig = detected.csvConfig;\r\n }\r\n \r\n if (detected.xmlConfig && !opts.xmlConfig) {\r\n actualOpts.xmlConfig = detected.xmlConfig;\r\n }\r\n \r\n if (opts.debug) {\r\n console.log(\"[convert-buddy] Auto-detected format:\", detected.format);\r\n }\r\n } else {\r\n throw new Error(\"Could not auto-detect input format. Please specify inputFormat explicitly.\");\r\n }\r\n }\r\n\r\n const buddy = await ConvertBuddy.create(actualOpts);\r\n\r\n const output = buddy.push(inputBytes);\r\n const final = buddy.finish();\r\n\r\n // Combine outputs\r\n const result = new Uint8Array(output.length + final.length);\r\n result.set(output, 0);\r\n result.set(final, output.length);\r\n\r\n if (opts.profile) {\r\n const stats = buddy.stats();\r\n console.log(\"[convert-buddy] Performance Stats:\", stats);\r\n }\r\n\r\n return result;\r\n } catch (err: any) {\r\n // Normalize non-Error throws (e.g., wasm JsValue) into Error with message\r\n if (err instanceof Error) throw err;\r\n try {\r\n // Try to stringify common structures\r\n const msg = typeof err === 'string' ? err : (err && err.message) ? err.message : JSON.stringify(err);\r\n throw new Error(String(msg));\r\n } catch (_) {\r\n throw new Error(String(err));\r\n }\r\n }\r\n}\r\n\r\n// Utility: Convert and return as string\r\nexport async function convertToString(\r\n input: Uint8Array | string,\r\n opts: ConvertBuddyOptions = {}\r\n): Promise<string> {\r\n const result = await convert(input, opts);\r\n return decodeUtf8(result);\r\n}\r\n\r\n/**\r\n * Ultra-simple standalone convert function with auto-detection.\r\n * Accepts any input type (URL, File, Buffer, string, stream) and automatically detects format.\r\n * \r\n * @example\r\n * // From URL\r\n * import { convertAny } from \"convert-buddy-js\";\r\n * const result = await convertAny(\"https://example.com/data.csv\", { outputFormat: \"json\" });\r\n * \r\n * @example\r\n * // From File (browser)\r\n * const file = fileInput.files[0];\r\n * const result = await convertAny(file, { outputFormat: \"ndjson\" });\r\n * \r\n * @example\r\n * // From string data\r\n * const result = await convertAny('{\"name\":\"Ada\"}', { outputFormat: \"csv\" });\r\n */\r\nexport async function convertAny(\r\n input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>,\r\n opts: ConvertOptions\r\n): Promise<Uint8Array> {\r\n // Validate outputFormat is provided\r\n if (!opts.outputFormat) {\r\n throw new Error('outputFormat is required. Must be one of: csv, json, ndjson, xml');\r\n }\r\n\r\n // Validate outputFormat value\r\n const validFormats = ['csv', 'json', 'ndjson', 'xml'];\r\n if (!validFormats.includes(opts.outputFormat)) {\r\n throw new Error(`Invalid outputFormat: \"${opts.outputFormat}\". Must be one of: ${validFormats.join(', ')}`);\r\n }\r\n\r\n // Validate inputFormat if specified\r\n if (opts.inputFormat && opts.inputFormat !== 'auto') {\r\n if (!validFormats.includes(opts.inputFormat)) {\r\n throw new Error(`Invalid inputFormat: \"${opts.inputFormat}\". Must be one of: ${validFormats.join(', ')}, or \"auto\"`);\r\n }\r\n }\r\n\r\n const buddy = new ConvertBuddy();\r\n return buddy.convert(input, opts);\r\n}\r\n\r\n/**\r\n * Ultra-simple standalone convert function that returns a string.\r\n * Same as convertAny but decodes the output to a string.\r\n * \r\n * @example\r\n * import { convertAnyToString } from \"convert-buddy-js\";\r\n * const json = await convertAnyToString(\"https://example.com/data.csv\", { outputFormat: \"json\" });\r\n * console.log(JSON.parse(json));\r\n */\r\nexport async function convertAnyToString(\r\n input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>,\r\n opts: ConvertOptions\r\n): Promise<string> {\r\n const result = await convertAny(input, opts);\r\n return decodeUtf8(result);\r\n}\r\n\r\n// ===== Helper Functions =====\r\n// File format utilities for common use cases\r\n\r\n/**\r\n * Get MIME type for a given format\r\n * \r\n * @example\r\n * const mimeType = getMimeType(\"json\"); // \"application/json\"\r\n */\r\nexport function getMimeType(format: Format): string {\r\n switch (format) {\r\n case \"json\":\r\n return \"application/json\";\r\n case \"ndjson\":\r\n return \"application/x-ndjson\";\r\n case \"csv\":\r\n return \"text/csv\";\r\n case \"xml\":\r\n return \"application/xml\";\r\n }\r\n}\r\n\r\n/**\r\n * Get file extension for a given format (without the dot)\r\n * \r\n * @example\r\n * const ext = getExtension(\"json\"); // \"json\"\r\n */\r\nexport function getExtension(format: Format): string {\r\n return format;\r\n}\r\n\r\n/**\r\n * Get suggested filename for a converted file\r\n * \r\n * @param originalName - Original filename\r\n * @param outputFormat - Target format\r\n * @param includeTimestamp - Whether to include a timestamp (default: false)\r\n * \r\n * @example\r\n * const name = getSuggestedFilename(\"data.csv\", \"json\"); // \"data.json\"\r\n * const name = getSuggestedFilename(\"data.csv\", \"json\", true); // \"data_converted_1234567890.json\"\r\n */\r\nexport function getSuggestedFilename(\r\n originalName: string,\r\n outputFormat: Format,\r\n includeTimestamp = false\r\n): string {\r\n const baseName = originalName.replace(/\\.[^/.]+$/, \"\");\r\n const extension = getExtension(outputFormat);\r\n \r\n if (includeTimestamp) {\r\n return `${baseName}_converted_${Date.now()}.${extension}`;\r\n }\r\n \r\n return `${baseName}.${extension}`;\r\n}\r\n\r\n/**\r\n * Get File System Access API file type configuration for showSaveFilePicker\r\n * \r\n * @example\r\n * const types = getFileTypeConfig(\"json\");\r\n * const handle = await showSaveFilePicker({ types });\r\n */\r\nexport function getFileTypeConfig(format: Format): Array<{\r\n description: string;\r\n accept: Record<string, string[]>;\r\n}> {\r\n const mimeType = getMimeType(format);\r\n const extension = `.${getExtension(format)}`;\r\n \r\n return [\r\n {\r\n description: `${format.toUpperCase()} Files`,\r\n accept: { [mimeType]: [extension] },\r\n },\r\n ];\r\n}\r\n\r\n// WASM Threading Capabilities API\r\n/**\r\n * Check if WASM threading is supported in the current environment\r\n * @returns true if SharedArrayBuffer and Atomics are available (required for WASM threads)\r\n */\r\nexport function isWasmThreadingSupported(): boolean {\r\n return detectWasmThreadingSupport();\r\n}\r\n\r\n/**\r\n * Get the optimal number of worker threads based on CPU cores and WASM capabilities\r\n * @returns Recommended thread count for optimal performance\r\n */\r\nexport function getOptimalThreadCount(): number {\r\n const cores = typeof navigator !== 'undefined' \r\n ? (navigator.hardwareConcurrency || 4)\r\n : (process?.env?.UV_THREADPOOL_SIZE ? parseInt(process.env.UV_THREADPOOL_SIZE) : \r\n typeof require !== 'undefined' ? require('os').cpus().length : 4);\r\n \r\n // For current JavaScript-level parallelism, limit to 4 parallel instances\r\n // When true WASM threading is enabled, this can be increased\r\n return Math.min(cores, 4);\r\n}\r\n\r\n/**\r\n * Get current threading capabilities and configuration\r\n * @returns Object with threading information\r\n */\r\nexport function getThreadingInfo(): {\r\n wasmThreadingSupported: boolean;\r\n customThreadPoolAvailable: boolean;\r\n nodejsWasmThreading: boolean;\r\n recommendedThreads: number;\r\n currentThreads: number;\r\n approach: string;\r\n} {\r\n const isNodejs = typeof process !== 'undefined';\r\n \r\n return {\r\n wasmThreadingSupported: detectWasmThreadingSupport(),\r\n customThreadPoolAvailable: typeof window !== 'undefined',\r\n nodejsWasmThreading: isNodejs && !!nodejsThreadPool,\r\n recommendedThreads: getOptimalThreadCount(),\r\n currentThreads: isNodejs ? \r\n (nodejsThreadPool ? nodejsThreadPool.workers?.length || 0 : 0) :\r\n (threadPool ? threadPool.workers?.length || 0 : 0),\r\n approach: isNodejs ? 'nodejs_enhanced_threading' : 'browser_custom_threading'\r\n };\r\n}\r\n\r\n/**\r\n * Backward compatibility alias for ConvertBuddy\r\n * @deprecated Use ConvertBuddy instead\r\n */\r\nexport const Converter = ConvertBuddy;\r\n\r\n// ============================================================================\r\n// Streaming API (Primary API)\r\n// ============================================================================\r\n\r\n// Import the new buddy-stream module\r\nimport { \r\n createBuddyController as _createBuddyController,\r\n _setConverterFactory,\r\n stream as buddyStream,\r\n} from './buddy-stream.js';\r\n\r\n// Re-export streaming API\r\nexport { stream } from './buddy-stream.js';\r\n\r\n// Internal reference for ConvertBuddy.stream() method\r\nconst __createBuddyController = _createBuddyController;\r\n\r\n// Register the converter factory for standalone stream() function\r\n_setConverterFactory(async (opts) => {\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: opts.inputFormat,\r\n outputFormat: opts.outputFormat,\r\n csvConfig: opts.csvConfig,\r\n xmlConfig: opts.xmlConfig,\r\n transform: opts.transform,\r\n debug: opts.debug,\r\n profile: opts.profile ?? true,\r\n });\r\n \r\n // Create a wrapper that implements ConverterInterface\r\n return {\r\n push: (chunk: Uint8Array) => buddy.push(chunk),\r\n pushWithRecords: (chunk: Uint8Array, includeRecords: boolean) => buddy.pushWithRecords(chunk, includeRecords),\r\n finish: () => buddy.finish(),\r\n getStats: () => buddy.stats(),\r\n } as ConverterInterface;\r\n});\r\n\r\n// ============================================================================\r\n\r\n"],"mappings":"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","names":["require","mod","stream","result","reader","Converter","chunks","total"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Import types from shared types module\r\nimport type { \r\n Format, \r\n CsvConfig, \r\n XmlConfig, \r\n TransformConfig, \r\n TransformMode, \r\n Coerce, \r\n FieldMap, \r\n Stats,\r\n ConverterInterface,\r\n} from './types.js';\r\n\r\n// Import streaming types (will be re-exported at bottom of file)\r\nimport type { \r\n BuddyStreamOptions,\r\n BuddyController,\r\n BuddyStats,\r\n BuddyInput,\r\n} from './types.js';\r\n\r\n// Export core types for public API\r\nexport type { \r\n Format, \r\n CsvConfig, \r\n XmlConfig, \r\n TransformConfig, \r\n TransformMode, \r\n Coerce, \r\n FieldMap, \r\n Stats,\r\n BuddyStats,\r\n BuddyController,\r\n BuddyStreamOptions,\r\n} from './types.js';\r\n\r\n// Export stream controller types (implementation is platform-specific)\r\nexport type DetectInput =\r\n | Uint8Array\r\n | ArrayBuffer\r\n | string\r\n | ReadableStream<Uint8Array>\r\n | AsyncIterable<Uint8Array>;\r\n\r\nexport type CsvDetection = {\r\n delimiter: string;\r\n fields: string[];\r\n};\r\n\r\nexport type XmlDetection = {\r\n elements: string[];\r\n recordElement?: string;\r\n};\r\n\r\nexport type JsonDetection = {\r\n fields: string[];\r\n};\r\n\r\nexport type NdjsonDetection = {\r\n fields: string[];\r\n};\r\n\r\nexport type StructureDetection = {\r\n format: Format;\r\n fields: string[];\r\n delimiter?: string; // For CSV\r\n recordElement?: string; // For XML\r\n};\r\n\r\nexport type DetectOptions = {\r\n maxBytes?: number;\r\n debug?: boolean;\r\n};\r\n\r\nexport type ProgressCallback = (stats: Stats) => void;\r\n\r\nexport type ConvertBuddyOptions = {\r\n debug?: boolean;\r\n profile?: boolean;\r\n inputFormat?: Format | \"auto\";\r\n outputFormat?: Format;\r\n chunkTargetBytes?: number;\r\n parallelism?: number; // Node only - number of worker threads\r\n maxMemoryMB?: number; // Memory limit for conversions (future use)\r\n csvConfig?: CsvConfig;\r\n xmlConfig?: XmlConfig;\r\n transform?: TransformConfig;\r\n pretty?: boolean;\r\n onProgress?: ProgressCallback;\r\n progressIntervalBytes?: number; // Trigger progress callback every N bytes (default: 1MB)\r\n};\r\n\r\nexport type ConvertOptions = {\r\n inputFormat?: Format | \"auto\";\r\n outputFormat: Format;\r\n csvConfig?: CsvConfig;\r\n xmlConfig?: XmlConfig;\r\n transform?: TransformConfig;\r\n pretty?: boolean;\r\n onProgress?: ProgressCallback;\r\n};\r\n\r\ntype WasmModule = {\r\n default?: unknown;\r\n init: (debugEnabled: boolean) => void;\r\n Converter: new (debug: boolean) => {\r\n push: (chunk: Uint8Array) => Uint8Array;\r\n pushWithRecords: (chunk: Uint8Array, includeRecords: boolean) => Uint8Array | { output: Uint8Array; records: any[] };\r\n finish: () => Uint8Array;\r\n getStats: () => Stats;\r\n };\r\n detectFormat?: (sample: Uint8Array) => string | null | undefined;\r\n detectCsvFields?: (sample: Uint8Array) => CsvDetection | null | undefined;\r\n detectXmlElements?: (sample: Uint8Array) => XmlDetection | null | undefined;\r\n detectJsonFields?: (sample: Uint8Array) => JsonDetection | null | undefined;\r\n detectNdjsonFields?: (sample: Uint8Array) => NdjsonDetection | null | undefined;\r\n detectStructure?: (sample: Uint8Array, formatHint?: string) => StructureDetection | null | undefined;\r\n getSimdEnabled?: () => boolean;\r\n __wbg_set_wasm?: (wasm: unknown) => void;\r\n};\r\n\r\nlet wasmModuleInstance: WasmModule | null = null;\r\nlet wasmModuleLoadPromise: Promise<WasmModule> | null = null;\r\nlet wasmThreadingSupported = false;\r\nlet threadPool: any = null; // Custom WASM thread pool (browser)\r\nlet nodejsThreadPool: any = null; // Node.js specific thread pool\r\nconst utf8Decoder = new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true });\r\n\r\nfunction decodeUtf8(bytes: Uint8Array): string {\r\n return utf8Decoder.decode(bytes);\r\n}\r\n\r\n// Detect SharedArrayBuffer support for WASM threading\r\nfunction detectWasmThreadingSupport(): boolean {\r\n if (typeof SharedArrayBuffer === 'undefined') {\r\n return false;\r\n }\r\n \r\n // Test if we can actually create a SharedArrayBuffer\r\n try {\r\n new SharedArrayBuffer(1);\r\n return true;\r\n } catch (e) {\r\n return false;\r\n }\r\n}\r\n\r\nasync function loadWasmModule(): Promise<WasmModule> {\r\n // Return cached instance if already loaded\r\n if (wasmModuleInstance) {\r\n return wasmModuleInstance;\r\n }\r\n\r\n // If load is in progress, wait for it\r\n if (wasmModuleLoadPromise) {\r\n return wasmModuleLoadPromise;\r\n }\r\n\r\n // Start loading\r\n wasmModuleLoadPromise = (async () => {\r\n const isNode =\r\n typeof process !== \"undefined\" &&\r\n !!(process as any).versions?.node;\r\n\r\n // Detect threading support\r\n wasmThreadingSupported = detectWasmThreadingSupport();\r\n \r\n if (isNode) {\r\n // Use dynamic string construction to prevent bundlers (Vite, webpack, etc.) \r\n // from statically analyzing and trying to resolve the Node.js module.\r\n // This pattern makes the import string opaque to static analysis.\r\n const nodeModuleName = [\"node\", \"module\"].join(\":\");\r\n const nodeModule: any = await (new Function(\"m\", \"return import(m)\")(nodeModuleName));\r\n const createRequire = nodeModule.createRequire as any;\r\n const requireFn = createRequire ? createRequire(import.meta.url) : (module as any).createRequire?.(import.meta.url);\r\n const require = requireFn ?? (globalThis as any).require;\r\n const mod = require(\"../wasm-node.cjs\");\r\n return mod as WasmModule;\r\n }\r\n\r\n // @ts-expect-error - WASM module will be available at runtime in dist/wasm/web/\r\n const mod = (await import(\"./wasm/web/convert_buddy.js\")) as unknown as WasmModule;\r\n \r\n // Initialize threading if supported\r\n if (wasmThreadingSupported && (mod as any).initThreadPool) {\r\n try {\r\n const numThreads = Math.min(navigator.hardwareConcurrency || 4, 8);\r\n await (mod as any).initThreadPool(numThreads);\r\n console.log(`[convert-buddy] WASM threading initialized with ${numThreads} threads`);\r\n } catch (e) {\r\n console.warn('[convert-buddy] WASM threading initialization failed, using single-thread:', e);\r\n wasmThreadingSupported = false;\r\n }\r\n }\r\n \r\n return mod;\r\n })();\r\n\r\n try {\r\n wasmModuleInstance = await wasmModuleLoadPromise;\r\n return wasmModuleInstance;\r\n } finally {\r\n wasmModuleLoadPromise = null;\r\n }\r\n}\r\n\r\nlet wasmInitialized = false;\r\nlet wasmInitPromise: Promise<void> | null = null;\r\n\r\nasync function initWasm(debug: boolean): Promise<void> {\r\n // If already initialized, return immediately\r\n if (wasmInitialized) {\r\n return;\r\n }\r\n\r\n // If initialization is in progress, wait for it\r\n if (wasmInitPromise) {\r\n return wasmInitPromise;\r\n }\r\n\r\n // Start initialization\r\n wasmInitPromise = (async () => {\r\n const wasmModule = await loadWasmModule();\r\n\r\n if (typeof wasmModule.default === \"function\") {\r\n await (wasmModule.default as () => Promise<void>)();\r\n }\r\n\r\n wasmModule.init(debug);\r\n \r\n // Note: Node.js enhanced threading is handled at the JavaScript level\r\n // No WASM thread pool initialization needed\r\n \r\n wasmInitialized = true;\r\n })();\r\n\r\n try {\r\n await wasmInitPromise;\r\n } finally {\r\n wasmInitPromise = null;\r\n }\r\n}\r\n\r\n/**\r\n * Warn if using non-streaming approach with large files\r\n */\r\nfunction warnIfLargeFile(sizeBytes: number, methodName: string = \"convert\"): void {\r\n const SIZE_THRESHOLD = 10 * 1024 * 1024; // 10MB\r\n \r\n if (sizeBytes >= SIZE_THRESHOLD) {\r\n const sizeMB = (sizeBytes / 1024 / 1024).toFixed(1);\r\n console.warn(\r\n `[convert-buddy-js] WARNING: Using ${methodName}() with a large file (${sizeMB}MB). ` +\r\n `This method is intended for small files and may cause memory issues with large files. ` +\r\n `For better performance and memory management with files of any size, use the streaming API: ` +\r\n `ConvertBuddy.create() with push()/finish() methods.`\r\n );\r\n }\r\n}\r\n\r\nexport class ConvertBuddy {\r\n private converter: any;\r\n private debug: boolean;\r\n private aborted: boolean = false;\r\n private paused: boolean = false;\r\n private onProgress?: ProgressCallback;\r\n private progressIntervalBytes: number;\r\n private lastProgressBytes: number = 0;\r\n private globalConfig: ConvertBuddyOptions;\r\n private initialized: boolean = false;\r\n public simd: boolean;\r\n\r\n /**\r\n * Create a new ConvertBuddy instance with global configuration.\r\n * This is useful when you want to set memory limits, debug mode, or other global settings.\r\n * \r\n * @example\r\n * const buddy = new ConvertBuddy({ maxMemoryMB: 512, debug: true });\r\n * const result = await buddy.convert(input, { outputFormat: \"json\" });\r\n */\r\n constructor(opts: ConvertBuddyOptions = {}) {\r\n // Initialize basic properties\r\n this.debug = !!opts.debug;\r\n this.simd = false; // Will be set on first convert\r\n this.globalConfig = opts;\r\n this.progressIntervalBytes = opts.progressIntervalBytes || 1024 * 1024;\r\n this.onProgress = opts.onProgress;\r\n this.converter = null; // Will be initialized lazily\r\n this.initialized = false;\r\n }\r\n\r\n /**\r\n * Convert input (string, Buffer, File, URL, etc.) to the desired output format.\r\n * This is the main method for the new simplified API.\r\n * \r\n * @example\r\n * // Auto-detect everything\r\n * const buddy = new ConvertBuddy();\r\n * const result = await buddy.convert(\"https://example.com/data.csv\", { outputFormat: \"json\" });\r\n * \r\n * @example\r\n * // With configuration\r\n * const buddy = new ConvertBuddy({ maxMemoryMB: 512 });\r\n * const result = await buddy.convert(file, { inputFormat: \"csv\", outputFormat: \"json\" });\r\n */\r\n async convert(\r\n input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>,\r\n opts: ConvertOptions\r\n ): Promise<Uint8Array> {\r\n // Merge global and local options\r\n const mergedOpts: ConvertBuddyOptions = {\r\n ...this.globalConfig,\r\n ...opts,\r\n inputFormat: opts.inputFormat || this.globalConfig.inputFormat || \"auto\",\r\n pretty: opts.pretty ?? this.globalConfig.pretty ?? true,\r\n };\r\n\r\n // Detect input type and convert accordingly\r\n if (typeof input === \"string\") {\r\n // Could be URL or raw data\r\n if (input.startsWith(\"http://\") || input.startsWith(\"https://\")) {\r\n // Fetch from URL\r\n return this.convertFromUrl(input, mergedOpts);\r\n } else {\r\n // Treat as raw data\r\n return this.convertFromString(input, mergedOpts);\r\n }\r\n } else if (input instanceof Uint8Array) {\r\n return this.convertFromBuffer(input, mergedOpts);\r\n } else if (typeof File !== \"undefined\" && input instanceof File) {\r\n return this.convertFromFile(input as File, mergedOpts);\r\n } else if (typeof Blob !== \"undefined\" && input instanceof Blob) {\r\n return this.convertFromBlob(input as Blob, mergedOpts);\r\n } else if (typeof ReadableStream !== \"undefined\" && input instanceof ReadableStream) {\r\n return this.convertFromStream(input, mergedOpts);\r\n } else {\r\n throw new Error(\"Unsupported input type\");\r\n }\r\n }\r\n\r\n /**\r\n * Stream conversion: returns controller immediately with done promise.\r\n * \r\n * Features:\r\n * - Fire-and-forget: call stream() and ignore done\r\n * - Await completion: await controller.done\r\n * - Automatic backpressure: if onRecords returns a Promise, processing waits\r\n * - Manual pause/resume also supported\r\n * \r\n * @example\r\n * // Primary pattern: onRecords callback with automatic backpressure\r\n * const buddy = cb.stream(csvData, {\r\n * recordBatchSize: 1000,\r\n * onRecords: async (buddy, records, stats, count) => {\r\n * console.log(`Batch of ${records.length} records, total: ${count}`);\r\n * await saveToDatabase(records); // Automatic backpressure\r\n * },\r\n * onError: (err, buddy, stats) => console.error('Failed:', err),\r\n * onDone: (stats) => console.log('Complete:', stats),\r\n * });\r\n * \r\n * // Optionally await completion\r\n * const finalStats = await buddy.done;\r\n * \r\n * @example\r\n * // Fire-and-forget (no await)\r\n * cb.stream(csvData, {\r\n * onRecords: (buddy, records) => queueForProcessing(records),\r\n * onError: (err) => console.error(err),\r\n * });\r\n * \r\n * @example\r\n * // With raw output streaming\r\n * const chunks: Uint8Array[] = [];\r\n * const buddy = cb.stream(csvData, {\r\n * outputFormat: 'ndjson',\r\n * onData: (chunk) => chunks.push(chunk),\r\n * onRecords: async (buddy, records, stats, count) => {\r\n * await processRecords(records);\r\n * },\r\n * });\r\n * await buddy.done;\r\n */\r\n stream<T = unknown>(\r\n input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>,\r\n opts: BuddyStreamOptions<T> = {}\r\n ): BuddyController {\r\n // Merge global and local options\r\n const mergedOpts: BuddyStreamOptions<T> = {\r\n ...opts,\r\n inputFormat: opts.inputFormat || this.globalConfig.inputFormat || \"auto\",\r\n outputFormat: opts.outputFormat || this.globalConfig.outputFormat,\r\n csvConfig: opts.csvConfig || this.globalConfig.csvConfig,\r\n xmlConfig: opts.xmlConfig || this.globalConfig.xmlConfig,\r\n transform: opts.transform || this.globalConfig.transform,\r\n pretty: opts.pretty ?? this.globalConfig.pretty ?? true,\r\n debug: opts.debug ?? this.globalConfig.debug,\r\n profile: opts.profile ?? this.globalConfig.profile ?? true, // Stats always enabled by default\r\n };\r\n\r\n // Create converter factory that uses ConvertBuddy.create\r\n const converterFactory = async () => {\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: mergedOpts.inputFormat,\r\n outputFormat: mergedOpts.outputFormat,\r\n csvConfig: mergedOpts.csvConfig,\r\n xmlConfig: mergedOpts.xmlConfig,\r\n transform: mergedOpts.transform,\r\n pretty: mergedOpts.pretty,\r\n debug: mergedOpts.debug,\r\n profile: mergedOpts.profile,\r\n });\r\n \r\n // Return a wrapper that implements ConverterInterface\r\n return {\r\n push: (chunk: Uint8Array) => buddy.push(chunk),\r\n pushWithRecords: (chunk: Uint8Array, includeRecords: boolean) => buddy.pushWithRecords(chunk, includeRecords),\r\n finish: () => buddy.finish(),\r\n getStats: () => buddy.stats(),\r\n } as ConverterInterface;\r\n };\r\n\r\n return __createBuddyController(input, converterFactory, mergedOpts as BuddyStreamOptions);\r\n }\r\n\r\n private async convertFromUrl(url: string, opts: ConvertBuddyOptions): Promise<Uint8Array> {\r\n const response = await fetch(url);\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch ${url}: ${response.statusText}`);\r\n }\r\n \r\n const stream = response.body;\r\n if (!stream) {\r\n throw new Error(\"Response body is null\");\r\n }\r\n\r\n return this.convertFromStream(stream, opts);\r\n }\r\n\r\n private async convertFromString(input: string, opts: ConvertBuddyOptions): Promise<Uint8Array> {\r\n const inputBytes = new TextEncoder().encode(input);\r\n // Don't warn here - will warn in convertFromBuffer\r\n return this.convertFromBuffer(inputBytes, opts);\r\n }\r\n\r\n private async convertFromBuffer(input: Uint8Array, opts: ConvertBuddyOptions, skipWarning = false): Promise<Uint8Array> {\r\n if (!skipWarning) {\r\n warnIfLargeFile(input.length, \"convert\");\r\n }\r\n \r\n // Use WASM threading for large inputs when available\r\n const useWasmThreading = wasmThreadingSupported && input.length > 256 * 1024; // 256KB threshold\r\n \r\n if (useWasmThreading && opts.debug) {\r\n console.log('[convert-buddy] Using WASM threading for parallel processing');\r\n }\r\n \r\n // Check if we should use JavaScript-level parallelism as fallback\r\n if (!useWasmThreading && opts.parallelism && opts.parallelism > 1 && input.length > 512 * 1024) {\r\n if (opts.debug) {\r\n console.log('[convert-buddy] WASM threading not available, using JavaScript parallelism');\r\n }\r\n return this.convertFromBufferParallel(input, opts);\r\n }\r\n\r\n // Handle auto-detection\r\n let actualOpts = { ...opts };\r\n \r\n if (opts.inputFormat === \"auto\") {\r\n const detected = await autoDetectConfig(input, { debug: opts.debug });\r\n \r\n if (detected.format !== \"unknown\") {\r\n actualOpts.inputFormat = detected.format as Format;\r\n \r\n if (detected.csvConfig) {\r\n actualOpts.csvConfig = opts.csvConfig ? { ...detected.csvConfig, ...opts.csvConfig } : detected.csvConfig;\r\n }\r\n \r\n if (detected.xmlConfig) {\r\n actualOpts.xmlConfig = opts.xmlConfig ? { ...detected.xmlConfig, ...opts.xmlConfig } : detected.xmlConfig;\r\n }\r\n \r\n if (opts.debug) {\r\n console.log(\"[convert-buddy] Auto-detected format:\", detected.format);\r\n }\r\n } else {\r\n throw new Error(\"Could not auto-detect input format. Please specify inputFormat explicitly.\");\r\n }\r\n }\r\n\r\n const buddy = await ConvertBuddy.create(actualOpts);\r\n const output = buddy.push(input);\r\n const final = buddy.finish();\r\n\r\n // Combine outputs\r\n const result = new Uint8Array(output.length + final.length);\r\n result.set(output, 0);\r\n result.set(final, output.length);\r\n\r\n if (opts.profile) {\r\n const stats = buddy.stats();\r\n console.log(\"[convert-buddy] Performance Stats:\", stats);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private async convertFromBufferParallel(input: Uint8Array, opts: ConvertBuddyOptions): Promise<Uint8Array> {\r\n // Only use parallel processing for large inputs and supported conversions\r\n const parallelThreshold = 512 * 1024; // 512KB (lowered threshold for better parallelism)\r\n const maxConcurrency = Math.min(\r\n typeof navigator !== \"undefined\" && navigator.hardwareConcurrency\r\n ? navigator.hardwareConcurrency\r\n : 4,\r\n 8\r\n );\r\n \r\n if (input.length < parallelThreshold || !opts.parallelism || opts.parallelism < 2) {\r\n return this.convertFromBuffer(input, { ...opts, parallelism: 1 }, true); // Skip warning on recursive call\r\n }\r\n\r\n // Extended support for parallel processing\r\n const supportedConversions = [\r\n { input: \"csv\", output: \"ndjson\" },\r\n { input: \"csv\", output: \"json\" },\r\n { input: \"ndjson\", output: \"json\" },\r\n { input: \"ndjson\", output: \"csv\" },\r\n { input: \"ndjson\", output: \"ndjson\" }, // passthrough optimization\r\n { input: \"json\", output: \"ndjson\" },\r\n { input: \"json\", output: \"csv\" },\r\n ];\r\n\r\n const isSupported = supportedConversions.some(\r\n conv => conv.input === opts.inputFormat && conv.output === opts.outputFormat\r\n );\r\n\r\n if (!isSupported) {\r\n if (opts.debug) {\r\n console.log(`[convert-buddy] Parallel processing not supported for ${opts.inputFormat} → ${opts.outputFormat}, using sequential`);\r\n }\r\n return this.convertFromBuffer(input, { ...opts, parallelism: 1 });\r\n }\r\n\r\n try {\r\n const actualThreads = Math.min(maxConcurrency, opts.parallelism || maxConcurrency);\r\n const isNodejs = typeof window === \"undefined\" && typeof process !== \"undefined\";\r\n \r\n if (opts.debug) {\r\n const threadingType = isNodejs ? 'Node.js WASM threading' : 'Browser custom threading';\r\n console.log(`[convert-buddy] Using ${threadingType} with ${actualThreads} threads`);\r\n }\r\n\r\n if (isNodejs) {\r\n // Try enhanced Node.js threading first\r\n if (!nodejsThreadPool) {\r\n try {\r\n const { NodejsThreadPool } = await import('./nodejs-thread-pool');\r\n nodejsThreadPool = new NodejsThreadPool({\r\n maxWorkers: actualThreads,\r\n wasmPath: '../wasm-node.cjs'\r\n });\r\n await nodejsThreadPool.initialize();\r\n } catch (error) {\r\n if (opts.debug) {\r\n console.log('[convert-buddy] Node.js thread pool creation failed, using JS parallelism:', error);\r\n }\r\n }\r\n }\r\n\r\n if (nodejsThreadPool) {\r\n return this.convertUsingNodejsThreadPool(input, opts, actualThreads);\r\n } else {\r\n return this.convertUsingJsParallelism(input, opts, actualThreads);\r\n }\r\n } else {\r\n // Browser: Create custom thread pool for WASM-level parallelism\r\n if (!threadPool) {\r\n const { WasmThreadPool } = await import('./thread-pool');\r\n threadPool = new WasmThreadPool({\r\n maxWorkers: actualThreads,\r\n wasmPath: './wasm/web/convert_buddy.js'\r\n });\r\n await threadPool.initialize();\r\n }\r\n\r\n return this.convertUsingWasmThreadPool(input, opts, actualThreads);\r\n }\r\n \r\n } catch (error) {\r\n if (opts.debug) {\r\n console.warn(`[convert-buddy] Parallel processing failed, falling back to sequential:`, error);\r\n }\r\n return this.convertFromBuffer(input, { ...opts, parallelism: 1 });\r\n }\r\n }\r\n\r\n private async convertUsingNodejsThreadPool(input: Uint8Array, opts: ConvertBuddyOptions, numThreads: number): Promise<Uint8Array> {\r\n const { chunkDataNodejs, mergeResultsNodejs } = await import('./nodejs-thread-pool');\r\n \r\n if (opts.debug) {\r\n console.log(`[convert-buddy] Processing with enhanced Node.js threading (${numThreads} workers)`);\r\n }\r\n\r\n // Use optimized chunking for Node.js\r\n const chunks = chunkDataNodejs(input, numThreads);\r\n \r\n // Process chunks using Node.js worker threads\r\n const results = await nodejsThreadPool!.processChunks('convert', chunks, {\r\n outputFormat: opts.outputFormat,\r\n inputFormat: opts.inputFormat,\r\n csvConfig: opts.csvConfig,\r\n xmlConfig: opts.xmlConfig,\r\n debug: false // Disable debug in workers to reduce noise\r\n });\r\n\r\n // Merge results intelligently based on output format\r\n const merged = mergeResultsNodejs(results, opts.outputFormat!);\r\n \r\n if (opts.debug) {\r\n console.log(`[convert-buddy] Node.js threading completed: ${chunks.length} chunks, ${merged.length} bytes`);\r\n }\r\n\r\n return merged;\r\n }\r\n\r\n private async convertUsingWasmThreadPool(input: Uint8Array, opts: ConvertBuddyOptions, numThreads: number): Promise<Uint8Array> {\r\n const inputStr = decodeUtf8(input);\r\n \r\n // Import chunking utilities\r\n const { chunkData, mergeResults } = await import('./thread-pool');\r\n const chunks = chunkData(inputStr, numThreads);\r\n \r\n if (opts.debug) {\r\n console.log(`[convert-buddy] Processing ${chunks.length} chunks with WASM thread pool`);\r\n }\r\n\r\n // Determine method based on conversion type\r\n let method: string;\r\n const conversion = `${opts.inputFormat}_to_${opts.outputFormat}`;\r\n switch (conversion) {\r\n case 'csv_to_ndjson':\r\n case 'csv_to_json':\r\n method = 'parseCSV';\r\n break;\r\n case 'ndjson_to_csv':\r\n case 'ndjson_to_json':\r\n method = 'parseNDJSON';\r\n break;\r\n case 'json_to_csv':\r\n case 'json_to_ndjson':\r\n method = 'parseJSON';\r\n break;\r\n default:\r\n throw new Error(`Unsupported conversion: ${conversion}`);\r\n }\r\n\r\n // Process chunks in parallel using thread pool\r\n const results = await threadPool!.processChunks(method, chunks, {\r\n outputFormat: opts.outputFormat,\r\n csvConfig: opts.csvConfig,\r\n xmlConfig: opts.xmlConfig,\r\n debug: opts.debug\r\n });\r\n\r\n // Merge results intelligently based on output format\r\n const merged = mergeResults(results, opts.outputFormat!);\r\n return new TextEncoder().encode(merged);\r\n }\r\n\r\n private async convertUsingJsParallelism(input: Uint8Array, opts: ConvertBuddyOptions, numThreads: number): Promise<Uint8Array> {\r\n // Split input into chunks based on line boundaries for CSV/NDJSON\r\n const chunks = this.splitIntoChunks(input, Math.max(1, Math.floor(input.length / numThreads)));\r\n \r\n if (opts.debug) {\r\n console.log(`[convert-buddy] Processing ${chunks.length} chunks with JS-level parallelism`);\r\n }\r\n \r\n // Process chunks in parallel with improved coordination\r\n const chunkPromises = chunks.map(async (chunk, index) => {\r\n const chunkOpts = { ...opts, parallelism: 1 }; // Disable recursion\r\n \r\n // For CSV with headers, only the first chunk should process headers\r\n if (opts.inputFormat === \"csv\" && index > 0) {\r\n chunkOpts.csvConfig = { ...chunkOpts.csvConfig, hasHeaders: false };\r\n }\r\n \r\n const chunkBuddy = await ConvertBuddy.create(chunkOpts);\r\n const output = chunkBuddy.push(chunk);\r\n const final = chunkBuddy.finish();\r\n \r\n // Combine chunk output\r\n const result = new Uint8Array(output.length + final.length);\r\n result.set(output, 0);\r\n result.set(final, output.length);\r\n \r\n return result;\r\n });\r\n\r\n const chunkResults = await Promise.all(chunkPromises);\r\n\r\n // Combine results more efficiently\r\n const totalLength = chunkResults.reduce((sum, chunk) => sum + chunk.length, 0);\r\n const result = new Uint8Array(totalLength);\r\n \r\n let offset = 0;\r\n for (const chunk of chunkResults) {\r\n result.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n\r\n if (opts.debug) {\r\n console.log(`[convert-buddy] JS parallel processing completed: ${chunks.length} chunks, ${totalLength} bytes`);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private splitIntoChunks(input: Uint8Array, targetChunkSize: number): Uint8Array[] {\r\n if (input.length <= targetChunkSize) {\r\n return [input];\r\n }\r\n\r\n const chunks: Uint8Array[] = [];\r\n let start = 0;\r\n\r\n while (start < input.length) {\r\n let end = Math.min(start + targetChunkSize, input.length);\r\n \r\n // Try to find a line boundary within a reasonable range\r\n if (end < input.length) {\r\n const searchStart = Math.max(start + targetChunkSize - 1024, start);\r\n const searchEnd = Math.min(end + 1024, input.length);\r\n \r\n // Look for newline\r\n for (let i = searchEnd - 1; i >= searchStart; i--) {\r\n if (input[i] === 0x0A) { // '\\n'\r\n end = i + 1;\r\n break;\r\n }\r\n }\r\n }\r\n \r\n chunks.push(input.slice(start, end));\r\n start = end;\r\n }\r\n\r\n return chunks;\r\n }\r\n\r\n private async convertFromFile(file: File, opts: ConvertBuddyOptions): Promise<Uint8Array> {\r\n return this.convertFromBlob(file, opts);\r\n }\r\n\r\n private async convertFromBlob(blob: Blob, opts: ConvertBuddyOptions): Promise<Uint8Array> {\r\n warnIfLargeFile(blob.size, \"convert\");\r\n \r\n // Handle auto-detection\r\n let actualOpts = { ...opts };\r\n \r\n if (opts.inputFormat === \"auto\") {\r\n const sampleSize = 256 * 1024; // 256KB\r\n const sampleBlob = blob.slice(0, sampleSize);\r\n const sampleBuffer = await sampleBlob.arrayBuffer();\r\n const sample = new Uint8Array(sampleBuffer as ArrayBuffer);\r\n \r\n const detected = await autoDetectConfig(sample, { debug: opts.debug });\r\n \r\n if (detected.format !== \"unknown\") {\r\n actualOpts.inputFormat = detected.format as Format;\r\n \r\n if (detected.csvConfig) {\r\n actualOpts.csvConfig = opts.csvConfig ? { ...detected.csvConfig, ...opts.csvConfig } : detected.csvConfig;\r\n }\r\n \r\n if (detected.xmlConfig) {\r\n actualOpts.xmlConfig = opts.xmlConfig ? { ...detected.xmlConfig, ...opts.xmlConfig } : detected.xmlConfig;\r\n }\r\n \r\n if (opts.debug) {\r\n console.log(\"[convert-buddy] Auto-detected format:\", detected.format);\r\n }\r\n } else {\r\n throw new Error(\"Could not auto-detect input format. Please specify inputFormat explicitly.\");\r\n }\r\n }\r\n\r\n const buddy = await ConvertBuddy.create(actualOpts);\r\n \r\n // Read blob as stream and process\r\n const stream = blob.stream();\r\n const reader = stream.getReader();\r\n \r\n const outputs: Uint8Array[] = [];\r\n \r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n \r\n const output = buddy.push(value);\r\n if (output.length > 0) {\r\n outputs.push(output);\r\n }\r\n }\r\n \r\n const final = buddy.finish();\r\n if (final.length > 0) {\r\n outputs.push(final);\r\n }\r\n \r\n // Combine all outputs\r\n const totalLength = outputs.reduce((sum, arr) => sum + arr.length, 0);\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const output of outputs) {\r\n result.set(output, offset);\r\n offset += output.length;\r\n }\r\n \r\n if (opts.profile) {\r\n const stats = buddy.stats();\r\n console.log(\"[convert-buddy] Performance Stats:\", stats);\r\n }\r\n \r\n return result;\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n }\r\n\r\n private async convertFromStream(stream: ReadableStream<Uint8Array>, opts: ConvertBuddyOptions): Promise<Uint8Array> {\r\n // Handle auto-detection by reading a sample first\r\n let actualOpts = { ...opts };\r\n let firstChunks: Uint8Array[] = [];\r\n let totalSampleBytes = 0;\r\n const maxSampleSize = 256 * 1024; // 256KB\r\n \r\n if (opts.inputFormat === \"auto\") {\r\n const reader = stream.getReader();\r\n \r\n try {\r\n while (totalSampleBytes < maxSampleSize) {\r\n const { done, value } = await reader.read();\r\n if (done || !value) break;\r\n \r\n firstChunks.push(value);\r\n totalSampleBytes += value.length;\r\n }\r\n \r\n // Concatenate sample\r\n const sample = new Uint8Array(totalSampleBytes);\r\n let offset = 0;\r\n for (const chunk of firstChunks) {\r\n sample.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n \r\n const detected = await autoDetectConfig(sample, { debug: opts.debug });\r\n \r\n if (detected.format !== \"unknown\") {\r\n actualOpts.inputFormat = detected.format as Format;\r\n \r\n if (detected.csvConfig) {\r\n actualOpts.csvConfig = opts.csvConfig ? { ...detected.csvConfig, ...opts.csvConfig } : detected.csvConfig;\r\n }\r\n \r\n if (detected.xmlConfig) {\r\n actualOpts.xmlConfig = opts.xmlConfig ? { ...detected.xmlConfig, ...opts.xmlConfig } : detected.xmlConfig;\r\n }\r\n \r\n if (opts.debug) {\r\n console.log(\"[convert-buddy] Auto-detected format:\", detected.format);\r\n }\r\n } else {\r\n throw new Error(\"Could not auto-detect input format. Please specify inputFormat explicitly.\");\r\n }\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n }\r\n\r\n const buddy = await ConvertBuddy.create(actualOpts);\r\n \r\n // Process buffered chunks from auto-detection\r\n const outputs: Uint8Array[] = [];\r\n for (const chunk of firstChunks) {\r\n const output = buddy.push(chunk);\r\n if (output.length > 0) {\r\n outputs.push(output);\r\n }\r\n }\r\n \r\n // Continue with the rest of the stream\r\n const reader = stream.getReader();\r\n \r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n \r\n const output = buddy.push(value);\r\n if (output.length > 0) {\r\n outputs.push(output);\r\n }\r\n }\r\n \r\n const final = buddy.finish();\r\n if (final.length > 0) {\r\n outputs.push(final);\r\n }\r\n \r\n // Combine all outputs\r\n const totalLength = outputs.reduce((sum, arr) => sum + arr.length, 0);\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const output of outputs) {\r\n result.set(output, offset);\r\n offset += output.length;\r\n }\r\n \r\n if (opts.profile) {\r\n const stats = buddy.stats();\r\n console.log(\"[convert-buddy] Performance Stats:\", stats);\r\n }\r\n \r\n return result;\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n }\r\n\r\n /**\r\n * Legacy create method for backward compatibility.\r\n * Prefer using the constructor: new ConvertBuddy(opts)\r\n */\r\n static async create(opts: ConvertBuddyOptions = {}): Promise<ConvertBuddy> {\r\n const debug = !!opts.debug;\r\n const profile = opts.profile !== false; // Stats always enabled by default\r\n\r\n // Initialize WASM once (singleton)\r\n await initWasm(debug);\r\n\r\n const wasmModule = await loadWasmModule();\r\n\r\n // Handle auto-detection\r\n let inputFormat = opts.inputFormat;\r\n let csvConfig = opts.csvConfig;\r\n\r\n // We can't auto-detect without data, so we'll defer this to push()\r\n // For now, just validate the format if it's not \"auto\"\r\n if (inputFormat === \"auto\") {\r\n // Auto-detection will be handled on first push()\r\n inputFormat = undefined;\r\n }\r\n\r\n // Optimize chunk size for better WASM performance\r\n // Larger chunks reduce boundary crossing overhead\r\n // Default: 512KB (was 1MB), but can be customized\r\n const chunkTargetBytes = opts.chunkTargetBytes || (512 * 1024);\r\n\r\n let converter;\r\n if (inputFormat && opts.outputFormat) {\r\n // Use withConfig for custom formats\r\n const Converter = (wasmModule as any).Converter;\r\n try {\r\n converter = Converter.withConfig(\r\n debug,\r\n inputFormat,\r\n opts.outputFormat,\r\n chunkTargetBytes,\r\n profile, // Enable stats tracking when profile is enabled\r\n csvConfig || null,\r\n opts.xmlConfig || null,\r\n opts.transform || null,\r\n opts.pretty ?? true\r\n );\r\n } catch (err: any) {\r\n // Enhance error message for common issues\r\n const errorMsg = typeof err === 'string' ? err : err?.message || String(err);\r\n if (errorMsg.includes('Invalid output format')) {\r\n const validFormats = ['csv', 'json', 'ndjson', 'xml'];\r\n throw new Error(`Invalid outputFormat: \"${opts.outputFormat}\". Must be one of: ${validFormats.join(', ')}`);\r\n } else if (errorMsg.includes('Invalid input format')) {\r\n const validFormats = ['csv', 'json', 'ndjson', 'xml', 'auto'];\r\n throw new Error(`Invalid inputFormat: \"${inputFormat}\". Must be one of: ${validFormats.join(', ')}`);\r\n }\r\n throw new Error(`Configuration error: ${errorMsg}`);\r\n }\r\n } else {\r\n converter = new wasmModule.Converter(debug);\r\n }\r\n\r\n // Check if SIMD is enabled\r\n const simdEnabled = (wasmModule as any).getSimdEnabled?.() ?? false;\r\n\r\n if (debug) console.log(\"[convert-buddy-js] initialized with chunkTargetBytes:\", chunkTargetBytes, \"simd:\", simdEnabled, opts);\r\n \r\n // Create instance using constructor and set internal properties\r\n const instance = new ConvertBuddy(opts);\r\n instance.converter = converter;\r\n instance.simd = simdEnabled;\r\n instance.initialized = true;\r\n \r\n return instance;\r\n }\r\n\r\n push(chunk: Uint8Array): Uint8Array {\r\n if (this.aborted) {\r\n throw new Error(\"Conversion has been aborted\");\r\n }\r\n\r\n if (this.paused) {\r\n throw new Error(\"Conversion is paused. Call resume() before pushing more data.\");\r\n }\r\n\r\n if (this.debug) console.log(\"[convert-buddy-js] push\", chunk.byteLength);\r\n const output = this.converter.push(chunk);\r\n\r\n // Check if we should trigger progress callback\r\n if (this.onProgress) {\r\n const stats = this.stats();\r\n if (stats.bytesIn - this.lastProgressBytes >= this.progressIntervalBytes) {\r\n this.onProgress(stats);\r\n this.lastProgressBytes = stats.bytesIn;\r\n }\r\n }\r\n\r\n return output;\r\n }\r\n\r\n /**\r\n * Push a chunk and optionally get pre-parsed records.\r\n * This is more efficient than parsing the output yourself.\r\n * \r\n * @param chunk - Input chunk to process\r\n * @param includeRecords - If true, returns { output, records }, otherwise just output bytes\r\n * @returns Either Uint8Array or { output: Uint8Array, records: any[] }\r\n */\r\n pushWithRecords(chunk: Uint8Array, includeRecords: boolean = true): Uint8Array | { output: Uint8Array; records: any[] } {\r\n if (this.aborted) {\r\n throw new Error(\"Conversion has been aborted\");\r\n }\r\n\r\n if (this.paused) {\r\n throw new Error(\"Conversion is paused. Call resume() before pushing more data.\");\r\n }\r\n\r\n if (this.debug) console.log(\"[convert-buddy-js] pushWithRecords\", chunk.byteLength, \"includeRecords:\", includeRecords);\r\n \r\n // Check if WASM supports pushWithRecords\r\n if (typeof this.converter.pushWithRecords === 'function') {\r\n const result = this.converter.pushWithRecords(chunk, includeRecords);\r\n \r\n // Check if we should trigger progress callback\r\n if (this.onProgress) {\r\n const stats = this.stats();\r\n if (stats.bytesIn - this.lastProgressBytes >= this.progressIntervalBytes) {\r\n this.onProgress(stats);\r\n this.lastProgressBytes = stats.bytesIn;\r\n }\r\n }\r\n \r\n return result;\r\n } else {\r\n // Fallback to regular push if WASM doesn't support it yet\r\n const output = this.push(chunk);\r\n if (includeRecords) {\r\n return { output, records: [] }; // Caller will use splitter\r\n }\r\n return output;\r\n }\r\n }\r\n\r\n finish(): Uint8Array {\r\n if (this.aborted) {\r\n throw new Error(\"Conversion has been aborted\");\r\n }\r\n\r\n if (this.debug) console.log(\"[convert-buddy-js] finish\");\r\n const output = this.converter.finish();\r\n\r\n // Final progress callback\r\n if (this.onProgress) {\r\n this.onProgress(this.stats());\r\n }\r\n\r\n return output;\r\n }\r\n\r\n stats(): Stats {\r\n if (!this.converter || typeof this.converter.getStats !== 'function') {\r\n // Converter not initialized yet\r\n return {\r\n bytesIn: 0,\r\n bytesOut: 0,\r\n chunksIn: 0,\r\n recordsProcessed: 0,\r\n parseTimeMs: 0,\r\n transformTimeMs: 0,\r\n writeTimeMs: 0,\r\n maxBufferSize: 0,\r\n currentPartialSize: 0,\r\n throughputMbPerSec: 0,\r\n };\r\n }\r\n\r\n try {\r\n const wasmStats = this.converter.getStats();\r\n \r\n // WASM object properties are snake_case (Rust convention via wasm_bindgen getters)\r\n return {\r\n bytesIn: wasmStats.bytes_in,\r\n bytesOut: wasmStats.bytes_out,\r\n chunksIn: wasmStats.chunks_in,\r\n recordsProcessed: wasmStats.records_processed,\r\n parseTimeMs: wasmStats.parse_time_ms,\r\n transformTimeMs: wasmStats.transform_time_ms,\r\n writeTimeMs: wasmStats.write_time_ms,\r\n maxBufferSize: wasmStats.max_buffer_size,\r\n currentPartialSize: wasmStats.current_partial_size,\r\n throughputMbPerSec: wasmStats.throughput_mb_per_sec,\r\n };\r\n } catch (e) {\r\n if (this.debug) console.error(\"[convert-buddy-js] Error getting stats:\", e);\r\n return {\r\n bytesIn: 0,\r\n bytesOut: 0,\r\n chunksIn: 0,\r\n recordsProcessed: 0,\r\n parseTimeMs: 0,\r\n transformTimeMs: 0,\r\n writeTimeMs: 0,\r\n maxBufferSize: 0,\r\n currentPartialSize: 0,\r\n throughputMbPerSec: 0,\r\n };\r\n }\r\n }\r\n\r\n abort(): void {\r\n this.aborted = true;\r\n if (this.debug) console.log(\"[convert-buddy-js] aborted\");\r\n }\r\n\r\n pause(): void {\r\n this.paused = true;\r\n if (this.debug) console.log(\"[convert-buddy-js] paused\");\r\n }\r\n\r\n resume(): void {\r\n this.paused = false;\r\n if (this.debug) console.log(\"[convert-buddy-js] resumed\");\r\n }\r\n\r\n isAborted(): boolean {\r\n return this.aborted;\r\n }\r\n\r\n isPaused(): boolean {\r\n return this.paused;\r\n }\r\n}\r\n\r\nasync function readSample(\r\n input: DetectInput,\r\n maxBytes = 256 * 1024\r\n): Promise<Uint8Array> {\r\n if (typeof input === \"string\") {\r\n const encoded = new TextEncoder().encode(input);\r\n return encoded.length > maxBytes ? encoded.slice(0, maxBytes) : encoded;\r\n }\r\n\r\n if (input instanceof Uint8Array) {\r\n return input.length > maxBytes ? input.slice(0, maxBytes) : input;\r\n }\r\n\r\n if (input instanceof ArrayBuffer) {\r\n const bytes = new Uint8Array(input as ArrayBuffer);\r\n return bytes.length > maxBytes ? bytes.slice(0, maxBytes) : bytes;\r\n }\r\n\r\n if (isReadableStream(input)) {\r\n const reader = input.getReader();\r\n const chunks: Uint8Array[] = [];\r\n let total = 0;\r\n\r\n while (total < maxBytes) {\r\n const { value, done } = await reader.read();\r\n if (done || !value) break;\r\n const slice = total + value.length > maxBytes\r\n ? value.slice(0, maxBytes - total)\r\n : value;\r\n chunks.push(slice);\r\n total += slice.length;\r\n }\r\n\r\n if (total >= maxBytes) {\r\n await reader.cancel();\r\n }\r\n\r\n return concatChunks(chunks, total);\r\n }\r\n\r\n const chunks: Uint8Array[] = [];\r\n let total = 0;\r\n\r\n for await (const chunk of input as AsyncIterable<Uint8Array>) {\r\n if (total >= maxBytes) {\r\n break;\r\n }\r\n const data = chunk instanceof Uint8Array ? chunk : new Uint8Array(chunk);\r\n const slice = total + data.length > maxBytes\r\n ? data.slice(0, maxBytes - total)\r\n : data;\r\n chunks.push(slice);\r\n total += slice.length;\r\n }\r\n\r\n return concatChunks(chunks, total);\r\n}\r\n\r\nfunction concatChunks(chunks: Uint8Array[], total: number): Uint8Array {\r\n const result = new Uint8Array(total);\r\n let offset = 0;\r\n for (const chunk of chunks) {\r\n result.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n return result;\r\n}\r\n\r\nfunction isReadableStream(\r\n input: DetectInput\r\n): input is ReadableStream<Uint8Array> {\r\n return typeof (input as ReadableStream<Uint8Array>)?.getReader === \"function\";\r\n}\r\n\r\nasync function loadDetectionWasm(debug: boolean): Promise<WasmModule> {\r\n const wasmModule = await loadWasmModule();\r\n if (typeof wasmModule.default === \"function\") {\r\n await (wasmModule.default as () => Promise<void>)();\r\n }\r\n wasmModule.init(debug);\r\n return wasmModule;\r\n}\r\n\r\nexport async function detectFormat(\r\n input: DetectInput,\r\n opts: DetectOptions = {}\r\n): Promise<Format | \"unknown\"> {\r\n const wasmModule = await loadDetectionWasm(!!opts.debug);\r\n const sample = await readSample(input, opts.maxBytes);\r\n const format = wasmModule.detectFormat?.(sample);\r\n return (format as Format) ?? \"unknown\";\r\n}\r\n\r\nexport async function detectStructure(\r\n input: DetectInput,\r\n formatHint?: Format,\r\n opts: DetectOptions = {}\r\n): Promise<StructureDetection | null> {\r\n const wasmModule = await loadDetectionWasm(!!opts.debug);\r\n const sample = await readSample(input, opts.maxBytes);\r\n const result = wasmModule.detectStructure?.(sample, formatHint);\r\n return result ?? null;\r\n}\r\n\r\n// Backward compatibility functions - these now use the unified detectStructure internally\r\nexport async function detectCsvFieldsAndDelimiter(\r\n input: DetectInput,\r\n opts: DetectOptions = {}\r\n): Promise<CsvDetection | null> {\r\n const structure = await detectStructure(input, \"csv\", opts);\r\n if (structure && structure.format === \"csv\" && structure.delimiter) {\r\n return {\r\n delimiter: structure.delimiter,\r\n fields: structure.fields,\r\n };\r\n }\r\n return null;\r\n}\r\n\r\nexport async function detectXmlElements(\r\n input: DetectInput,\r\n opts: DetectOptions = {}\r\n): Promise<XmlDetection | null> {\r\n const structure = await detectStructure(input, \"xml\", opts);\r\n if (structure && structure.format === \"xml\") {\r\n return {\r\n elements: structure.fields,\r\n recordElement: structure.recordElement,\r\n };\r\n }\r\n return null;\r\n}\r\n\r\n// Helper to auto-detect format and CSV/XML configuration from sample data\r\nexport async function autoDetectConfig(\r\n input: DetectInput,\r\n opts: DetectOptions = {}\r\n): Promise<{ \r\n format: Format | \"unknown\"; \r\n csvConfig?: CsvConfig;\r\n xmlConfig?: XmlConfig;\r\n}> {\r\n const wasmModule = await loadDetectionWasm(!!opts.debug);\r\n const sample = await readSample(input, opts.maxBytes);\r\n \r\n const format = (wasmModule.detectFormat?.(sample) as Format) ?? \"unknown\";\r\n \r\n const result: { format: Format | \"unknown\"; csvConfig?: CsvConfig; xmlConfig?: XmlConfig } = { format };\r\n \r\n if (format === \"csv\") {\r\n const csvDetection = wasmModule.detectCsvFields?.(sample);\r\n if (csvDetection) {\r\n result.csvConfig = {\r\n delimiter: csvDetection.delimiter,\r\n hasHeaders: csvDetection.fields.length > 0,\r\n };\r\n }\r\n } else if (format === \"xml\") {\r\n const xmlDetection = wasmModule.detectXmlElements?.(sample);\r\n if (xmlDetection?.recordElement) {\r\n result.xmlConfig = {\r\n recordElement: xmlDetection.recordElement,\r\n };\r\n }\r\n }\r\n \r\n return result;\r\n}\r\n\r\n// Web Streams TransformStream adapter\r\nexport class ConvertBuddyTransformStream extends TransformStream<Uint8Array, Uint8Array> {\r\n constructor(opts: ConvertBuddyOptions = {}) {\r\n let buddy: ConvertBuddy | null = null;\r\n\r\n super({\r\n async start(controller) {\r\n buddy = await ConvertBuddy.create(opts);\r\n },\r\n\r\n transform(chunk, controller) {\r\n if (!buddy) {\r\n throw new Error(\"ConvertBuddy not initialized\");\r\n }\r\n\r\n const output = buddy.push(chunk);\r\n if (output.length > 0) {\r\n controller.enqueue(output);\r\n }\r\n },\r\n\r\n flush(controller) {\r\n if (!buddy) {\r\n return;\r\n }\r\n\r\n const output = buddy.finish();\r\n if (output.length > 0) {\r\n controller.enqueue(output);\r\n }\r\n\r\n if (opts.profile) {\r\n const stats = buddy.stats();\r\n console.log(\"[convert-buddy] Performance Stats:\", stats);\r\n }\r\n },\r\n });\r\n }\r\n}\r\n\r\n// Utility: Convert entire buffer/string\r\nexport async function convert(\r\n input: Uint8Array | string,\r\n opts: ConvertBuddyOptions = {}\r\n): Promise<Uint8Array> {\r\n try {\r\n // Validate outputFormat early\r\n if (opts.outputFormat) {\r\n const validFormats = ['csv', 'json', 'ndjson', 'xml'];\r\n if (!validFormats.includes(opts.outputFormat)) {\r\n throw new Error(`Invalid outputFormat: \"${opts.outputFormat}\". Must be one of: ${validFormats.join(', ')}`);\r\n }\r\n }\r\n\r\n // Validate inputFormat early (if specified)\r\n if (opts.inputFormat && opts.inputFormat !== 'auto') {\r\n const validFormats = ['csv', 'json', 'ndjson', 'xml'];\r\n if (!validFormats.includes(opts.inputFormat)) {\r\n throw new Error(`Invalid inputFormat: \"${opts.inputFormat}\". Must be one of: ${validFormats.join(', ')}, or \"auto\"`);\r\n }\r\n }\r\n\r\n const inputBytes = typeof input === \"string\" \r\n ? new TextEncoder().encode(input)\r\n : input;\r\n\r\n // If inputFormat is not specified or is \"auto\", perform auto-detection\r\n let actualOpts = opts;\r\n if (!opts.inputFormat || opts.inputFormat === \"auto\") {\r\n const sample = inputBytes.length > 256 * 1024 \r\n ? inputBytes.slice(0, 256 * 1024) \r\n : inputBytes;\r\n \r\n const detected = await autoDetectConfig(sample, { debug: opts.debug });\r\n \r\n if (detected.format !== \"unknown\") {\r\n actualOpts = { ...opts, inputFormat: detected.format as Format };\r\n \r\n if (detected.csvConfig && !opts.csvConfig) {\r\n actualOpts.csvConfig = detected.csvConfig;\r\n }\r\n \r\n if (detected.xmlConfig && !opts.xmlConfig) {\r\n actualOpts.xmlConfig = detected.xmlConfig;\r\n }\r\n \r\n if (opts.debug) {\r\n console.log(\"[convert-buddy] Auto-detected format:\", detected.format);\r\n }\r\n } else {\r\n throw new Error(\"Could not auto-detect input format. Please specify inputFormat explicitly.\");\r\n }\r\n }\r\n\r\n const buddy = await ConvertBuddy.create(actualOpts);\r\n\r\n const output = buddy.push(inputBytes);\r\n const final = buddy.finish();\r\n\r\n // Combine outputs\r\n const result = new Uint8Array(output.length + final.length);\r\n result.set(output, 0);\r\n result.set(final, output.length);\r\n\r\n if (opts.profile) {\r\n const stats = buddy.stats();\r\n console.log(\"[convert-buddy] Performance Stats:\", stats);\r\n }\r\n\r\n return result;\r\n } catch (err: any) {\r\n // Normalize non-Error throws (e.g., wasm JsValue) into Error with message\r\n if (err instanceof Error) throw err;\r\n try {\r\n // Try to stringify common structures\r\n const msg = typeof err === 'string' ? err : (err && err.message) ? err.message : JSON.stringify(err);\r\n throw new Error(String(msg));\r\n } catch (_) {\r\n throw new Error(String(err));\r\n }\r\n }\r\n}\r\n\r\n// Utility: Convert and return as string\r\nexport async function convertToString(\r\n input: Uint8Array | string,\r\n opts: ConvertBuddyOptions = {}\r\n): Promise<string> {\r\n const result = await convert(input, opts);\r\n return decodeUtf8(result);\r\n}\r\n\r\n/**\r\n * Ultra-simple standalone convert function with auto-detection.\r\n * Accepts any input type (URL, File, Buffer, string, stream) and automatically detects format.\r\n * \r\n * @example\r\n * // From URL\r\n * import { convertAny } from \"convert-buddy-js\";\r\n * const result = await convertAny(\"https://example.com/data.csv\", { outputFormat: \"json\" });\r\n * \r\n * @example\r\n * // From File (browser)\r\n * const file = fileInput.files[0];\r\n * const result = await convertAny(file, { outputFormat: \"ndjson\" });\r\n * \r\n * @example\r\n * // From string data\r\n * const result = await convertAny('{\"name\":\"Ada\"}', { outputFormat: \"csv\" });\r\n */\r\nexport async function convertAny(\r\n input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>,\r\n opts: ConvertOptions\r\n): Promise<Uint8Array> {\r\n // Validate outputFormat is provided\r\n if (!opts.outputFormat) {\r\n throw new Error('outputFormat is required. Must be one of: csv, json, ndjson, xml');\r\n }\r\n\r\n // Validate outputFormat value\r\n const validFormats = ['csv', 'json', 'ndjson', 'xml'];\r\n if (!validFormats.includes(opts.outputFormat)) {\r\n throw new Error(`Invalid outputFormat: \"${opts.outputFormat}\". Must be one of: ${validFormats.join(', ')}`);\r\n }\r\n\r\n // Validate inputFormat if specified\r\n if (opts.inputFormat && opts.inputFormat !== 'auto') {\r\n if (!validFormats.includes(opts.inputFormat)) {\r\n throw new Error(`Invalid inputFormat: \"${opts.inputFormat}\". Must be one of: ${validFormats.join(', ')}, or \"auto\"`);\r\n }\r\n }\r\n\r\n const buddy = new ConvertBuddy();\r\n return buddy.convert(input, opts);\r\n}\r\n\r\n/**\r\n * Ultra-simple standalone convert function that returns a string.\r\n * Same as convertAny but decodes the output to a string.\r\n * \r\n * @example\r\n * import { convertAnyToString } from \"convert-buddy-js\";\r\n * const json = await convertAnyToString(\"https://example.com/data.csv\", { outputFormat: \"json\" });\r\n * console.log(JSON.parse(json));\r\n */\r\nexport async function convertAnyToString(\r\n input: string | Uint8Array | File | Blob | ReadableStream<Uint8Array>,\r\n opts: ConvertOptions\r\n): Promise<string> {\r\n const result = await convertAny(input, opts);\r\n return decodeUtf8(result);\r\n}\r\n\r\n// ===== Helper Functions =====\r\n// File format utilities for common use cases\r\n\r\n/**\r\n * Get MIME type for a given format\r\n * \r\n * @example\r\n * const mimeType = getMimeType(\"json\"); // \"application/json\"\r\n */\r\nexport function getMimeType(format: Format): string {\r\n switch (format) {\r\n case \"json\":\r\n return \"application/json\";\r\n case \"ndjson\":\r\n return \"application/x-ndjson\";\r\n case \"csv\":\r\n return \"text/csv\";\r\n case \"xml\":\r\n return \"application/xml\";\r\n }\r\n}\r\n\r\n/**\r\n * Get file extension for a given format (without the dot)\r\n * \r\n * @example\r\n * const ext = getExtension(\"json\"); // \"json\"\r\n */\r\nexport function getExtension(format: Format): string {\r\n return format;\r\n}\r\n\r\n/**\r\n * Get suggested filename for a converted file\r\n * \r\n * @param originalName - Original filename\r\n * @param outputFormat - Target format\r\n * @param includeTimestamp - Whether to include a timestamp (default: false)\r\n * \r\n * @example\r\n * const name = getSuggestedFilename(\"data.csv\", \"json\"); // \"data.json\"\r\n * const name = getSuggestedFilename(\"data.csv\", \"json\", true); // \"data_converted_1234567890.json\"\r\n */\r\nexport function getSuggestedFilename(\r\n originalName: string,\r\n outputFormat: Format,\r\n includeTimestamp = false\r\n): string {\r\n const baseName = originalName.replace(/\\.[^/.]+$/, \"\");\r\n const extension = getExtension(outputFormat);\r\n \r\n if (includeTimestamp) {\r\n return `${baseName}_converted_${Date.now()}.${extension}`;\r\n }\r\n \r\n return `${baseName}.${extension}`;\r\n}\r\n\r\n/**\r\n * Get File System Access API file type configuration for showSaveFilePicker\r\n * \r\n * @example\r\n * const types = getFileTypeConfig(\"json\");\r\n * const handle = await showSaveFilePicker({ types });\r\n */\r\nexport function getFileTypeConfig(format: Format): Array<{\r\n description: string;\r\n accept: Record<string, string[]>;\r\n}> {\r\n const mimeType = getMimeType(format);\r\n const extension = `.${getExtension(format)}`;\r\n \r\n return [\r\n {\r\n description: `${format.toUpperCase()} Files`,\r\n accept: { [mimeType]: [extension] },\r\n },\r\n ];\r\n}\r\n\r\n// WASM Threading Capabilities API\r\n/**\r\n * Check if WASM threading is supported in the current environment\r\n * @returns true if SharedArrayBuffer and Atomics are available (required for WASM threads)\r\n */\r\nexport function isWasmThreadingSupported(): boolean {\r\n return detectWasmThreadingSupport();\r\n}\r\n\r\n/**\r\n * Get the optimal number of worker threads based on CPU cores and WASM capabilities\r\n * @returns Recommended thread count for optimal performance\r\n */\r\nexport function getOptimalThreadCount(): number {\r\n const cores = typeof navigator !== 'undefined' \r\n ? (navigator.hardwareConcurrency || 4)\r\n : (process?.env?.UV_THREADPOOL_SIZE ? parseInt(process.env.UV_THREADPOOL_SIZE) : \r\n typeof require !== 'undefined' ? require('os').cpus().length : 4);\r\n \r\n // For current JavaScript-level parallelism, limit to 4 parallel instances\r\n // When true WASM threading is enabled, this can be increased\r\n return Math.min(cores, 4);\r\n}\r\n\r\n/**\r\n * Get current threading capabilities and configuration\r\n * @returns Object with threading information\r\n */\r\nexport function getThreadingInfo(): {\r\n wasmThreadingSupported: boolean;\r\n customThreadPoolAvailable: boolean;\r\n nodejsWasmThreading: boolean;\r\n recommendedThreads: number;\r\n currentThreads: number;\r\n approach: string;\r\n} {\r\n const isNodejs = typeof process !== 'undefined';\r\n \r\n return {\r\n wasmThreadingSupported: detectWasmThreadingSupport(),\r\n customThreadPoolAvailable: typeof window !== 'undefined',\r\n nodejsWasmThreading: isNodejs && !!nodejsThreadPool,\r\n recommendedThreads: getOptimalThreadCount(),\r\n currentThreads: isNodejs ? \r\n (nodejsThreadPool ? nodejsThreadPool.workers?.length || 0 : 0) :\r\n (threadPool ? threadPool.workers?.length || 0 : 0),\r\n approach: isNodejs ? 'nodejs_enhanced_threading' : 'browser_custom_threading'\r\n };\r\n}\r\n\r\n/**\r\n * Backward compatibility alias for ConvertBuddy\r\n * @deprecated Use ConvertBuddy instead\r\n */\r\nexport const Converter = ConvertBuddy;\r\n\r\n// ============================================================================\r\n// Streaming API (Primary API)\r\n// ============================================================================\r\n\r\n// Import the new buddy-stream module\r\nimport { \r\n createBuddyController as _createBuddyController,\r\n _setConverterFactory,\r\n stream as buddyStream,\r\n} from './buddy-stream.js';\r\n\r\n// Re-export streaming API\r\nexport { stream } from './buddy-stream.js';\r\n\r\n// Internal reference for ConvertBuddy.stream() method\r\nconst __createBuddyController = _createBuddyController;\r\n\r\n// Register the converter factory for standalone stream() function\r\n_setConverterFactory(async (opts) => {\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: opts.inputFormat,\r\n outputFormat: opts.outputFormat,\r\n csvConfig: opts.csvConfig,\r\n xmlConfig: opts.xmlConfig,\r\n transform: opts.transform,\r\n debug: opts.debug,\r\n profile: opts.profile ?? true,\r\n });\r\n \r\n // Create a wrapper that implements ConverterInterface\r\n return {\r\n push: (chunk: Uint8Array) => buddy.push(chunk),\r\n pushWithRecords: (chunk: Uint8Array, includeRecords: boolean) => buddy.pushWithRecords(chunk, includeRecords),\r\n finish: () => buddy.finish(),\r\n getStats: () => buddy.stats(),\r\n } as ConverterInterface;\r\n});\r\n\r\n// ============================================================================\r\n"],"mappings":"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","names":["require","mod","stream","result","reader","Converter","chunks","total"]}
@@ -3,28 +3,49 @@ import { convertToString, convert } from "../../index.js";
3
3
  import { strict as assert } from "node:assert";
4
4
  describe("NDJSON Edge Cases - Comprehensive Safety Tests", () => {
5
5
  describe("Line Handling", () => {
6
- it("should handle empty file", async () => {
7
- const result = await convertToString("", {
6
+ it("should handle empty file (pretty and compact)", async () => {
7
+ const prettyResult = await convertToString("", {
8
8
  inputFormat: "ndjson",
9
9
  outputFormat: "json"
10
10
  });
11
- assert.strictEqual(result.trim(), "[]");
11
+ const parsedPretty = JSON.parse(prettyResult);
12
+ assert.strictEqual(parsedPretty.length, 0);
13
+ const compactResult = await convertToString("", {
14
+ inputFormat: "ndjson",
15
+ outputFormat: "json",
16
+ pretty: false
17
+ });
18
+ assert.strictEqual(compactResult.trim(), "[]");
12
19
  });
13
- it("should handle file with only empty lines", async () => {
20
+ it("should handle file with only empty lines (pretty and compact)", async () => {
14
21
  const ndjson = "\n\n\n\n";
15
- const result = await convertToString(ndjson, {
22
+ const prettyResult = await convertToString(ndjson, {
16
23
  inputFormat: "ndjson",
17
24
  outputFormat: "json"
18
25
  });
19
- assert.strictEqual(result.trim(), "[]");
26
+ const parsedPretty = JSON.parse(prettyResult);
27
+ assert.strictEqual(parsedPretty.length, 0);
28
+ const compactResult = await convertToString(ndjson, {
29
+ inputFormat: "ndjson",
30
+ outputFormat: "json",
31
+ pretty: false
32
+ });
33
+ assert.strictEqual(compactResult.trim(), "[]");
20
34
  });
21
- it("should handle lines with only whitespace", async () => {
35
+ it("should handle lines with only whitespace (pretty and compact)", async () => {
22
36
  const ndjson = " \n \n \n";
23
- const result = await convertToString(ndjson, {
37
+ const prettyResult = await convertToString(ndjson, {
24
38
  inputFormat: "ndjson",
25
39
  outputFormat: "json"
26
40
  });
27
- assert.strictEqual(result.trim(), "[]");
41
+ const parsedPretty = JSON.parse(prettyResult);
42
+ assert.strictEqual(parsedPretty.length, 0);
43
+ const compactResult = await convertToString(ndjson, {
44
+ inputFormat: "ndjson",
45
+ outputFormat: "json",
46
+ pretty: false
47
+ });
48
+ assert.strictEqual(compactResult.trim(), "[]");
28
49
  });
29
50
  it("should handle empty lines between records", async () => {
30
51
  const ndjson = `{"name":"Alice"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../tests/edge-cases/ndjson-edge-cases.test.ts"],"sourcesContent":["import { describe, it } from \"node:test\";\r\nimport { convertToString, convert } from \"../../index.js\";\r\nimport { strict as assert } from \"node:assert\";\r\n\r\n/**\r\n * Comprehensive NDJSON Edge Case Test Suite\r\n * \r\n * Tests all possible edge cases for NDJSON parsing to ensure maximum safety.\r\n */\r\n\r\ndescribe(\"NDJSON Edge Cases - Comprehensive Safety Tests\", () => {\r\n \r\n // ========== LINE HANDLING ==========\r\n describe(\"Line Handling\", () => {\r\n it(\"should handle empty file\", async () => {\r\n const result = await convertToString(\"\", {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n assert.strictEqual(result.trim(), \"[]\");\r\n });\r\n\r\n it(\"should handle file with only empty lines\", async () => {\r\n const ndjson = \"\\n\\n\\n\\n\";\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n assert.strictEqual(result.trim(), \"[]\");\r\n });\r\n\r\n it(\"should handle lines with only whitespace\", async () => {\r\n const ndjson = \" \\n \\n \\n\";\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n assert.strictEqual(result.trim(), \"[]\");\r\n });\r\n\r\n it(\"should handle empty lines between records\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n\\n{\"name\":\"Bob\"}\\n\\n{\"name\":\"Charlie\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle very long lines (>10MB)\", async () => {\r\n const largeObj = { data: \"A\".repeat(1000000) };\r\n const ndjson = JSON.stringify(largeObj);\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle missing trailing newline\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n{\"name\":\"Bob\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n\r\n it(\"should handle multiple consecutive newlines\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n\\n\\n{\"name\":\"Bob\"}\\n\\n\\n`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n\r\n it(\"should handle single line NDJSON\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle CRLF line endings\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\r\\n{\"name\":\"Bob\"}\\r\\n`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n\r\n it(\"should handle mixed line endings (LF and CRLF)\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n{\"name\":\"Bob\"}\\r\\n{\"name\":\"Charlie\"}\\n`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n });\r\n\r\n // ========== JSON VALIDITY ==========\r\n describe(\"JSON Validity\", () => {\r\n it(\"should handle valid JSON objects\", async () => {\r\n const ndjson = `{\"name\":\"Alice\",\"age\":30}\\n{\"name\":\"Bob\",\"age\":25}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n\r\n it(\"should handle JSON arrays as records\", async () => {\r\n const ndjson = `[1,2,3]\\n[4,5,6]\\n[7,8,9]`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle JSON primitives (strings)\", async () => {\r\n const ndjson = `\"Alice\"\\n\"Bob\"\\n\"Charlie\"`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle JSON primitives (numbers)\", async () => {\r\n const ndjson = `42\\n3.14\\n-100`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle JSON primitives (booleans)\", async () => {\r\n const ndjson = `true\\nfalse\\ntrue`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle JSON null values\", async () => {\r\n const ndjson = `null\\nnull\\nnull`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle deeply nested objects (>10 levels)\", async () => {\r\n let obj: any = { value: \"deep\" };\r\n for (let i = 0; i < 15; i++) {\r\n obj = { nested: obj };\r\n }\r\n const ndjson = JSON.stringify(obj);\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle large arrays (>1000 elements)\", async () => {\r\n const largeArray = Array.from({ length: 2000 }, (_, i) => i);\r\n const ndjson = JSON.stringify(largeArray);\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle Unicode escape sequences\", async () => {\r\n const ndjson = `{\"emoji\":\"😀\"}\\n{\"text\":\"Hello\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n\r\n it(\"should handle special characters in strings\", async () => {\r\n const ndjson = `{\"text\":\"Line 1\\\\nLine 2\"}\\n{\"text\":\"Tab\\\\there\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n });\r\n\r\n // ========== DATA TYPES ==========\r\n describe(\"Data Types\", () => {\r\n it(\"should handle all JSON types in single record\", async () => {\r\n const ndjson = `{\"string\":\"text\",\"number\":42,\"boolean\":true,\"null\":null,\"array\":[1,2,3],\"object\":{\"nested\":\"value\"}}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n assert.strictEqual(parsed[0].string, \"text\");\r\n assert.strictEqual(parsed[0].number, 42);\r\n assert.strictEqual(parsed[0].boolean, true);\r\n assert.strictEqual(parsed[0].null, null);\r\n });\r\n\r\n it(\"should handle mixed types across records\", async () => {\r\n const ndjson = `{\"type\":\"object\"}\\n[1,2,3]\\n\"string\"\\n42\\ntrue\\nnull`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 6);\r\n });\r\n\r\n it(\"should handle empty objects\", async () => {\r\n const ndjson = `{}\\n{}\\n{}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle empty arrays\", async () => {\r\n const ndjson = `[]\\n[]\\n[]`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle very large strings (>1MB)\", async () => {\r\n const largeString = \"A\".repeat(2000000);\r\n const ndjson = JSON.stringify({ data: largeString });\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle numbers at precision limits\", async () => {\r\n const ndjson = `{\"max\":${Number.MAX_SAFE_INTEGER}}\\n{\"min\":${Number.MIN_SAFE_INTEGER}}\\n{\"float\":${Number.MAX_VALUE}}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle objects with many keys (>1000)\", async () => {\r\n const obj: any = {};\r\n for (let i = 0; i < 1500; i++) {\r\n obj[`key${i}`] = i;\r\n }\r\n const ndjson = JSON.stringify(obj);\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n assert.strictEqual(Object.keys(parsed[0]).length, 1500);\r\n });\r\n\r\n it(\"should handle objects with duplicate keys (last wins)\", async () => {\r\n const ndjson = `{\"key\":\"value1\",\"key\":\"value2\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle objects with special key names\", async () => {\r\n const ndjson = `{\"\":\"empty\",\"123\":\"numeric\",\"@#$\":\"special\",\"__proto__\":\"proto\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n });\r\n\r\n // ========== NDJSON PASSTHROUGH ==========\r\n describe(\"NDJSON Passthrough\", () => {\r\n it(\"should handle NDJSON → NDJSON passthrough\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n{\"name\":\"Bob\"}\\n{\"name\":\"Charlie\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"ndjson\",\r\n });\r\n const lines = result.trim().split(\"\\n\");\r\n assert.strictEqual(lines.length, 3);\r\n });\r\n\r\n it(\"should preserve record order in passthrough\", async () => {\r\n const ndjson = `{\"id\":1}\\n{\"id\":2}\\n{\"id\":3}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"ndjson\",\r\n });\r\n const lines = result.trim().split(\"\\n\");\r\n const first = JSON.parse(lines[0]);\r\n assert.strictEqual(first.id, 1);\r\n });\r\n\r\n it(\"should handle large passthrough (10K records)\", async () => {\r\n let ndjson = \"\";\r\n for (let i = 0; i < 10000; i++) {\r\n ndjson += `{\"id\":${i}}\\n`;\r\n }\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"ndjson\",\r\n });\r\n const lines = result.trim().split(\"\\n\");\r\n assert.strictEqual(lines.length, 10000);\r\n });\r\n });\r\n\r\n // ========== STREAMING AND BOUNDARIES ==========\r\n describe(\"Streaming and Chunk Boundaries\", () => {\r\n it(\"should handle records split across chunks\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n{\"name\":\"Bob\"}\\n{\"name\":\"Charlie\"}`;\r\n const data = new TextEncoder().encode(ndjson);\r\n \r\n const result = await convert(data, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n \r\n const resultStr = new TextDecoder().decode(result);\r\n const parsed = JSON.parse(resultStr);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle partial JSON objects across chunks\", async () => {\r\n const ndjson = `{\"name\":\"Alice\",\"age\":30}\\n{\"name\":\"Bob\",\"age\":25}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n });\r\n\r\n // ========== PERFORMANCE EDGE CASES ==========\r\n describe(\"Performance Edge Cases\", () => {\r\n it(\"should handle tiny files (<100 bytes)\", async () => {\r\n const ndjson = `{\"a\":1}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n assert.ok(result.length > 0);\r\n });\r\n\r\n it(\"should handle many small records\", async () => {\r\n let ndjson = \"\";\r\n for (let i = 0; i < 1000; i++) {\r\n ndjson += `{\"id\":${i}}\\n`;\r\n }\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1000);\r\n });\r\n\r\n it(\"should handle few large records\", async () => {\r\n const largeValue = \"A\".repeat(50000);\r\n const ndjson = `{\"data\":\"${largeValue}\"}\\n{\"data\":\"${largeValue}\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n\r\n it(\"should handle highly compressible data\", async () => {\r\n let ndjson = \"\";\r\n for (let i = 0; i < 100; i++) {\r\n ndjson += `{\"name\":\"Alice\",\"value\":100}\\n`;\r\n }\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 100);\r\n });\r\n\r\n it(\"should handle random data (low compressibility)\", async () => {\r\n let ndjson = \"\";\r\n for (let i = 0; i < 100; i++) {\r\n ndjson += `{\"id\":\"${Math.random().toString(36)}\",\"value\":${Math.random()}}\\n`;\r\n }\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 100);\r\n });\r\n });\r\n\r\n // ========== MALFORMED INPUT (ERROR HANDLING) ==========\r\n describe(\"Malformed Input Handling\", () => {\r\n it(\"should handle invalid JSON syntax gracefully\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n{invalid json}\\n{\"name\":\"Bob\"}`;\r\n try {\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n // If it succeeds, it handled it gracefully (maybe skipped invalid line)\r\n assert.ok(true);\r\n } catch (error) {\r\n // If it fails, it detected the error\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle incomplete JSON objects\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"\\n{\"name\":\"Bob\"}`;\r\n try {\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle truncated JSON\", async () => {\r\n const ndjson = `{\"name\":\"Alice\",\"age\":30,\"city\":\"N`;\r\n try {\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle mixed valid and invalid lines\", async () => {\r\n const ndjson = `{\"valid\":1}\\ninvalid\\n{\"valid\":2}\\n{broken\\n{\"valid\":3}`;\r\n try {\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n });\r\n\r\n // ========== UNICODE AND ENCODING ==========\r\n describe(\"Unicode and Encoding\", () => {\r\n it(\"should handle Unicode characters\", async () => {\r\n const ndjson = `{\"emoji\":\"😀🎉🚀\"}\\n{\"text\":\"日本語\"}\\n{\"symbols\":\"αβγδ\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n assert.ok(parsed[0].emoji.includes(\"😀\"));\r\n });\r\n\r\n it(\"should handle surrogate pairs\", async () => {\r\n const ndjson = `{\"emoji\":\"𝕳𝖊𝖑𝖑𝖔\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle zero-width characters\", async () => {\r\n const ndjson = `{\"text\":\"Hello\\u200BWorld\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n });\r\n\r\n // ========== REAL WORLD DATA ==========\r\n describe(\"Real World Data - DND Characters\", () => {\r\n it(\"should convert DND characters NDJSON to JSON correctly\", async () => {\r\n const ndjsonData = `{\"name\":\"Gorwin \\\\\"Grog\\\\\" Oakenshield\",\"race\":\"Human\",\"class\":\"Barbarian\",\"quirk\":\"Collects spoons from every tavern\"}\r\n{\"name\":\"Zilaen Whisperleaf\",\"race\":\"Elf\",\"class\":\"Rogue\",\"quirk\":\"Talks to shadows, claims they're shy\"}\r\n{\"name\":\"Pip Thistlewhisk\",\"race\":\"Halfling\",\"class\":\"Bard\",\"quirk\":\"Plays the lute with carrots\"}\r\n{\"name\":\"Thraxxus Bonegrinder\",\"race\":\"Orc\",\"class\":\"Cleric\",\"quirk\":\"Prays to a rock named Doris\"}\r\n{\"name\":\"Elaria Moonbeam\",\"race\":\"Half-Elf\",\"class\":\"Wizard\",\"quirk\":\"Writes shopping lists in ancient runes\"}`;\r\n\r\n const result = await convertToString(ndjsonData, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n\r\n // Verify it's valid JSON\r\n const parsed = JSON.parse(result);\r\n \r\n // Verify count\r\n assert.strictEqual(parsed.length, 5, \"Should have 5 characters\");\r\n \r\n // Verify first record\r\n assert.strictEqual(parsed[0].name, 'Gorwin \"Grog\" Oakenshield');\r\n assert.strictEqual(parsed[0].race, 'Human');\r\n assert.strictEqual(parsed[0].class, 'Barbarian');\r\n \r\n // Verify last record\r\n assert.strictEqual(parsed[4].name, 'Elaria Moonbeam');\r\n assert.strictEqual(parsed[4].race, 'Half-Elf');\r\n assert.strictEqual(parsed[4].class, 'Wizard');\r\n assert.strictEqual(parsed[4].quirk, 'Writes shopping lists in ancient runes');\r\n });\r\n\r\n it(\"should auto-detect DND characters NDJSON format\", async () => {\r\n const ndjsonData = `{\"name\":\"Gorwin \\\\\"Grog\\\\\" Oakenshield\",\"race\":\"Human\",\"class\":\"Barbarian\",\"quirk\":\"Collects spoons from every tavern\"}\r\n{\"name\":\"Zilaen Whisperleaf\",\"race\":\"Elf\",\"class\":\"Rogue\",\"quirk\":\"Talks to shadows, claims they're shy\"}\r\n{\"name\":\"Pip Thistlewhisk\",\"race\":\"Halfling\",\"class\":\"Bard\",\"quirk\":\"Plays the lute with carrots\"}`;\r\n\r\n // Don't specify inputFormat - let it auto-detect\r\n const result = await convertToString(ndjsonData, {\r\n outputFormat: \"json\",\r\n });\r\n\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3, \"Should auto-detect and parse 3 characters\");\r\n assert.strictEqual(parsed[0].name, 'Gorwin \"Grog\" Oakenshield');\r\n });\r\n });\r\n});\r\n\r\nconsole.log(\"✓ NDJSON Edge Case Test Suite loaded\");\r\nconsole.log(\" Run with: node --test tests/edge-cases/ndjson-edge-cases.test.ts\");\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../tests/edge-cases/ndjson-edge-cases.test.ts"],"sourcesContent":["import { describe, it } from \"node:test\";\r\nimport { convertToString, convert } from \"../../index.js\";\r\nimport { strict as assert } from \"node:assert\";\r\n\r\n/**\r\n * Comprehensive NDJSON Edge Case Test Suite\r\n * \r\n * Tests all possible edge cases for NDJSON parsing to ensure maximum safety.\r\n */\r\n\r\ndescribe(\"NDJSON Edge Cases - Comprehensive Safety Tests\", () => {\r\n \r\n // ========== LINE HANDLING ==========\r\n describe(\"Line Handling\", () => {\r\n it(\"should handle empty file (pretty and compact)\", async () => {\r\n // Default (pretty=true) should produce a valid empty array when parsed\r\n const prettyResult = await convertToString(\"\", {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsedPretty = JSON.parse(prettyResult);\r\n assert.strictEqual(parsedPretty.length, 0);\r\n\r\n // Explicit compact output\r\n const compactResult = await convertToString(\"\", {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n pretty: false,\r\n });\r\n assert.strictEqual(compactResult.trim(), \"[]\");\r\n });\r\n\r\n it(\"should handle file with only empty lines (pretty and compact)\", async () => {\r\n const ndjson = \"\\n\\n\\n\\n\";\r\n const prettyResult = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsedPretty = JSON.parse(prettyResult);\r\n assert.strictEqual(parsedPretty.length, 0);\r\n\r\n const compactResult = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n pretty: false,\r\n });\r\n assert.strictEqual(compactResult.trim(), \"[]\");\r\n });\r\n\r\n it(\"should handle lines with only whitespace (pretty and compact)\", async () => {\r\n const ndjson = \" \\n \\n \\n\";\r\n const prettyResult = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsedPretty = JSON.parse(prettyResult);\r\n assert.strictEqual(parsedPretty.length, 0);\r\n\r\n const compactResult = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n pretty: false,\r\n });\r\n assert.strictEqual(compactResult.trim(), \"[]\");\r\n });\r\n\r\n it(\"should handle empty lines between records\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n\\n{\"name\":\"Bob\"}\\n\\n{\"name\":\"Charlie\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle very long lines (>10MB)\", async () => {\r\n const largeObj = { data: \"A\".repeat(1000000) };\r\n const ndjson = JSON.stringify(largeObj);\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle missing trailing newline\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n{\"name\":\"Bob\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n\r\n it(\"should handle multiple consecutive newlines\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n\\n\\n{\"name\":\"Bob\"}\\n\\n\\n`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n\r\n it(\"should handle single line NDJSON\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle CRLF line endings\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\r\\n{\"name\":\"Bob\"}\\r\\n`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n\r\n it(\"should handle mixed line endings (LF and CRLF)\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n{\"name\":\"Bob\"}\\r\\n{\"name\":\"Charlie\"}\\n`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n });\r\n\r\n // ========== JSON VALIDITY ==========\r\n describe(\"JSON Validity\", () => {\r\n it(\"should handle valid JSON objects\", async () => {\r\n const ndjson = `{\"name\":\"Alice\",\"age\":30}\\n{\"name\":\"Bob\",\"age\":25}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n\r\n it(\"should handle JSON arrays as records\", async () => {\r\n const ndjson = `[1,2,3]\\n[4,5,6]\\n[7,8,9]`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle JSON primitives (strings)\", async () => {\r\n const ndjson = `\"Alice\"\\n\"Bob\"\\n\"Charlie\"`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle JSON primitives (numbers)\", async () => {\r\n const ndjson = `42\\n3.14\\n-100`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle JSON primitives (booleans)\", async () => {\r\n const ndjson = `true\\nfalse\\ntrue`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle JSON null values\", async () => {\r\n const ndjson = `null\\nnull\\nnull`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle deeply nested objects (>10 levels)\", async () => {\r\n let obj: any = { value: \"deep\" };\r\n for (let i = 0; i < 15; i++) {\r\n obj = { nested: obj };\r\n }\r\n const ndjson = JSON.stringify(obj);\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle large arrays (>1000 elements)\", async () => {\r\n const largeArray = Array.from({ length: 2000 }, (_, i) => i);\r\n const ndjson = JSON.stringify(largeArray);\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle Unicode escape sequences\", async () => {\r\n const ndjson = `{\"emoji\":\"😀\"}\\n{\"text\":\"Hello\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n\r\n it(\"should handle special characters in strings\", async () => {\r\n const ndjson = `{\"text\":\"Line 1\\\\nLine 2\"}\\n{\"text\":\"Tab\\\\there\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n });\r\n\r\n // ========== DATA TYPES ==========\r\n describe(\"Data Types\", () => {\r\n it(\"should handle all JSON types in single record\", async () => {\r\n const ndjson = `{\"string\":\"text\",\"number\":42,\"boolean\":true,\"null\":null,\"array\":[1,2,3],\"object\":{\"nested\":\"value\"}}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n assert.strictEqual(parsed[0].string, \"text\");\r\n assert.strictEqual(parsed[0].number, 42);\r\n assert.strictEqual(parsed[0].boolean, true);\r\n assert.strictEqual(parsed[0].null, null);\r\n });\r\n\r\n it(\"should handle mixed types across records\", async () => {\r\n const ndjson = `{\"type\":\"object\"}\\n[1,2,3]\\n\"string\"\\n42\\ntrue\\nnull`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 6);\r\n });\r\n\r\n it(\"should handle empty objects\", async () => {\r\n const ndjson = `{}\\n{}\\n{}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle empty arrays\", async () => {\r\n const ndjson = `[]\\n[]\\n[]`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle very large strings (>1MB)\", async () => {\r\n const largeString = \"A\".repeat(2000000);\r\n const ndjson = JSON.stringify({ data: largeString });\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle numbers at precision limits\", async () => {\r\n const ndjson = `{\"max\":${Number.MAX_SAFE_INTEGER}}\\n{\"min\":${Number.MIN_SAFE_INTEGER}}\\n{\"float\":${Number.MAX_VALUE}}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle objects with many keys (>1000)\", async () => {\r\n const obj: any = {};\r\n for (let i = 0; i < 1500; i++) {\r\n obj[`key${i}`] = i;\r\n }\r\n const ndjson = JSON.stringify(obj);\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n assert.strictEqual(Object.keys(parsed[0]).length, 1500);\r\n });\r\n\r\n it(\"should handle objects with duplicate keys (last wins)\", async () => {\r\n const ndjson = `{\"key\":\"value1\",\"key\":\"value2\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle objects with special key names\", async () => {\r\n const ndjson = `{\"\":\"empty\",\"123\":\"numeric\",\"@#$\":\"special\",\"__proto__\":\"proto\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n });\r\n\r\n // ========== NDJSON PASSTHROUGH ==========\r\n describe(\"NDJSON Passthrough\", () => {\r\n it(\"should handle NDJSON → NDJSON passthrough\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n{\"name\":\"Bob\"}\\n{\"name\":\"Charlie\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"ndjson\",\r\n });\r\n const lines = result.trim().split(\"\\n\");\r\n assert.strictEqual(lines.length, 3);\r\n });\r\n\r\n it(\"should preserve record order in passthrough\", async () => {\r\n const ndjson = `{\"id\":1}\\n{\"id\":2}\\n{\"id\":3}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"ndjson\",\r\n });\r\n const lines = result.trim().split(\"\\n\");\r\n const first = JSON.parse(lines[0]);\r\n assert.strictEqual(first.id, 1);\r\n });\r\n\r\n it(\"should handle large passthrough (10K records)\", async () => {\r\n let ndjson = \"\";\r\n for (let i = 0; i < 10000; i++) {\r\n ndjson += `{\"id\":${i}}\\n`;\r\n }\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"ndjson\",\r\n });\r\n const lines = result.trim().split(\"\\n\");\r\n assert.strictEqual(lines.length, 10000);\r\n });\r\n });\r\n\r\n // ========== STREAMING AND BOUNDARIES ==========\r\n describe(\"Streaming and Chunk Boundaries\", () => {\r\n it(\"should handle records split across chunks\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n{\"name\":\"Bob\"}\\n{\"name\":\"Charlie\"}`;\r\n const data = new TextEncoder().encode(ndjson);\r\n \r\n const result = await convert(data, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n \r\n const resultStr = new TextDecoder().decode(result);\r\n const parsed = JSON.parse(resultStr);\r\n assert.strictEqual(parsed.length, 3);\r\n });\r\n\r\n it(\"should handle partial JSON objects across chunks\", async () => {\r\n const ndjson = `{\"name\":\"Alice\",\"age\":30}\\n{\"name\":\"Bob\",\"age\":25}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n });\r\n\r\n // ========== PERFORMANCE EDGE CASES ==========\r\n describe(\"Performance Edge Cases\", () => {\r\n it(\"should handle tiny files (<100 bytes)\", async () => {\r\n const ndjson = `{\"a\":1}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n assert.ok(result.length > 0);\r\n });\r\n\r\n it(\"should handle many small records\", async () => {\r\n let ndjson = \"\";\r\n for (let i = 0; i < 1000; i++) {\r\n ndjson += `{\"id\":${i}}\\n`;\r\n }\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1000);\r\n });\r\n\r\n it(\"should handle few large records\", async () => {\r\n const largeValue = \"A\".repeat(50000);\r\n const ndjson = `{\"data\":\"${largeValue}\"}\\n{\"data\":\"${largeValue}\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 2);\r\n });\r\n\r\n it(\"should handle highly compressible data\", async () => {\r\n let ndjson = \"\";\r\n for (let i = 0; i < 100; i++) {\r\n ndjson += `{\"name\":\"Alice\",\"value\":100}\\n`;\r\n }\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 100);\r\n });\r\n\r\n it(\"should handle random data (low compressibility)\", async () => {\r\n let ndjson = \"\";\r\n for (let i = 0; i < 100; i++) {\r\n ndjson += `{\"id\":\"${Math.random().toString(36)}\",\"value\":${Math.random()}}\\n`;\r\n }\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 100);\r\n });\r\n });\r\n\r\n // ========== MALFORMED INPUT (ERROR HANDLING) ==========\r\n describe(\"Malformed Input Handling\", () => {\r\n it(\"should handle invalid JSON syntax gracefully\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"}\\n{invalid json}\\n{\"name\":\"Bob\"}`;\r\n try {\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n // If it succeeds, it handled it gracefully (maybe skipped invalid line)\r\n assert.ok(true);\r\n } catch (error) {\r\n // If it fails, it detected the error\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle incomplete JSON objects\", async () => {\r\n const ndjson = `{\"name\":\"Alice\"\\n{\"name\":\"Bob\"}`;\r\n try {\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle truncated JSON\", async () => {\r\n const ndjson = `{\"name\":\"Alice\",\"age\":30,\"city\":\"N`;\r\n try {\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle mixed valid and invalid lines\", async () => {\r\n const ndjson = `{\"valid\":1}\\ninvalid\\n{\"valid\":2}\\n{broken\\n{\"valid\":3}`;\r\n try {\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n });\r\n\r\n // ========== UNICODE AND ENCODING ==========\r\n describe(\"Unicode and Encoding\", () => {\r\n it(\"should handle Unicode characters\", async () => {\r\n const ndjson = `{\"emoji\":\"😀🎉🚀\"}\\n{\"text\":\"日本語\"}\\n{\"symbols\":\"αβγδ\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3);\r\n assert.ok(parsed[0].emoji.includes(\"😀\"));\r\n });\r\n\r\n it(\"should handle surrogate pairs\", async () => {\r\n const ndjson = `{\"emoji\":\"𝕳𝖊𝖑𝖑𝖔\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n\r\n it(\"should handle zero-width characters\", async () => {\r\n const ndjson = `{\"text\":\"Hello\\u200BWorld\"}`;\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 1);\r\n });\r\n });\r\n\r\n // ========== REAL WORLD DATA ==========\r\n describe(\"Real World Data - DND Characters\", () => {\r\n it(\"should convert DND characters NDJSON to JSON correctly\", async () => {\r\n const ndjsonData = `{\"name\":\"Gorwin \\\\\"Grog\\\\\" Oakenshield\",\"race\":\"Human\",\"class\":\"Barbarian\",\"quirk\":\"Collects spoons from every tavern\"}\r\n{\"name\":\"Zilaen Whisperleaf\",\"race\":\"Elf\",\"class\":\"Rogue\",\"quirk\":\"Talks to shadows, claims they're shy\"}\r\n{\"name\":\"Pip Thistlewhisk\",\"race\":\"Halfling\",\"class\":\"Bard\",\"quirk\":\"Plays the lute with carrots\"}\r\n{\"name\":\"Thraxxus Bonegrinder\",\"race\":\"Orc\",\"class\":\"Cleric\",\"quirk\":\"Prays to a rock named Doris\"}\r\n{\"name\":\"Elaria Moonbeam\",\"race\":\"Half-Elf\",\"class\":\"Wizard\",\"quirk\":\"Writes shopping lists in ancient runes\"}`;\r\n\r\n const result = await convertToString(ndjsonData, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n\r\n // Verify it's valid JSON\r\n const parsed = JSON.parse(result);\r\n \r\n // Verify count\r\n assert.strictEqual(parsed.length, 5, \"Should have 5 characters\");\r\n \r\n // Verify first record\r\n assert.strictEqual(parsed[0].name, 'Gorwin \"Grog\" Oakenshield');\r\n assert.strictEqual(parsed[0].race, 'Human');\r\n assert.strictEqual(parsed[0].class, 'Barbarian');\r\n \r\n // Verify last record\r\n assert.strictEqual(parsed[4].name, 'Elaria Moonbeam');\r\n assert.strictEqual(parsed[4].race, 'Half-Elf');\r\n assert.strictEqual(parsed[4].class, 'Wizard');\r\n assert.strictEqual(parsed[4].quirk, 'Writes shopping lists in ancient runes');\r\n });\r\n\r\n it(\"should auto-detect DND characters NDJSON format\", async () => {\r\n const ndjsonData = `{\"name\":\"Gorwin \\\\\"Grog\\\\\" Oakenshield\",\"race\":\"Human\",\"class\":\"Barbarian\",\"quirk\":\"Collects spoons from every tavern\"}\r\n{\"name\":\"Zilaen Whisperleaf\",\"race\":\"Elf\",\"class\":\"Rogue\",\"quirk\":\"Talks to shadows, claims they're shy\"}\r\n{\"name\":\"Pip Thistlewhisk\",\"race\":\"Halfling\",\"class\":\"Bard\",\"quirk\":\"Plays the lute with carrots\"}`;\r\n\r\n // Don't specify inputFormat - let it auto-detect\r\n const result = await convertToString(ndjsonData, {\r\n outputFormat: \"json\",\r\n });\r\n\r\n const parsed = JSON.parse(result);\r\n assert.strictEqual(parsed.length, 3, \"Should auto-detect and parse 3 characters\");\r\n assert.strictEqual(parsed[0].name, 'Gorwin \"Grog\" Oakenshield');\r\n });\r\n });\r\n});\r\n\r\nconsole.log(\"✓ NDJSON Edge Case Test Suite loaded\");\r\nconsole.log(\" Run with: node --test tests/edge-cases/ndjson-edge-cases.test.ts\");\r\n"],"mappings":"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","names":[]}
@@ -43,7 +43,7 @@ export class Converter {
43
43
  /**
44
44
  * Create a new converter with specific configuration
45
45
  */
46
- static withConfig(debug: boolean, input_format: string, output_format: string, chunk_target_bytes: number, enable_stats: boolean, csv_config: any, xml_config: any, transform_config: any): Converter;
46
+ static withConfig(debug: boolean, input_format: string, output_format: string, chunk_target_bytes: number, enable_stats: boolean, csv_config: any, xml_config: any, transform_config: any, pretty_json: boolean): Converter;
47
47
  /**
48
48
  * Push a chunk of bytes and optionally get pre-parsed records.
49
49
  * When include_records is true, returns { output: Uint8Array, records: Array }
@@ -339,14 +339,15 @@ class Converter {
339
339
  * @param {any} csv_config
340
340
  * @param {any} xml_config
341
341
  * @param {any} transform_config
342
+ * @param {boolean} pretty_json
342
343
  * @returns {Converter}
343
344
  */
344
- static withConfig(debug, input_format, output_format, chunk_target_bytes, enable_stats, csv_config, xml_config, transform_config) {
345
+ static withConfig(debug, input_format, output_format, chunk_target_bytes, enable_stats, csv_config, xml_config, transform_config, pretty_json) {
345
346
  const ptr0 = passStringToWasm0(input_format, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
346
347
  const len0 = WASM_VECTOR_LEN;
347
348
  const ptr1 = passStringToWasm0(output_format, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
348
349
  const len1 = WASM_VECTOR_LEN;
349
- const ret = wasm.converter_withConfig(debug, ptr0, len0, ptr1, len1, chunk_target_bytes, enable_stats, csv_config, xml_config, transform_config);
350
+ const ret = wasm.converter_withConfig(debug, ptr0, len0, ptr1, len1, chunk_target_bytes, enable_stats, csv_config, xml_config, transform_config, pretty_json);
350
351
  if (ret[2]) {
351
352
  throw takeFromExternrefTable0(ret[1]);
352
353
  }
@@ -8,7 +8,7 @@ export const converter_getStats: (a: number) => number;
8
8
  export const converter_new: (a: number) => number;
9
9
  export const converter_push: (a: number, b: number, c: number) => [number, number, number, number];
10
10
  export const converter_pushWithRecords: (a: number, b: number, c: number, d: number) => [number, number, number];
11
- export const converter_withConfig: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: any, i: any, j: any) => [number, number, number];
11
+ export const converter_withConfig: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: any, i: any, j: any, k: number) => [number, number, number];
12
12
  export const detectCsvFields: (a: number, b: number) => any;
13
13
  export const detectFormat: (a: number, b: number) => [number, number];
14
14
  export const detectJsonFields: (a: number, b: number) => any;
@@ -43,7 +43,7 @@ export class Converter {
43
43
  /**
44
44
  * Create a new converter with specific configuration
45
45
  */
46
- static withConfig(debug: boolean, input_format: string, output_format: string, chunk_target_bytes: number, enable_stats: boolean, csv_config: any, xml_config: any, transform_config: any): Converter;
46
+ static withConfig(debug: boolean, input_format: string, output_format: string, chunk_target_bytes: number, enable_stats: boolean, csv_config: any, xml_config: any, transform_config: any, pretty_json: boolean): Converter;
47
47
  /**
48
48
  * Push a chunk of bytes and optionally get pre-parsed records.
49
49
  * When include_records is true, returns { output: Uint8Array, records: Array }
@@ -93,7 +93,7 @@ export interface InitOutput {
93
93
  readonly converter_new: (a: number) => number;
94
94
  readonly converter_push: (a: number, b: number, c: number) => [number, number, number, number];
95
95
  readonly converter_pushWithRecords: (a: number, b: number, c: number, d: number) => [number, number, number];
96
- readonly converter_withConfig: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: any, i: any, j: any) => [number, number, number];
96
+ readonly converter_withConfig: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: any, i: any, j: any, k: number) => [number, number, number];
97
97
  readonly detectCsvFields: (a: number, b: number) => any;
98
98
  readonly detectFormat: (a: number, b: number) => [number, number];
99
99
  readonly detectJsonFields: (a: number, b: number) => any;
@@ -335,14 +335,15 @@ export class Converter {
335
335
  * @param {any} csv_config
336
336
  * @param {any} xml_config
337
337
  * @param {any} transform_config
338
+ * @param {boolean} pretty_json
338
339
  * @returns {Converter}
339
340
  */
340
- static withConfig(debug, input_format, output_format, chunk_target_bytes, enable_stats, csv_config, xml_config, transform_config) {
341
+ static withConfig(debug, input_format, output_format, chunk_target_bytes, enable_stats, csv_config, xml_config, transform_config, pretty_json) {
341
342
  const ptr0 = passStringToWasm0(input_format, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
342
343
  const len0 = WASM_VECTOR_LEN;
343
344
  const ptr1 = passStringToWasm0(output_format, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
344
345
  const len1 = WASM_VECTOR_LEN;
345
- const ret = wasm.converter_withConfig(debug, ptr0, len0, ptr1, len1, chunk_target_bytes, enable_stats, csv_config, xml_config, transform_config);
346
+ const ret = wasm.converter_withConfig(debug, ptr0, len0, ptr1, len1, chunk_target_bytes, enable_stats, csv_config, xml_config, transform_config, pretty_json);
346
347
  if (ret[2]) {
347
348
  throw takeFromExternrefTable0(ret[1]);
348
349
  }
Binary file
@@ -8,7 +8,7 @@ export const converter_getStats: (a: number) => number;
8
8
  export const converter_new: (a: number) => number;
9
9
  export const converter_push: (a: number, b: number, c: number) => [number, number, number, number];
10
10
  export const converter_pushWithRecords: (a: number, b: number, c: number, d: number) => [number, number, number];
11
- export const converter_withConfig: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: any, i: any, j: any) => [number, number, number];
11
+ export const converter_withConfig: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: any, i: any, j: any, k: number) => [number, number, number];
12
12
  export const detectCsvFields: (a: number, b: number) => any;
13
13
  export const detectFormat: (a: number, b: number) => [number, number];
14
14
  export const detectJsonFields: (a: number, b: number) => any;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "convert-buddy-js",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "TypeScript wrapper for convert-buddy (Rust/WASM core)",
5
5
  "license": "MIT",
6
6
  "type": "module",