convert-buddy-js 0.9.2 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +142 -5
- package/dist/src/browser.d.ts +74 -0
- package/dist/src/browser.js +140 -0
- package/dist/src/browser.js.map +1 -0
- package/dist/src/index.d.ts +23 -2
- package/dist/src/index.js +82 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/node.d.ts +83 -2
- package/dist/src/node.js +270 -2
- package/dist/src/node.js.map +1 -1
- package/dist/tests/edge-cases/control-features.test.d.ts +2 -0
- package/dist/tests/edge-cases/control-features.test.js +87 -0
- package/dist/tests/edge-cases/control-features.test.js.map +1 -0
- package/dist/tests/edge-cases/csv-edge-cases.test.d.ts +2 -0
- package/dist/tests/edge-cases/csv-edge-cases.test.js +547 -0
- package/dist/tests/edge-cases/csv-edge-cases.test.js.map +1 -0
- package/dist/tests/edge-cases/detection.test.d.ts +2 -0
- package/dist/tests/edge-cases/detection.test.js +129 -0
- package/dist/tests/edge-cases/detection.test.js.map +1 -0
- package/dist/tests/edge-cases/error-handling.test.d.ts +2 -0
- package/dist/tests/edge-cases/error-handling.test.js +448 -0
- package/dist/tests/edge-cases/error-handling.test.js.map +1 -0
- package/dist/tests/edge-cases/ndjson-edge-cases.test.d.ts +2 -0
- package/dist/tests/edge-cases/ndjson-edge-cases.test.js +539 -0
- package/dist/tests/edge-cases/ndjson-edge-cases.test.js.map +1 -0
- package/dist/tests/edge-cases/node-helpers.test.d.ts +2 -0
- package/dist/tests/edge-cases/node-helpers.test.js +114 -0
- package/dist/tests/edge-cases/node-helpers.test.js.map +1 -0
- package/dist/wasm/nodejs/convert_buddy_bg.wasm +0 -0
- package/dist/wasm/web/convert_buddy_bg.wasm +0 -0
- package/package.json +6 -2
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export type Format = \"csv\" | \"ndjson\" | \"json\" | \"xml\";\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};\r\n\r\nexport type DetectOptions = {\r\n maxBytes?: number;\r\n debug?: boolean;\r\n};\r\n\r\nexport type ConvertBuddyOptions = {\r\n debug?: boolean;\r\n profile?: boolean;\r\n inputFormat?: Format;\r\n outputFormat?: Format;\r\n chunkTargetBytes?: number;\r\n parallelism?: number; // Node only - number of worker threads\r\n csvConfig?: CsvConfig;\r\n xmlConfig?: XmlConfig;\r\n};\r\n\r\nexport type CsvConfig = {\r\n delimiter?: string;\r\n quote?: string;\r\n hasHeaders?: boolean;\r\n trimWhitespace?: boolean;\r\n};\r\n\r\nexport type XmlConfig = {\r\n recordElement?: string;\r\n trimText?: boolean;\r\n includeAttributes?: boolean;\r\n expandEntities?: boolean;\r\n};\r\n\r\nexport type Stats = {\r\n bytesIn: number;\r\n bytesOut: number;\r\n chunksIn: number;\r\n recordsProcessed: number;\r\n parseTimeMs: number;\r\n transformTimeMs: number;\r\n writeTimeMs: number;\r\n maxBufferSize: number;\r\n currentPartialSize: number;\r\n throughputMbPerSec: number;\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 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 __wbg_set_wasm?: (wasm: unknown) => void;\r\n};\r\n\r\nasync function loadWasmModule(): Promise<WasmModule> {\r\n const isNode =\r\n typeof process !== \"undefined\" &&\r\n !!(process as any).versions?.node;\r\n\r\n if (isNode) {\r\n const { createRequire } = await import(\"node:module\");\r\n const require = createRequire(import.meta.url);\r\n const mod = require(\"../../wasm-node.cjs\");\r\n return mod as WasmModule;\r\n }\r\n\r\n const wasmUrl = new URL(\"../wasm/web/convert_buddy.js\", import.meta.url);\r\n const mod = (await import(wasmUrl.href)) as unknown as WasmModule;\r\n return mod;\r\n}\r\n\r\nexport class ConvertBuddy {\r\n private converter: any;\r\n private debug: boolean;\r\n private profile: boolean;\r\n\r\n private constructor(converter: any, debug: boolean, profile: boolean) {\r\n this.converter = converter;\r\n this.debug = debug;\r\n this.profile = profile;\r\n }\r\n\r\n static async create(opts: ConvertBuddyOptions = {}): Promise<ConvertBuddy> {\r\n const debug = !!opts.debug;\r\n const profile = !!opts.profile;\r\n\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 let converter;\r\n if (opts.inputFormat && opts.outputFormat) {\r\n // Use withConfig for custom formats\r\n const Converter = (wasmModule as any).Converter;\r\n converter = Converter.withConfig(\r\n debug,\r\n opts.inputFormat,\r\n opts.outputFormat,\r\n opts.chunkTargetBytes || 1024 * 1024,\r\n profile,\r\n opts.csvConfig,\r\n opts.xmlConfig\r\n );\r\n } else {\r\n converter = new wasmModule.Converter(debug);\r\n }\r\n\r\n if (debug) console.log(\"[convert-buddy-js] initialized\", opts);\r\n return new ConvertBuddy(converter, debug, profile);\r\n }\r\n\r\n push(chunk: Uint8Array): Uint8Array {\r\n if (this.debug) console.log(\"[convert-buddy-js] push\", chunk.byteLength);\r\n return this.converter.push(chunk);\r\n }\r\n\r\n finish(): Uint8Array {\r\n if (this.debug) console.log(\"[convert-buddy-js] finish\");\r\n return this.converter.finish();\r\n }\r\n\r\n stats(): Stats {\r\n return this.converter.getStats();\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);\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 detectCsvFieldsAndDelimiter(\r\n input: DetectInput,\r\n opts: DetectOptions = {}\r\n): Promise<CsvDetection | null> {\r\n const wasmModule = await loadDetectionWasm(!!opts.debug);\r\n const sample = await readSample(input, opts.maxBytes);\r\n const result = wasmModule.detectCsvFields?.(sample);\r\n return result ?? 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 wasmModule = await loadDetectionWasm(!!opts.debug);\r\n const sample = await readSample(input, opts.maxBytes);\r\n const result = wasmModule.detectXmlElements?.(sample);\r\n return result ?? null;\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 const buddy = await ConvertBuddy.create(opts);\r\n\r\n const inputBytes = typeof input === \"string\" \r\n ? new TextEncoder().encode(input)\r\n : input;\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}\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 new TextDecoder().decode(result);\r\n}\r\n"],"mappings":"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","names":["require","mod","chunks","total"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export type Format = \"csv\" | \"ndjson\" | \"json\" | \"xml\";\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 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 csvConfig?: CsvConfig;\r\n xmlConfig?: XmlConfig;\r\n onProgress?: ProgressCallback;\r\n progressIntervalBytes?: number; // Trigger progress callback every N bytes (default: 1MB)\r\n};\r\n\r\nexport type CsvConfig = {\r\n delimiter?: string;\r\n quote?: string;\r\n hasHeaders?: boolean;\r\n trimWhitespace?: boolean;\r\n};\r\n\r\nexport type XmlConfig = {\r\n recordElement?: string;\r\n trimText?: boolean;\r\n includeAttributes?: boolean;\r\n expandEntities?: boolean;\r\n};\r\n\r\nexport type Stats = {\r\n bytesIn: number;\r\n bytesOut: number;\r\n chunksIn: number;\r\n recordsProcessed: number;\r\n parseTimeMs: number;\r\n transformTimeMs: number;\r\n writeTimeMs: number;\r\n maxBufferSize: number;\r\n currentPartialSize: number;\r\n throughputMbPerSec: number;\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 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 __wbg_set_wasm?: (wasm: unknown) => void;\r\n};\r\n\r\nasync function loadWasmModule(): Promise<WasmModule> {\r\n const isNode =\r\n typeof process !== \"undefined\" &&\r\n !!(process as any).versions?.node;\r\n\r\n if (isNode) {\r\n const { createRequire } = await import(\"node:module\");\r\n const require = createRequire(import.meta.url);\r\n const mod = require(\"../../wasm-node.cjs\");\r\n return mod as WasmModule;\r\n }\r\n\r\n const wasmUrl = new URL(\"../wasm/web/convert_buddy.js\", import.meta.url);\r\n const mod = (await import(wasmUrl.href)) as unknown as WasmModule;\r\n return mod;\r\n}\r\n\r\nexport class ConvertBuddy {\r\n private converter: any;\r\n private debug: boolean;\r\n private profile: 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\r\n private constructor(converter: any, debug: boolean, profile: boolean, opts: ConvertBuddyOptions = {}) {\r\n this.converter = converter;\r\n this.debug = debug;\r\n this.profile = profile;\r\n this.onProgress = opts.onProgress;\r\n this.progressIntervalBytes = opts.progressIntervalBytes || 1024 * 1024; // 1MB default\r\n }\r\n\r\n static async create(opts: ConvertBuddyOptions = {}): Promise<ConvertBuddy> {\r\n const debug = !!opts.debug;\r\n const profile = !!opts.profile;\r\n\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 // 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 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 converter = Converter.withConfig(\r\n debug,\r\n inputFormat,\r\n opts.outputFormat,\r\n opts.chunkTargetBytes || 1024 * 1024,\r\n profile,\r\n csvConfig || null,\r\n opts.xmlConfig || null\r\n );\r\n } else {\r\n converter = new wasmModule.Converter(debug);\r\n }\r\n\r\n if (debug) console.log(\"[convert-buddy-js] initialized\", opts);\r\n return new ConvertBuddy(converter, debug, profile, opts);\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 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 return this.converter.getStats();\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);\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 detectCsvFieldsAndDelimiter(\r\n input: DetectInput,\r\n opts: DetectOptions = {}\r\n): Promise<CsvDetection | null> {\r\n const wasmModule = await loadDetectionWasm(!!opts.debug);\r\n const sample = await readSample(input, opts.maxBytes);\r\n const result = wasmModule.detectCsvFields?.(sample);\r\n return result ?? 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 wasmModule = await loadDetectionWasm(!!opts.debug);\r\n const sample = await readSample(input, opts.maxBytes);\r\n const result = wasmModule.detectXmlElements?.(sample);\r\n return result ?? null;\r\n}\r\n\r\n// Helper to auto-detect format and CSV configuration from sample data\r\nexport async function autoDetectConfig(\r\n sample: Uint8Array,\r\n opts: { debug?: boolean } = {}\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 \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 const buddy = await ConvertBuddy.create(opts);\r\n\r\n const inputBytes = typeof input === \"string\" \r\n ? new TextEncoder().encode(input)\r\n : input;\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}\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 new TextDecoder().decode(result);\r\n}\r\n"],"mappings":"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","names":["require","mod","chunks","total"]}
|
package/dist/src/node.d.ts
CHANGED
|
@@ -1,7 +1,88 @@
|
|
|
1
1
|
import { Transform } from 'node:stream';
|
|
2
|
+
import { PathLike } from 'node:fs';
|
|
2
3
|
import { ConvertBuddyOptions } from './index.js';
|
|
3
|
-
export { ConvertBuddy, ConvertBuddyTransformStream, CsvConfig, CsvDetection, DetectInput, DetectOptions, Format, Stats, XmlConfig, XmlDetection, convert, convertToString, detectCsvFieldsAndDelimiter, detectFormat, detectXmlElements } from './index.js';
|
|
4
|
+
export { ConvertBuddy, ConvertBuddyTransformStream, CsvConfig, CsvDetection, DetectInput, DetectOptions, Format, ProgressCallback, Stats, XmlConfig, XmlDetection, autoDetectConfig, convert, convertToString, detectCsvFieldsAndDelimiter, detectFormat, detectXmlElements } from './index.js';
|
|
4
5
|
|
|
5
6
|
declare function createNodeTransform(opts?: ConvertBuddyOptions): Promise<Transform>;
|
|
7
|
+
/**
|
|
8
|
+
* Convert a file from one format to another and return as a string.
|
|
9
|
+
* Handles file reading and streaming internally.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // Basic conversion
|
|
13
|
+
* const result = await convertFileToString("input.csv", {
|
|
14
|
+
* inputFormat: "csv",
|
|
15
|
+
* outputFormat: "json"
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // With auto-detection
|
|
20
|
+
* const result = await convertFileToString("data.csv", {
|
|
21
|
+
* inputFormat: "auto",
|
|
22
|
+
* outputFormat: "ndjson",
|
|
23
|
+
* onProgress: (stats) => {
|
|
24
|
+
* console.log(`Processed ${stats.recordsProcessed} records`);
|
|
25
|
+
* }
|
|
26
|
+
* });
|
|
27
|
+
*/
|
|
28
|
+
declare function convertFileToString(inputPath: PathLike, opts?: ConvertBuddyOptions): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Convert a file from one format to another and return as a Buffer.
|
|
31
|
+
* Handles file reading and streaming internally.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* const buffer = await convertFileToBuffer("input.csv", {
|
|
35
|
+
* inputFormat: "csv",
|
|
36
|
+
* outputFormat: "json"
|
|
37
|
+
* });
|
|
38
|
+
* console.log(buffer.toString());
|
|
39
|
+
*/
|
|
40
|
+
declare function convertFileToBuffer(inputPath: PathLike, opts?: ConvertBuddyOptions): Promise<Buffer>;
|
|
41
|
+
/**
|
|
42
|
+
* Convert a file from one format to another and write to an output file.
|
|
43
|
+
* Handles file reading, conversion, and writing with streaming.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* await convertFileToFile("input.csv", "output.json", {
|
|
47
|
+
* inputFormat: "csv",
|
|
48
|
+
* outputFormat: "json"
|
|
49
|
+
* });
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* // With progress tracking
|
|
53
|
+
* await convertFileToFile("large-data.csv", "output.ndjson", {
|
|
54
|
+
* inputFormat: "auto",
|
|
55
|
+
* outputFormat: "ndjson",
|
|
56
|
+
* onProgress: (stats) => {
|
|
57
|
+
* const percent = (stats.bytesIn / totalSize * 100).toFixed(1);
|
|
58
|
+
* console.log(`Progress: ${percent}%`);
|
|
59
|
+
* }
|
|
60
|
+
* });
|
|
61
|
+
*/
|
|
62
|
+
declare function convertFileToFile(inputPath: PathLike, outputPath: PathLike, opts?: ConvertBuddyOptions): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Convert data from a Node.js Readable stream.
|
|
65
|
+
* Useful for processing data from HTTP requests, stdin, or other stream sources.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* import { createReadStream } from 'fs';
|
|
69
|
+
* const stream = createReadStream('input.csv');
|
|
70
|
+
* const result = await convertStream(stream, {
|
|
71
|
+
* inputFormat: "csv",
|
|
72
|
+
* outputFormat: "json"
|
|
73
|
+
* });
|
|
74
|
+
*/
|
|
75
|
+
declare function convertStream(inputStream: NodeJS.ReadableStream, opts?: ConvertBuddyOptions): Promise<Buffer>;
|
|
76
|
+
/**
|
|
77
|
+
* Convert a Buffer directly (useful when you already have data in memory).
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* const buffer = Buffer.from(csvData);
|
|
81
|
+
* const result = await convertBuffer(buffer, {
|
|
82
|
+
* inputFormat: "csv",
|
|
83
|
+
* outputFormat: "json"
|
|
84
|
+
* });
|
|
85
|
+
*/
|
|
86
|
+
declare function convertBuffer(input: Buffer, opts?: ConvertBuddyOptions): Promise<Buffer>;
|
|
6
87
|
|
|
7
|
-
export { ConvertBuddyOptions, createNodeTransform };
|
|
88
|
+
export { ConvertBuddyOptions, convertBuffer, convertFileToBuffer, convertFileToFile, convertFileToString, convertStream, createNodeTransform };
|
package/dist/src/node.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ConvertBuddy } from "./index";
|
|
2
|
-
export * from "./index";
|
|
1
|
+
import { ConvertBuddy, autoDetectConfig } from "./index.js";
|
|
2
|
+
export * from "./index.js";
|
|
3
3
|
async function loadNodeTransform() {
|
|
4
4
|
const isNode = typeof process !== "undefined" && !!process.versions?.node;
|
|
5
5
|
if (!isNode) {
|
|
@@ -53,7 +53,275 @@ async function createNodeTransform(opts = {}) {
|
|
|
53
53
|
});
|
|
54
54
|
return transform;
|
|
55
55
|
}
|
|
56
|
+
async function convertFileToString(inputPath, opts = {}) {
|
|
57
|
+
const bytes = await convertFileToBuffer(inputPath, opts);
|
|
58
|
+
return bytes.toString("utf-8");
|
|
59
|
+
}
|
|
60
|
+
async function convertFileToBuffer(inputPath, opts = {}) {
|
|
61
|
+
const fs = await import("node:fs");
|
|
62
|
+
const path = await import("node:path");
|
|
63
|
+
let actualOpts = { ...opts };
|
|
64
|
+
if (opts.inputFormat === "auto") {
|
|
65
|
+
const sampleSize = 256 * 1024;
|
|
66
|
+
const fileHandle = await fs.promises.open(inputPath, "r");
|
|
67
|
+
const buffer = Buffer.allocUnsafe(sampleSize);
|
|
68
|
+
const { bytesRead } = await fileHandle.read(buffer, 0, sampleSize, 0);
|
|
69
|
+
await fileHandle.close();
|
|
70
|
+
const sample = new Uint8Array(buffer.buffer, buffer.byteOffset, bytesRead);
|
|
71
|
+
const detected = await autoDetectConfig(sample, { debug: opts.debug });
|
|
72
|
+
if (detected.format !== "unknown") {
|
|
73
|
+
actualOpts.inputFormat = detected.format;
|
|
74
|
+
if (detected.csvConfig) {
|
|
75
|
+
actualOpts.csvConfig = opts.csvConfig ? { ...detected.csvConfig, ...opts.csvConfig } : detected.csvConfig;
|
|
76
|
+
}
|
|
77
|
+
if (detected.xmlConfig) {
|
|
78
|
+
actualOpts.xmlConfig = opts.xmlConfig ? { ...detected.xmlConfig, ...opts.xmlConfig } : detected.xmlConfig;
|
|
79
|
+
}
|
|
80
|
+
if (opts.debug) {
|
|
81
|
+
console.log("[convert-buddy] Auto-detected format:", detected.format);
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
throw new Error("Could not auto-detect input format. Please specify inputFormat explicitly.");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const buddy = await ConvertBuddy.create(actualOpts);
|
|
88
|
+
const readStream = fs.createReadStream(inputPath, { highWaterMark: 64 * 1024 });
|
|
89
|
+
const chunks = [];
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
readStream.on("data", (chunk) => {
|
|
92
|
+
try {
|
|
93
|
+
if (buddy.isAborted()) {
|
|
94
|
+
readStream.destroy();
|
|
95
|
+
reject(new Error("Conversion aborted"));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const output = buddy.push(new Uint8Array(chunk));
|
|
99
|
+
if (output.length > 0) {
|
|
100
|
+
chunks.push(Buffer.from(output));
|
|
101
|
+
}
|
|
102
|
+
} catch (error) {
|
|
103
|
+
readStream.destroy();
|
|
104
|
+
reject(error);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
readStream.on("end", () => {
|
|
108
|
+
try {
|
|
109
|
+
const final = buddy.finish();
|
|
110
|
+
if (final.length > 0) {
|
|
111
|
+
chunks.push(Buffer.from(final));
|
|
112
|
+
}
|
|
113
|
+
if (opts.profile) {
|
|
114
|
+
console.log("[convert-buddy] Performance Stats:", buddy.stats());
|
|
115
|
+
}
|
|
116
|
+
resolve(Buffer.concat(chunks));
|
|
117
|
+
} catch (error) {
|
|
118
|
+
reject(error);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
readStream.on("error", reject);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
async function convertFileToFile(inputPath, outputPath, opts = {}) {
|
|
125
|
+
const fs = await import("node:fs");
|
|
126
|
+
let actualOpts = { ...opts };
|
|
127
|
+
if (opts.inputFormat === "auto") {
|
|
128
|
+
const sampleSize = 256 * 1024;
|
|
129
|
+
const fileHandle = await fs.promises.open(inputPath, "r");
|
|
130
|
+
const buffer = Buffer.allocUnsafe(sampleSize);
|
|
131
|
+
const { bytesRead } = await fileHandle.read(buffer, 0, sampleSize, 0);
|
|
132
|
+
await fileHandle.close();
|
|
133
|
+
const sample = new Uint8Array(buffer.buffer, buffer.byteOffset, bytesRead);
|
|
134
|
+
const detected = await autoDetectConfig(sample, { debug: opts.debug });
|
|
135
|
+
if (detected.format !== "unknown") {
|
|
136
|
+
actualOpts.inputFormat = detected.format;
|
|
137
|
+
if (detected.csvConfig) {
|
|
138
|
+
actualOpts.csvConfig = opts.csvConfig ? { ...detected.csvConfig, ...opts.csvConfig } : detected.csvConfig;
|
|
139
|
+
}
|
|
140
|
+
if (detected.xmlConfig) {
|
|
141
|
+
actualOpts.xmlConfig = opts.xmlConfig ? { ...detected.xmlConfig, ...opts.xmlConfig } : detected.xmlConfig;
|
|
142
|
+
}
|
|
143
|
+
if (opts.debug) {
|
|
144
|
+
console.log("[convert-buddy] Auto-detected format:", detected.format);
|
|
145
|
+
}
|
|
146
|
+
} else {
|
|
147
|
+
throw new Error("Could not auto-detect input format. Please specify inputFormat explicitly.");
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const buddy = await ConvertBuddy.create(actualOpts);
|
|
151
|
+
const readStream = fs.createReadStream(inputPath, { highWaterMark: 64 * 1024 });
|
|
152
|
+
const writeStream = fs.createWriteStream(outputPath);
|
|
153
|
+
return new Promise((resolve, reject) => {
|
|
154
|
+
readStream.on("data", (chunk) => {
|
|
155
|
+
try {
|
|
156
|
+
if (buddy.isAborted()) {
|
|
157
|
+
readStream.destroy();
|
|
158
|
+
writeStream.destroy();
|
|
159
|
+
reject(new Error("Conversion aborted"));
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const output = buddy.push(new Uint8Array(chunk));
|
|
163
|
+
if (output.length > 0) {
|
|
164
|
+
writeStream.write(Buffer.from(output));
|
|
165
|
+
}
|
|
166
|
+
} catch (error) {
|
|
167
|
+
readStream.destroy();
|
|
168
|
+
writeStream.destroy();
|
|
169
|
+
reject(error);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
readStream.on("end", () => {
|
|
173
|
+
try {
|
|
174
|
+
const final = buddy.finish();
|
|
175
|
+
if (final.length > 0) {
|
|
176
|
+
writeStream.write(Buffer.from(final));
|
|
177
|
+
}
|
|
178
|
+
writeStream.end();
|
|
179
|
+
if (opts.profile) {
|
|
180
|
+
console.log("[convert-buddy] Performance Stats:", buddy.stats());
|
|
181
|
+
}
|
|
182
|
+
} catch (error) {
|
|
183
|
+
writeStream.destroy();
|
|
184
|
+
reject(error);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
writeStream.on("finish", () => resolve());
|
|
188
|
+
writeStream.on("error", reject);
|
|
189
|
+
readStream.on("error", reject);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
async function convertStream(inputStream, opts = {}) {
|
|
193
|
+
let actualOpts = { ...opts };
|
|
194
|
+
let firstChunk = null;
|
|
195
|
+
if (opts.inputFormat === "auto") {
|
|
196
|
+
const sampleSize = 256 * 1024;
|
|
197
|
+
const chunks2 = [];
|
|
198
|
+
let totalSize = 0;
|
|
199
|
+
await new Promise((resolve, reject) => {
|
|
200
|
+
const onData = (chunk) => {
|
|
201
|
+
chunks2.push(chunk);
|
|
202
|
+
totalSize += chunk.length;
|
|
203
|
+
if (totalSize >= sampleSize) {
|
|
204
|
+
inputStream.removeListener("data", onData);
|
|
205
|
+
if ("pause" in inputStream && typeof inputStream.pause === "function") {
|
|
206
|
+
inputStream.pause();
|
|
207
|
+
}
|
|
208
|
+
resolve();
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
const onEnd = () => {
|
|
212
|
+
inputStream.removeListener("data", onData);
|
|
213
|
+
resolve();
|
|
214
|
+
};
|
|
215
|
+
inputStream.on("data", onData);
|
|
216
|
+
inputStream.once("end", onEnd);
|
|
217
|
+
inputStream.once("error", reject);
|
|
218
|
+
});
|
|
219
|
+
const sample = Buffer.concat(chunks2).slice(0, sampleSize);
|
|
220
|
+
const detected = await autoDetectConfig(new Uint8Array(sample), { debug: opts.debug });
|
|
221
|
+
if (detected.format !== "unknown") {
|
|
222
|
+
actualOpts.inputFormat = detected.format;
|
|
223
|
+
if (detected.csvConfig) {
|
|
224
|
+
actualOpts.csvConfig = opts.csvConfig ? { ...detected.csvConfig, ...opts.csvConfig } : detected.csvConfig;
|
|
225
|
+
}
|
|
226
|
+
if (detected.xmlConfig) {
|
|
227
|
+
actualOpts.xmlConfig = opts.xmlConfig ? { ...detected.xmlConfig, ...opts.xmlConfig } : detected.xmlConfig;
|
|
228
|
+
}
|
|
229
|
+
if (opts.debug) {
|
|
230
|
+
console.log("[convert-buddy] Auto-detected format:", detected.format);
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
throw new Error("Could not auto-detect input format.");
|
|
234
|
+
}
|
|
235
|
+
firstChunk = Buffer.concat(chunks2);
|
|
236
|
+
}
|
|
237
|
+
const buddy = await ConvertBuddy.create(actualOpts);
|
|
238
|
+
const chunks = [];
|
|
239
|
+
return new Promise((resolve, reject) => {
|
|
240
|
+
if (firstChunk) {
|
|
241
|
+
try {
|
|
242
|
+
const output = buddy.push(new Uint8Array(firstChunk));
|
|
243
|
+
if (output.length > 0) {
|
|
244
|
+
chunks.push(Buffer.from(output));
|
|
245
|
+
}
|
|
246
|
+
} catch (error) {
|
|
247
|
+
return reject(error);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
inputStream.on("data", (chunk) => {
|
|
251
|
+
try {
|
|
252
|
+
if (buddy.isAborted()) {
|
|
253
|
+
if ("destroy" in inputStream && typeof inputStream.destroy === "function") {
|
|
254
|
+
inputStream.destroy();
|
|
255
|
+
}
|
|
256
|
+
reject(new Error("Conversion aborted"));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
const output = buddy.push(new Uint8Array(chunk));
|
|
260
|
+
if (output.length > 0) {
|
|
261
|
+
chunks.push(Buffer.from(output));
|
|
262
|
+
}
|
|
263
|
+
} catch (error) {
|
|
264
|
+
if ("destroy" in inputStream && typeof inputStream.destroy === "function") {
|
|
265
|
+
inputStream.destroy();
|
|
266
|
+
}
|
|
267
|
+
reject(error);
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
inputStream.on("end", () => {
|
|
271
|
+
try {
|
|
272
|
+
const final = buddy.finish();
|
|
273
|
+
if (final.length > 0) {
|
|
274
|
+
chunks.push(Buffer.from(final));
|
|
275
|
+
}
|
|
276
|
+
if (opts.profile) {
|
|
277
|
+
console.log("[convert-buddy] Performance Stats:", buddy.stats());
|
|
278
|
+
}
|
|
279
|
+
resolve(Buffer.concat(chunks));
|
|
280
|
+
} catch (error) {
|
|
281
|
+
reject(error);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
inputStream.on("error", reject);
|
|
285
|
+
if (firstChunk && "resume" in inputStream && typeof inputStream.resume === "function") {
|
|
286
|
+
inputStream.resume();
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
async function convertBuffer(input, opts = {}) {
|
|
291
|
+
let actualOpts = { ...opts };
|
|
292
|
+
if (opts.inputFormat === "auto") {
|
|
293
|
+
const sampleSize = Math.min(256 * 1024, input.length);
|
|
294
|
+
const sample = new Uint8Array(input.buffer, input.byteOffset, sampleSize);
|
|
295
|
+
const detected = await autoDetectConfig(sample, { debug: opts.debug });
|
|
296
|
+
if (detected.format !== "unknown") {
|
|
297
|
+
actualOpts.inputFormat = detected.format;
|
|
298
|
+
if (detected.csvConfig) {
|
|
299
|
+
actualOpts.csvConfig = opts.csvConfig ? { ...detected.csvConfig, ...opts.csvConfig } : detected.csvConfig;
|
|
300
|
+
}
|
|
301
|
+
if (detected.xmlConfig) {
|
|
302
|
+
actualOpts.xmlConfig = opts.xmlConfig ? { ...detected.xmlConfig, ...opts.xmlConfig } : detected.xmlConfig;
|
|
303
|
+
}
|
|
304
|
+
if (opts.debug) {
|
|
305
|
+
console.log("[convert-buddy] Auto-detected format:", detected.format);
|
|
306
|
+
}
|
|
307
|
+
} else {
|
|
308
|
+
throw new Error("Could not auto-detect input format.");
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const buddy = await ConvertBuddy.create(actualOpts);
|
|
312
|
+
const output = buddy.push(new Uint8Array(input));
|
|
313
|
+
const final = buddy.finish();
|
|
314
|
+
if (opts.profile) {
|
|
315
|
+
console.log("[convert-buddy] Performance Stats:", buddy.stats());
|
|
316
|
+
}
|
|
317
|
+
return Buffer.concat([Buffer.from(output), Buffer.from(final)]);
|
|
318
|
+
}
|
|
56
319
|
export {
|
|
320
|
+
convertBuffer,
|
|
321
|
+
convertFileToBuffer,
|
|
322
|
+
convertFileToFile,
|
|
323
|
+
convertFileToString,
|
|
324
|
+
convertStream,
|
|
57
325
|
createNodeTransform
|
|
58
326
|
};
|
|
59
327
|
//# sourceMappingURL=node.js.map
|
package/dist/src/node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/node.ts"],"sourcesContent":["import type { Transform as NodeTransform } from \"node:stream\";\r\n\r\nimport { ConvertBuddy, type ConvertBuddyOptions } from \"./index\";\r\n\r\nexport * from \"./index\";\r\n\r\n// Node.js Transform Stream adapter\r\nasync function loadNodeTransform(): Promise<typeof import(\"node:stream\").Transform> {\r\n const isNode =\r\n typeof process !== \"undefined\" &&\r\n !!(process as any).versions?.node;\r\n\r\n if (!isNode) {\r\n throw new Error(\"createNodeTransform is only available in Node.js runtimes.\");\r\n }\r\n\r\n const streamModule = await import(\"node:stream\");\r\n return streamModule.Transform;\r\n}\r\n\r\nexport async function createNodeTransform(\r\n opts: ConvertBuddyOptions = {}\r\n): Promise<NodeTransform> {\r\n let buddy: ConvertBuddy | null = null;\r\n let initPromise: Promise<void> | null = null;\r\n\r\n const Transform = await loadNodeTransform();\r\n const transform = new Transform({\r\n async transform(chunk: Buffer, encoding: string, callback: Function) {\r\n try {\r\n if (!buddy) {\r\n if (!initPromise) {\r\n initPromise = ConvertBuddy.create(opts).then((b) => {\r\n buddy = b;\r\n });\r\n }\r\n await initPromise;\r\n }\r\n\r\n const input = new Uint8Array(chunk);\r\n const output = buddy!.push(input);\r\n\r\n if (output.length > 0) {\r\n this.push(Buffer.from(output));\r\n }\r\n\r\n callback();\r\n } catch (err) {\r\n callback(err);\r\n }\r\n },\r\n\r\n async flush(callback: Function) {\r\n try {\r\n if (buddy) {\r\n const output = buddy.finish();\r\n if (output.length > 0) {\r\n this.push(Buffer.from(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 callback();\r\n } catch (err) {\r\n callback(err);\r\n }\r\n },\r\n });\r\n\r\n return transform;\r\n}\r\n"],"mappings":"AAEA,SAAS,oBAA8C;AAEvD,cAAc;AAGd,eAAe,oBAAqE;AAClF,QAAM,SACJ,OAAO,YAAY,eACnB,CAAC,CAAE,QAAgB,UAAU;AAE/B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,4DAA4D;AAAA,EAC9E;AAEA,QAAM,eAAe,MAAM,OAAO,aAAa;AAC/C,SAAO,aAAa;AACtB;AAEA,eAAsB,oBACpB,OAA4B,CAAC,GACL;AACxB,MAAI,QAA6B;AACjC,MAAI,cAAoC;AAExC,QAAM,YAAY,MAAM,kBAAkB;AAC1C,QAAM,YAAY,IAAI,UAAU;AAAA,IAC9B,MAAM,UAAU,OAAe,UAAkB,UAAoB;AACnE,UAAI;AACF,YAAI,CAAC,OAAO;AACV,cAAI,CAAC,aAAa;AAChB,0BAAc,aAAa,OAAO,IAAI,EAAE,KAAK,CAAC,MAAM;AAClD,sBAAQ;AAAA,YACV,CAAC;AAAA,UACH;AACA,gBAAM;AAAA,QACR;AAEA,cAAM,QAAQ,IAAI,WAAW,KAAK;AAClC,cAAM,SAAS,MAAO,KAAK,KAAK;AAEhC,YAAI,OAAO,SAAS,GAAG;AACrB,eAAK,KAAK,OAAO,KAAK,MAAM,CAAC;AAAA,QAC/B;AAEA,iBAAS;AAAA,MACX,SAAS,KAAK;AACZ,iBAAS,GAAG;AAAA,MACd;AAAA,IACF;AAAA,IAEA,MAAM,MAAM,UAAoB;AAC9B,UAAI;AACF,YAAI,OAAO;AACT,gBAAM,SAAS,MAAM,OAAO;AAC5B,cAAI,OAAO,SAAS,GAAG;AACrB,iBAAK,KAAK,OAAO,KAAK,MAAM,CAAC;AAAA,UAC/B;AAEA,cAAI,KAAK,SAAS;AAChB,kBAAM,QAAQ,MAAM,MAAM;AAC1B,oBAAQ,IAAI,sCAAsC,KAAK;AAAA,UACzD;AAAA,QACF;AACA,iBAAS;AAAA,MACX,SAAS,KAAK;AACZ,iBAAS,GAAG;AAAA,MACd;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/node.ts"],"sourcesContent":["import type { Transform as NodeTransform } from \"node:stream\";\r\nimport type { PathLike } from \"node:fs\";\r\n\r\nimport { ConvertBuddy, type ConvertBuddyOptions, type Format, autoDetectConfig } from \"./index.js\";\r\n\r\nexport * from \"./index.js\";\r\n\r\n// Node.js Transform Stream adapter\r\nasync function loadNodeTransform(): Promise<typeof import(\"node:stream\").Transform> {\r\n const isNode =\r\n typeof process !== \"undefined\" &&\r\n !!(process as any).versions?.node;\r\n\r\n if (!isNode) {\r\n throw new Error(\"createNodeTransform is only available in Node.js runtimes.\");\r\n }\r\n\r\n const streamModule = await import(\"node:stream\");\r\n return streamModule.Transform;\r\n}\r\n\r\nexport async function createNodeTransform(\r\n opts: ConvertBuddyOptions = {}\r\n): Promise<NodeTransform> {\r\n let buddy: ConvertBuddy | null = null;\r\n let initPromise: Promise<void> | null = null;\r\n\r\n const Transform = await loadNodeTransform();\r\n const transform = new Transform({\r\n async transform(chunk: Buffer, encoding: string, callback: Function) {\r\n try {\r\n if (!buddy) {\r\n if (!initPromise) {\r\n initPromise = ConvertBuddy.create(opts).then((b) => {\r\n buddy = b;\r\n });\r\n }\r\n await initPromise;\r\n }\r\n\r\n const input = new Uint8Array(chunk);\r\n const output = buddy!.push(input);\r\n\r\n if (output.length > 0) {\r\n this.push(Buffer.from(output));\r\n }\r\n\r\n callback();\r\n } catch (err) {\r\n callback(err);\r\n }\r\n },\r\n\r\n async flush(callback: Function) {\r\n try {\r\n if (buddy) {\r\n const output = buddy.finish();\r\n if (output.length > 0) {\r\n this.push(Buffer.from(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 callback();\r\n } catch (err) {\r\n callback(err);\r\n }\r\n },\r\n });\r\n\r\n return transform;\r\n}\r\n\r\n/**\r\n * Convert a file from one format to another and return as a string.\r\n * Handles file reading and streaming internally.\r\n * \r\n * @example\r\n * // Basic conversion\r\n * const result = await convertFileToString(\"input.csv\", {\r\n * inputFormat: \"csv\",\r\n * outputFormat: \"json\"\r\n * });\r\n * \r\n * @example\r\n * // With auto-detection\r\n * const result = await convertFileToString(\"data.csv\", {\r\n * inputFormat: \"auto\",\r\n * outputFormat: \"ndjson\",\r\n * onProgress: (stats) => {\r\n * console.log(`Processed ${stats.recordsProcessed} records`);\r\n * }\r\n * });\r\n */\r\nexport async function convertFileToString(\r\n inputPath: PathLike,\r\n opts: ConvertBuddyOptions = {}\r\n): Promise<string> {\r\n const bytes = await convertFileToBuffer(inputPath, opts);\r\n return bytes.toString(\"utf-8\");\r\n}\r\n\r\n/**\r\n * Convert a file from one format to another and return as a Buffer.\r\n * Handles file reading and streaming internally.\r\n * \r\n * @example\r\n * const buffer = await convertFileToBuffer(\"input.csv\", {\r\n * inputFormat: \"csv\",\r\n * outputFormat: \"json\"\r\n * });\r\n * console.log(buffer.toString());\r\n */\r\nexport async function convertFileToBuffer(\r\n inputPath: PathLike,\r\n opts: ConvertBuddyOptions = {}\r\n): Promise<Buffer> {\r\n const fs = await import(\"node:fs\");\r\n const path = await import(\"node:path\");\r\n \r\n // Handle auto-detection\r\n let actualOpts = { ...opts };\r\n \r\n if (opts.inputFormat === \"auto\") {\r\n // Read a sample for auto-detection\r\n const sampleSize = 256 * 1024; // 256KB\r\n const fileHandle = await fs.promises.open(inputPath, \"r\");\r\n const buffer = Buffer.allocUnsafe(sampleSize);\r\n const { bytesRead } = await fileHandle.read(buffer, 0, sampleSize, 0);\r\n await fileHandle.close();\r\n \r\n const sample = new Uint8Array(buffer.buffer, buffer.byteOffset, bytesRead);\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 const readStream = fs.createReadStream(inputPath, { highWaterMark: 64 * 1024 });\r\n \r\n const chunks: Buffer[] = [];\r\n \r\n return new Promise((resolve, reject) => {\r\n readStream.on(\"data\", (chunk: Buffer) => {\r\n try {\r\n if (buddy.isAborted()) {\r\n readStream.destroy();\r\n reject(new Error(\"Conversion aborted\"));\r\n return;\r\n }\r\n \r\n const output = buddy.push(new Uint8Array(chunk));\r\n if (output.length > 0) {\r\n chunks.push(Buffer.from(output));\r\n }\r\n } catch (error) {\r\n readStream.destroy();\r\n reject(error);\r\n }\r\n });\r\n \r\n readStream.on(\"end\", () => {\r\n try {\r\n const final = buddy.finish();\r\n if (final.length > 0) {\r\n chunks.push(Buffer.from(final));\r\n }\r\n \r\n if (opts.profile) {\r\n console.log(\"[convert-buddy] Performance Stats:\", buddy.stats());\r\n }\r\n \r\n resolve(Buffer.concat(chunks));\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n \r\n readStream.on(\"error\", reject);\r\n });\r\n}\r\n\r\n/**\r\n * Convert a file from one format to another and write to an output file.\r\n * Handles file reading, conversion, and writing with streaming.\r\n * \r\n * @example\r\n * await convertFileToFile(\"input.csv\", \"output.json\", {\r\n * inputFormat: \"csv\",\r\n * outputFormat: \"json\"\r\n * });\r\n * \r\n * @example\r\n * // With progress tracking\r\n * await convertFileToFile(\"large-data.csv\", \"output.ndjson\", {\r\n * inputFormat: \"auto\",\r\n * outputFormat: \"ndjson\",\r\n * onProgress: (stats) => {\r\n * const percent = (stats.bytesIn / totalSize * 100).toFixed(1);\r\n * console.log(`Progress: ${percent}%`);\r\n * }\r\n * });\r\n */\r\nexport async function convertFileToFile(\r\n inputPath: PathLike,\r\n outputPath: PathLike,\r\n opts: ConvertBuddyOptions = {}\r\n): Promise<void> {\r\n const fs = await import(\"node:fs\");\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;\r\n const fileHandle = await fs.promises.open(inputPath, \"r\");\r\n const buffer = Buffer.allocUnsafe(sampleSize);\r\n const { bytesRead } = await fileHandle.read(buffer, 0, sampleSize, 0);\r\n await fileHandle.close();\r\n \r\n const sample = new Uint8Array(buffer.buffer, buffer.byteOffset, bytesRead);\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 const readStream = fs.createReadStream(inputPath, { highWaterMark: 64 * 1024 });\r\n const writeStream = fs.createWriteStream(outputPath);\r\n \r\n return new Promise((resolve, reject) => {\r\n readStream.on(\"data\", (chunk: Buffer) => {\r\n try {\r\n if (buddy.isAborted()) {\r\n readStream.destroy();\r\n writeStream.destroy();\r\n reject(new Error(\"Conversion aborted\"));\r\n return;\r\n }\r\n \r\n const output = buddy.push(new Uint8Array(chunk));\r\n if (output.length > 0) {\r\n writeStream.write(Buffer.from(output));\r\n }\r\n } catch (error) {\r\n readStream.destroy();\r\n writeStream.destroy();\r\n reject(error);\r\n }\r\n });\r\n \r\n readStream.on(\"end\", () => {\r\n try {\r\n const final = buddy.finish();\r\n if (final.length > 0) {\r\n writeStream.write(Buffer.from(final));\r\n }\r\n \r\n writeStream.end();\r\n \r\n if (opts.profile) {\r\n console.log(\"[convert-buddy] Performance Stats:\", buddy.stats());\r\n }\r\n } catch (error) {\r\n writeStream.destroy();\r\n reject(error);\r\n }\r\n });\r\n \r\n writeStream.on(\"finish\", () => resolve());\r\n writeStream.on(\"error\", reject);\r\n readStream.on(\"error\", reject);\r\n });\r\n}\r\n\r\n/**\r\n * Convert data from a Node.js Readable stream.\r\n * Useful for processing data from HTTP requests, stdin, or other stream sources.\r\n * \r\n * @example\r\n * import { createReadStream } from 'fs';\r\n * const stream = createReadStream('input.csv');\r\n * const result = await convertStream(stream, {\r\n * inputFormat: \"csv\",\r\n * outputFormat: \"json\"\r\n * });\r\n */\r\nexport async function convertStream(\r\n inputStream: NodeJS.ReadableStream,\r\n opts: ConvertBuddyOptions = {}\r\n): Promise<Buffer> {\r\n // Handle auto-detection by buffering initial chunk\r\n let actualOpts = { ...opts };\r\n let firstChunk: Buffer | null = null;\r\n \r\n if (opts.inputFormat === \"auto\") {\r\n // We need to peek at the first chunk for detection\r\n const sampleSize = 256 * 1024;\r\n const chunks: Buffer[] = [];\r\n let totalSize = 0;\r\n \r\n await new Promise<void>((resolve, reject) => {\r\n const onData = (chunk: Buffer) => {\r\n chunks.push(chunk);\r\n totalSize += chunk.length;\r\n \r\n if (totalSize >= sampleSize) {\r\n inputStream.removeListener(\"data\", onData);\r\n if ('pause' in inputStream && typeof inputStream.pause === 'function') {\r\n inputStream.pause();\r\n }\r\n resolve();\r\n }\r\n };\r\n \r\n const onEnd = () => {\r\n inputStream.removeListener(\"data\", onData);\r\n resolve();\r\n };\r\n \r\n inputStream.on(\"data\", onData);\r\n inputStream.once(\"end\", onEnd);\r\n inputStream.once(\"error\", reject);\r\n });\r\n \r\n const sample = Buffer.concat(chunks).slice(0, sampleSize);\r\n const detected = await autoDetectConfig(new Uint8Array(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.\");\r\n }\r\n \r\n // Store the buffered data to process it first\r\n firstChunk = Buffer.concat(chunks);\r\n }\r\n \r\n const buddy = await ConvertBuddy.create(actualOpts);\r\n const chunks: Buffer[] = [];\r\n \r\n return new Promise((resolve, reject) => {\r\n // Process the buffered first chunk if we did auto-detection\r\n if (firstChunk) {\r\n try {\r\n const output = buddy.push(new Uint8Array(firstChunk));\r\n if (output.length > 0) {\r\n chunks.push(Buffer.from(output));\r\n }\r\n } catch (error) {\r\n return reject(error);\r\n }\r\n }\r\n \r\n inputStream.on(\"data\", (chunk: Buffer) => {\r\n try {\r\n if (buddy.isAborted()) {\r\n if ('destroy' in inputStream && typeof inputStream.destroy === 'function') {\r\n inputStream.destroy();\r\n }\r\n reject(new Error(\"Conversion aborted\"));\r\n return;\r\n }\r\n \r\n const output = buddy.push(new Uint8Array(chunk));\r\n if (output.length > 0) {\r\n chunks.push(Buffer.from(output));\r\n }\r\n } catch (error) {\r\n if ('destroy' in inputStream && typeof inputStream.destroy === 'function') {\r\n inputStream.destroy();\r\n }\r\n reject(error);\r\n }\r\n });\r\n \r\n inputStream.on(\"end\", () => {\r\n try {\r\n const final = buddy.finish();\r\n if (final.length > 0) {\r\n chunks.push(Buffer.from(final));\r\n }\r\n \r\n if (opts.profile) {\r\n console.log(\"[convert-buddy] Performance Stats:\", buddy.stats());\r\n }\r\n \r\n resolve(Buffer.concat(chunks));\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n \r\n inputStream.on(\"error\", reject);\r\n \r\n // Resume if we paused for auto-detection\r\n if (firstChunk && 'resume' in inputStream && typeof inputStream.resume === 'function') {\r\n inputStream.resume();\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Convert a Buffer directly (useful when you already have data in memory).\r\n * \r\n * @example\r\n * const buffer = Buffer.from(csvData);\r\n * const result = await convertBuffer(buffer, {\r\n * inputFormat: \"csv\",\r\n * outputFormat: \"json\"\r\n * });\r\n */\r\nexport async function convertBuffer(\r\n input: Buffer,\r\n opts: ConvertBuddyOptions = {}\r\n): Promise<Buffer> {\r\n // Handle auto-detection\r\n let actualOpts = { ...opts };\r\n \r\n if (opts.inputFormat === \"auto\") {\r\n const sampleSize = Math.min(256 * 1024, input.length);\r\n const sample = new Uint8Array(input.buffer, input.byteOffset, sampleSize);\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.\");\r\n }\r\n }\r\n \r\n const buddy = await ConvertBuddy.create(actualOpts);\r\n const output = buddy.push(new Uint8Array(input));\r\n const final = buddy.finish();\r\n \r\n if (opts.profile) {\r\n console.log(\"[convert-buddy] Performance Stats:\", buddy.stats());\r\n }\r\n \r\n return Buffer.concat([Buffer.from(output), Buffer.from(final)]);\r\n}\r\n"],"mappings":"AAGA,SAAS,cAAqD,wBAAwB;AAEtF,cAAc;AAGd,eAAe,oBAAqE;AAClF,QAAM,SACJ,OAAO,YAAY,eACnB,CAAC,CAAE,QAAgB,UAAU;AAE/B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,4DAA4D;AAAA,EAC9E;AAEA,QAAM,eAAe,MAAM,OAAO,aAAa;AAC/C,SAAO,aAAa;AACtB;AAEA,eAAsB,oBACpB,OAA4B,CAAC,GACL;AACxB,MAAI,QAA6B;AACjC,MAAI,cAAoC;AAExC,QAAM,YAAY,MAAM,kBAAkB;AAC1C,QAAM,YAAY,IAAI,UAAU;AAAA,IAC9B,MAAM,UAAU,OAAe,UAAkB,UAAoB;AACnE,UAAI;AACF,YAAI,CAAC,OAAO;AACV,cAAI,CAAC,aAAa;AAChB,0BAAc,aAAa,OAAO,IAAI,EAAE,KAAK,CAAC,MAAM;AAClD,sBAAQ;AAAA,YACV,CAAC;AAAA,UACH;AACA,gBAAM;AAAA,QACR;AAEA,cAAM,QAAQ,IAAI,WAAW,KAAK;AAClC,cAAM,SAAS,MAAO,KAAK,KAAK;AAEhC,YAAI,OAAO,SAAS,GAAG;AACrB,eAAK,KAAK,OAAO,KAAK,MAAM,CAAC;AAAA,QAC/B;AAEA,iBAAS;AAAA,MACX,SAAS,KAAK;AACZ,iBAAS,GAAG;AAAA,MACd;AAAA,IACF;AAAA,IAEA,MAAM,MAAM,UAAoB;AAC9B,UAAI;AACF,YAAI,OAAO;AACT,gBAAM,SAAS,MAAM,OAAO;AAC5B,cAAI,OAAO,SAAS,GAAG;AACrB,iBAAK,KAAK,OAAO,KAAK,MAAM,CAAC;AAAA,UAC/B;AAEA,cAAI,KAAK,SAAS;AAChB,kBAAM,QAAQ,MAAM,MAAM;AAC1B,oBAAQ,IAAI,sCAAsC,KAAK;AAAA,UACzD;AAAA,QACF;AACA,iBAAS;AAAA,MACX,SAAS,KAAK;AACZ,iBAAS,GAAG;AAAA,MACd;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAuBA,eAAsB,oBACpB,WACA,OAA4B,CAAC,GACZ;AACjB,QAAM,QAAQ,MAAM,oBAAoB,WAAW,IAAI;AACvD,SAAO,MAAM,SAAS,OAAO;AAC/B;AAaA,eAAsB,oBACpB,WACA,OAA4B,CAAC,GACZ;AACjB,QAAM,KAAK,MAAM,OAAO,SAAS;AACjC,QAAM,OAAO,MAAM,OAAO,WAAW;AAGrC,MAAI,aAAa,EAAE,GAAG,KAAK;AAE3B,MAAI,KAAK,gBAAgB,QAAQ;AAE/B,UAAM,aAAa,MAAM;AACzB,UAAM,aAAa,MAAM,GAAG,SAAS,KAAK,WAAW,GAAG;AACxD,UAAM,SAAS,OAAO,YAAY,UAAU;AAC5C,UAAM,EAAE,UAAU,IAAI,MAAM,WAAW,KAAK,QAAQ,GAAG,YAAY,CAAC;AACpE,UAAM,WAAW,MAAM;AAEvB,UAAM,SAAS,IAAI,WAAW,OAAO,QAAQ,OAAO,YAAY,SAAS;AACzE,UAAM,WAAW,MAAM,iBAAiB,QAAQ,EAAE,OAAO,KAAK,MAAM,CAAC;AAErE,QAAI,SAAS,WAAW,WAAW;AACjC,iBAAW,cAAc,SAAS;AAElC,UAAI,SAAS,WAAW;AACtB,mBAAW,YAAY,KAAK,YAAY,EAAE,GAAG,SAAS,WAAW,GAAG,KAAK,UAAU,IAAI,SAAS;AAAA,MAClG;AAEA,UAAI,SAAS,WAAW;AACtB,mBAAW,YAAY,KAAK,YAAY,EAAE,GAAG,SAAS,WAAW,GAAG,KAAK,UAAU,IAAI,SAAS;AAAA,MAClG;AAEA,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,yCAAyC,SAAS,MAAM;AAAA,MACtE;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,4EAA4E;AAAA,IAC9F;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,aAAa,OAAO,UAAU;AAClD,QAAM,aAAa,GAAG,iBAAiB,WAAW,EAAE,eAAe,KAAK,KAAK,CAAC;AAE9E,QAAM,SAAmB,CAAC;AAE1B,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,eAAW,GAAG,QAAQ,CAAC,UAAkB;AACvC,UAAI;AACF,YAAI,MAAM,UAAU,GAAG;AACrB,qBAAW,QAAQ;AACnB,iBAAO,IAAI,MAAM,oBAAoB,CAAC;AACtC;AAAA,QACF;AAEA,cAAM,SAAS,MAAM,KAAK,IAAI,WAAW,KAAK,CAAC;AAC/C,YAAI,OAAO,SAAS,GAAG;AACrB,iBAAO,KAAK,OAAO,KAAK,MAAM,CAAC;AAAA,QACjC;AAAA,MACF,SAAS,OAAO;AACd,mBAAW,QAAQ;AACnB,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAED,eAAW,GAAG,OAAO,MAAM;AACzB,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO;AAC3B,YAAI,MAAM,SAAS,GAAG;AACpB,iBAAO,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,QAChC;AAEA,YAAI,KAAK,SAAS;AAChB,kBAAQ,IAAI,sCAAsC,MAAM,MAAM,CAAC;AAAA,QACjE;AAEA,gBAAQ,OAAO,OAAO,MAAM,CAAC;AAAA,MAC/B,SAAS,OAAO;AACd,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAED,eAAW,GAAG,SAAS,MAAM;AAAA,EAC/B,CAAC;AACH;AAuBA,eAAsB,kBACpB,WACA,YACA,OAA4B,CAAC,GACd;AACf,QAAM,KAAK,MAAM,OAAO,SAAS;AAGjC,MAAI,aAAa,EAAE,GAAG,KAAK;AAE3B,MAAI,KAAK,gBAAgB,QAAQ;AAC/B,UAAM,aAAa,MAAM;AACzB,UAAM,aAAa,MAAM,GAAG,SAAS,KAAK,WAAW,GAAG;AACxD,UAAM,SAAS,OAAO,YAAY,UAAU;AAC5C,UAAM,EAAE,UAAU,IAAI,MAAM,WAAW,KAAK,QAAQ,GAAG,YAAY,CAAC;AACpE,UAAM,WAAW,MAAM;AAEvB,UAAM,SAAS,IAAI,WAAW,OAAO,QAAQ,OAAO,YAAY,SAAS;AACzE,UAAM,WAAW,MAAM,iBAAiB,QAAQ,EAAE,OAAO,KAAK,MAAM,CAAC;AAErE,QAAI,SAAS,WAAW,WAAW;AACjC,iBAAW,cAAc,SAAS;AAElC,UAAI,SAAS,WAAW;AACtB,mBAAW,YAAY,KAAK,YAAY,EAAE,GAAG,SAAS,WAAW,GAAG,KAAK,UAAU,IAAI,SAAS;AAAA,MAClG;AAEA,UAAI,SAAS,WAAW;AACtB,mBAAW,YAAY,KAAK,YAAY,EAAE,GAAG,SAAS,WAAW,GAAG,KAAK,UAAU,IAAI,SAAS;AAAA,MAClG;AAEA,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,yCAAyC,SAAS,MAAM;AAAA,MACtE;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,4EAA4E;AAAA,IAC9F;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,aAAa,OAAO,UAAU;AAClD,QAAM,aAAa,GAAG,iBAAiB,WAAW,EAAE,eAAe,KAAK,KAAK,CAAC;AAC9E,QAAM,cAAc,GAAG,kBAAkB,UAAU;AAEnD,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,eAAW,GAAG,QAAQ,CAAC,UAAkB;AACvC,UAAI;AACF,YAAI,MAAM,UAAU,GAAG;AACrB,qBAAW,QAAQ;AACnB,sBAAY,QAAQ;AACpB,iBAAO,IAAI,MAAM,oBAAoB,CAAC;AACtC;AAAA,QACF;AAEA,cAAM,SAAS,MAAM,KAAK,IAAI,WAAW,KAAK,CAAC;AAC/C,YAAI,OAAO,SAAS,GAAG;AACrB,sBAAY,MAAM,OAAO,KAAK,MAAM,CAAC;AAAA,QACvC;AAAA,MACF,SAAS,OAAO;AACd,mBAAW,QAAQ;AACnB,oBAAY,QAAQ;AACpB,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAED,eAAW,GAAG,OAAO,MAAM;AACzB,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO;AAC3B,YAAI,MAAM,SAAS,GAAG;AACpB,sBAAY,MAAM,OAAO,KAAK,KAAK,CAAC;AAAA,QACtC;AAEA,oBAAY,IAAI;AAEhB,YAAI,KAAK,SAAS;AAChB,kBAAQ,IAAI,sCAAsC,MAAM,MAAM,CAAC;AAAA,QACjE;AAAA,MACF,SAAS,OAAO;AACd,oBAAY,QAAQ;AACpB,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAED,gBAAY,GAAG,UAAU,MAAM,QAAQ,CAAC;AACxC,gBAAY,GAAG,SAAS,MAAM;AAC9B,eAAW,GAAG,SAAS,MAAM;AAAA,EAC/B,CAAC;AACH;AAcA,eAAsB,cACpB,aACA,OAA4B,CAAC,GACZ;AAEjB,MAAI,aAAa,EAAE,GAAG,KAAK;AAC3B,MAAI,aAA4B;AAEhC,MAAI,KAAK,gBAAgB,QAAQ;AAE/B,UAAM,aAAa,MAAM;AACzB,UAAMA,UAAmB,CAAC;AAC1B,QAAI,YAAY;AAEhB,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,YAAM,SAAS,CAAC,UAAkB;AAChC,QAAAA,QAAO,KAAK,KAAK;AACjB,qBAAa,MAAM;AAEnB,YAAI,aAAa,YAAY;AAC3B,sBAAY,eAAe,QAAQ,MAAM;AACzC,cAAI,WAAW,eAAe,OAAO,YAAY,UAAU,YAAY;AACrE,wBAAY,MAAM;AAAA,UACpB;AACA,kBAAQ;AAAA,QACV;AAAA,MACF;AAEA,YAAM,QAAQ,MAAM;AAClB,oBAAY,eAAe,QAAQ,MAAM;AACzC,gBAAQ;AAAA,MACV;AAEA,kBAAY,GAAG,QAAQ,MAAM;AAC7B,kBAAY,KAAK,OAAO,KAAK;AAC7B,kBAAY,KAAK,SAAS,MAAM;AAAA,IAClC,CAAC;AAED,UAAM,SAAS,OAAO,OAAOA,OAAM,EAAE,MAAM,GAAG,UAAU;AACxD,UAAM,WAAW,MAAM,iBAAiB,IAAI,WAAW,MAAM,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;AAErF,QAAI,SAAS,WAAW,WAAW;AACjC,iBAAW,cAAc,SAAS;AAElC,UAAI,SAAS,WAAW;AACtB,mBAAW,YAAY,KAAK,YAAY,EAAE,GAAG,SAAS,WAAW,GAAG,KAAK,UAAU,IAAI,SAAS;AAAA,MAClG;AAEA,UAAI,SAAS,WAAW;AACtB,mBAAW,YAAY,KAAK,YAAY,EAAE,GAAG,SAAS,WAAW,GAAG,KAAK,UAAU,IAAI,SAAS;AAAA,MAClG;AAEA,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,yCAAyC,SAAS,MAAM;AAAA,MACtE;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AAGA,iBAAa,OAAO,OAAOA,OAAM;AAAA,EACnC;AAEA,QAAM,QAAQ,MAAM,aAAa,OAAO,UAAU;AAClD,QAAM,SAAmB,CAAC;AAE1B,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AAEtC,QAAI,YAAY;AACd,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,IAAI,WAAW,UAAU,CAAC;AACpD,YAAI,OAAO,SAAS,GAAG;AACrB,iBAAO,KAAK,OAAO,KAAK,MAAM,CAAC;AAAA,QACjC;AAAA,MACF,SAAS,OAAO;AACd,eAAO,OAAO,KAAK;AAAA,MACrB;AAAA,IACF;AAEA,gBAAY,GAAG,QAAQ,CAAC,UAAkB;AACxC,UAAI;AACF,YAAI,MAAM,UAAU,GAAG;AACrB,cAAI,aAAa,eAAe,OAAO,YAAY,YAAY,YAAY;AACzE,wBAAY,QAAQ;AAAA,UACtB;AACA,iBAAO,IAAI,MAAM,oBAAoB,CAAC;AACtC;AAAA,QACF;AAEA,cAAM,SAAS,MAAM,KAAK,IAAI,WAAW,KAAK,CAAC;AAC/C,YAAI,OAAO,SAAS,GAAG;AACrB,iBAAO,KAAK,OAAO,KAAK,MAAM,CAAC;AAAA,QACjC;AAAA,MACF,SAAS,OAAO;AACd,YAAI,aAAa,eAAe,OAAO,YAAY,YAAY,YAAY;AACzE,sBAAY,QAAQ;AAAA,QACtB;AACA,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAED,gBAAY,GAAG,OAAO,MAAM;AAC1B,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO;AAC3B,YAAI,MAAM,SAAS,GAAG;AACpB,iBAAO,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,QAChC;AAEA,YAAI,KAAK,SAAS;AAChB,kBAAQ,IAAI,sCAAsC,MAAM,MAAM,CAAC;AAAA,QACjE;AAEA,gBAAQ,OAAO,OAAO,MAAM,CAAC;AAAA,MAC/B,SAAS,OAAO;AACd,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAED,gBAAY,GAAG,SAAS,MAAM;AAG9B,QAAI,cAAc,YAAY,eAAe,OAAO,YAAY,WAAW,YAAY;AACrF,kBAAY,OAAO;AAAA,IACrB;AAAA,EACF,CAAC;AACH;AAYA,eAAsB,cACpB,OACA,OAA4B,CAAC,GACZ;AAEjB,MAAI,aAAa,EAAE,GAAG,KAAK;AAE3B,MAAI,KAAK,gBAAgB,QAAQ;AAC/B,UAAM,aAAa,KAAK,IAAI,MAAM,MAAM,MAAM,MAAM;AACpD,UAAM,SAAS,IAAI,WAAW,MAAM,QAAQ,MAAM,YAAY,UAAU;AACxE,UAAM,WAAW,MAAM,iBAAiB,QAAQ,EAAE,OAAO,KAAK,MAAM,CAAC;AAErE,QAAI,SAAS,WAAW,WAAW;AACjC,iBAAW,cAAc,SAAS;AAElC,UAAI,SAAS,WAAW;AACtB,mBAAW,YAAY,KAAK,YAAY,EAAE,GAAG,SAAS,WAAW,GAAG,KAAK,UAAU,IAAI,SAAS;AAAA,MAClG;AAEA,UAAI,SAAS,WAAW;AACtB,mBAAW,YAAY,KAAK,YAAY,EAAE,GAAG,SAAS,WAAW,GAAG,KAAK,UAAU,IAAI,SAAS;AAAA,MAClG;AAEA,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,yCAAyC,SAAS,MAAM;AAAA,MACtE;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,aAAa,OAAO,UAAU;AAClD,QAAM,SAAS,MAAM,KAAK,IAAI,WAAW,KAAK,CAAC;AAC/C,QAAM,QAAQ,MAAM,OAAO;AAE3B,MAAI,KAAK,SAAS;AAChB,YAAQ,IAAI,sCAAsC,MAAM,MAAM,CAAC;AAAA,EACjE;AAEA,SAAO,OAAO,OAAO,CAAC,OAAO,KAAK,MAAM,GAAG,OAAO,KAAK,KAAK,CAAC,CAAC;AAChE;","names":["chunks"]}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
import { ConvertBuddy } from "../../src/index.js";
|
|
4
|
+
describe("Abort/Pause/Resume Control", () => {
|
|
5
|
+
it("should abort conversion when abort() is called", async () => {
|
|
6
|
+
const buddy = await ConvertBuddy.create({
|
|
7
|
+
inputFormat: "csv",
|
|
8
|
+
outputFormat: "json"
|
|
9
|
+
});
|
|
10
|
+
const csvData = new TextEncoder().encode("name,age\nAlice,30\nBob,25\n");
|
|
11
|
+
buddy.push(csvData.slice(0, 10));
|
|
12
|
+
buddy.abort();
|
|
13
|
+
assert.throws(() => {
|
|
14
|
+
buddy.push(csvData.slice(10));
|
|
15
|
+
}, /aborted/);
|
|
16
|
+
assert.strictEqual(buddy.isAborted(), true);
|
|
17
|
+
});
|
|
18
|
+
it("should pause and resume conversion", async () => {
|
|
19
|
+
const buddy = await ConvertBuddy.create({
|
|
20
|
+
inputFormat: "csv",
|
|
21
|
+
outputFormat: "json"
|
|
22
|
+
});
|
|
23
|
+
const csvData = new TextEncoder().encode("name,age\nAlice,30\nBob,25\n");
|
|
24
|
+
buddy.push(csvData.slice(0, 10));
|
|
25
|
+
buddy.pause();
|
|
26
|
+
assert.strictEqual(buddy.isPaused(), true);
|
|
27
|
+
assert.throws(() => {
|
|
28
|
+
buddy.push(csvData.slice(10, 20));
|
|
29
|
+
}, /paused/);
|
|
30
|
+
buddy.resume();
|
|
31
|
+
assert.strictEqual(buddy.isPaused(), false);
|
|
32
|
+
buddy.push(csvData.slice(10));
|
|
33
|
+
const result = buddy.finish();
|
|
34
|
+
assert.ok(result.length > 0);
|
|
35
|
+
});
|
|
36
|
+
it("should track aborted state correctly", async () => {
|
|
37
|
+
const buddy = await ConvertBuddy.create({
|
|
38
|
+
inputFormat: "csv",
|
|
39
|
+
outputFormat: "json"
|
|
40
|
+
});
|
|
41
|
+
assert.strictEqual(buddy.isAborted(), false);
|
|
42
|
+
buddy.abort();
|
|
43
|
+
assert.strictEqual(buddy.isAborted(), true);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe("Progress Callbacks", () => {
|
|
47
|
+
it("should call progress callback during conversion", async () => {
|
|
48
|
+
let progressCalls = 0;
|
|
49
|
+
const buddy = await ConvertBuddy.create({
|
|
50
|
+
inputFormat: "csv",
|
|
51
|
+
outputFormat: "json",
|
|
52
|
+
onProgress: (stats) => {
|
|
53
|
+
progressCalls++;
|
|
54
|
+
},
|
|
55
|
+
progressIntervalBytes: 1
|
|
56
|
+
// Trigger on every byte for testing
|
|
57
|
+
});
|
|
58
|
+
const csvData = new TextEncoder().encode("name,age\nAlice,30\nBob,25\nCharlie,35\n");
|
|
59
|
+
buddy.push(csvData);
|
|
60
|
+
buddy.finish();
|
|
61
|
+
assert.ok(progressCalls > 0, "Progress callback should be called");
|
|
62
|
+
});
|
|
63
|
+
it("should call progress callback on finish", async () => {
|
|
64
|
+
let finalCallMade = false;
|
|
65
|
+
const buddy = await ConvertBuddy.create({
|
|
66
|
+
inputFormat: "csv",
|
|
67
|
+
outputFormat: "json",
|
|
68
|
+
onProgress: (stats) => {
|
|
69
|
+
finalCallMade = true;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
const csvData = new TextEncoder().encode("name,age\nAlice,30\n");
|
|
73
|
+
buddy.push(csvData);
|
|
74
|
+
buddy.finish();
|
|
75
|
+
assert.ok(finalCallMade, "Progress callback should be called on finish");
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
describe("Auto-detection", () => {
|
|
79
|
+
it("should handle auto format detection in options", async () => {
|
|
80
|
+
const buddy = await ConvertBuddy.create({
|
|
81
|
+
inputFormat: "auto",
|
|
82
|
+
outputFormat: "json"
|
|
83
|
+
});
|
|
84
|
+
assert.ok(buddy);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=control-features.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../tests/edge-cases/control-features.test.ts"],"sourcesContent":["import { describe, it, before } from \"node:test\";\r\nimport assert from \"node:assert\";\r\nimport { ConvertBuddy } from \"../../src/index.js\";\r\n\r\ndescribe(\"Abort/Pause/Resume Control\", () => {\r\n it(\"should abort conversion when abort() is called\", async () => {\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: \"csv\",\r\n outputFormat: \"json\",\r\n });\r\n\r\n const csvData = new TextEncoder().encode(\"name,age\\nAlice,30\\nBob,25\\n\");\r\n \r\n // Push first chunk\r\n buddy.push(csvData.slice(0, 10));\r\n \r\n // Abort the conversion\r\n buddy.abort();\r\n \r\n // Should throw when trying to push more data\r\n assert.throws(() => {\r\n buddy.push(csvData.slice(10));\r\n }, /aborted/);\r\n \r\n assert.strictEqual(buddy.isAborted(), true);\r\n });\r\n\r\n it(\"should pause and resume conversion\", async () => {\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: \"csv\",\r\n outputFormat: \"json\",\r\n });\r\n\r\n const csvData = new TextEncoder().encode(\"name,age\\nAlice,30\\nBob,25\\n\");\r\n \r\n // Push first chunk\r\n buddy.push(csvData.slice(0, 10));\r\n \r\n // Pause the conversion\r\n buddy.pause();\r\n assert.strictEqual(buddy.isPaused(), true);\r\n \r\n // Should throw when trying to push while paused\r\n assert.throws(() => {\r\n buddy.push(csvData.slice(10, 20));\r\n }, /paused/);\r\n \r\n // Resume and continue\r\n buddy.resume();\r\n assert.strictEqual(buddy.isPaused(), false);\r\n \r\n // Should work now\r\n buddy.push(csvData.slice(10));\r\n const result = buddy.finish();\r\n assert.ok(result.length > 0);\r\n });\r\n\r\n it(\"should track aborted state correctly\", async () => {\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: \"csv\",\r\n outputFormat: \"json\",\r\n });\r\n\r\n assert.strictEqual(buddy.isAborted(), false);\r\n buddy.abort();\r\n assert.strictEqual(buddy.isAborted(), true);\r\n });\r\n});\r\n\r\ndescribe(\"Progress Callbacks\", () => {\r\n it(\"should call progress callback during conversion\", async () => {\r\n let progressCalls = 0;\r\n\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: \"csv\",\r\n outputFormat: \"json\",\r\n onProgress: (stats) => {\r\n progressCalls++;\r\n },\r\n progressIntervalBytes: 1, // Trigger on every byte for testing\r\n });\r\n\r\n const csvData = new TextEncoder().encode(\"name,age\\nAlice,30\\nBob,25\\nCharlie,35\\n\");\r\n \r\n // Push all data at once\r\n buddy.push(csvData);\r\n buddy.finish();\r\n \r\n // Progress callback should have been called at least on finish\r\n assert.ok(progressCalls > 0, \"Progress callback should be called\");\r\n });\r\n\r\n it(\"should call progress callback on finish\", async () => {\r\n let finalCallMade = false;\r\n\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: \"csv\",\r\n outputFormat: \"json\",\r\n onProgress: (stats) => {\r\n finalCallMade = true;\r\n },\r\n });\r\n\r\n const csvData = new TextEncoder().encode(\"name,age\\nAlice,30\\n\");\r\n buddy.push(csvData);\r\n buddy.finish();\r\n \r\n assert.ok(finalCallMade, \"Progress callback should be called on finish\");\r\n });\r\n});\r\n\r\ndescribe(\"Auto-detection\", () => {\r\n it(\"should handle auto format detection in options\", async () => {\r\n // This will test that the \"auto\" format is accepted\r\n // Actual detection happens on first push, which we can't easily test here\r\n // without data, but we can verify the option is accepted\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: \"auto\" as any,\r\n outputFormat: \"json\",\r\n });\r\n \r\n // Should not throw\r\n assert.ok(buddy);\r\n });\r\n});\r\n"],"mappings":"AAAA,SAAS,UAAU,UAAkB;AACrC,OAAO,YAAY;AACnB,SAAS,oBAAoB;AAE7B,SAAS,8BAA8B,MAAM;AAC3C,KAAG,kDAAkD,YAAY;AAC/D,UAAM,QAAQ,MAAM,aAAa,OAAO;AAAA,MACtC,aAAa;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAED,UAAM,UAAU,IAAI,YAAY,EAAE,OAAO,8BAA8B;AAGvE,UAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,CAAC;AAG/B,UAAM,MAAM;AAGZ,WAAO,OAAO,MAAM;AAClB,YAAM,KAAK,QAAQ,MAAM,EAAE,CAAC;AAAA,IAC9B,GAAG,SAAS;AAEZ,WAAO,YAAY,MAAM,UAAU,GAAG,IAAI;AAAA,EAC5C,CAAC;AAED,KAAG,sCAAsC,YAAY;AACnD,UAAM,QAAQ,MAAM,aAAa,OAAO;AAAA,MACtC,aAAa;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAED,UAAM,UAAU,IAAI,YAAY,EAAE,OAAO,8BAA8B;AAGvE,UAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,CAAC;AAG/B,UAAM,MAAM;AACZ,WAAO,YAAY,MAAM,SAAS,GAAG,IAAI;AAGzC,WAAO,OAAO,MAAM;AAClB,YAAM,KAAK,QAAQ,MAAM,IAAI,EAAE,CAAC;AAAA,IAClC,GAAG,QAAQ;AAGX,UAAM,OAAO;AACb,WAAO,YAAY,MAAM,SAAS,GAAG,KAAK;AAG1C,UAAM,KAAK,QAAQ,MAAM,EAAE,CAAC;AAC5B,UAAM,SAAS,MAAM,OAAO;AAC5B,WAAO,GAAG,OAAO,SAAS,CAAC;AAAA,EAC7B,CAAC;AAED,KAAG,wCAAwC,YAAY;AACrD,UAAM,QAAQ,MAAM,aAAa,OAAO;AAAA,MACtC,aAAa;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAED,WAAO,YAAY,MAAM,UAAU,GAAG,KAAK;AAC3C,UAAM,MAAM;AACZ,WAAO,YAAY,MAAM,UAAU,GAAG,IAAI;AAAA,EAC5C,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,MAAM;AACnC,KAAG,mDAAmD,YAAY;AAChE,QAAI,gBAAgB;AAEpB,UAAM,QAAQ,MAAM,aAAa,OAAO;AAAA,MACtC,aAAa;AAAA,MACb,cAAc;AAAA,MACd,YAAY,CAAC,UAAU;AACrB;AAAA,MACF;AAAA,MACA,uBAAuB;AAAA;AAAA,IACzB,CAAC;AAED,UAAM,UAAU,IAAI,YAAY,EAAE,OAAO,0CAA0C;AAGnF,UAAM,KAAK,OAAO;AAClB,UAAM,OAAO;AAGb,WAAO,GAAG,gBAAgB,GAAG,oCAAoC;AAAA,EACnE,CAAC;AAED,KAAG,2CAA2C,YAAY;AACxD,QAAI,gBAAgB;AAEpB,UAAM,QAAQ,MAAM,aAAa,OAAO;AAAA,MACtC,aAAa;AAAA,MACb,cAAc;AAAA,MACd,YAAY,CAAC,UAAU;AACrB,wBAAgB;AAAA,MAClB;AAAA,IACF,CAAC;AAED,UAAM,UAAU,IAAI,YAAY,EAAE,OAAO,sBAAsB;AAC/D,UAAM,KAAK,OAAO;AAClB,UAAM,OAAO;AAEb,WAAO,GAAG,eAAe,8CAA8C;AAAA,EACzE,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,MAAM;AAC/B,KAAG,kDAAkD,YAAY;AAI/D,UAAM,QAAQ,MAAM,aAAa,OAAO;AAAA,MACtC,aAAa;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAGD,WAAO,GAAG,KAAK;AAAA,EACjB,CAAC;AACH,CAAC;","names":[]}
|