convert-buddy-js 0.9.7 → 0.9.8

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.
@@ -0,0 +1,32 @@
1
+ interface NodejsThreadPoolConfig {
2
+ maxWorkers: number;
3
+ wasmPath: string;
4
+ }
5
+ interface WorkerTask {
6
+ id: string;
7
+ method: string;
8
+ data: Uint8Array;
9
+ options: any;
10
+ }
11
+ interface WorkerResult {
12
+ id: string;
13
+ result?: Uint8Array;
14
+ error?: string;
15
+ }
16
+ declare class NodejsThreadPool {
17
+ private config;
18
+ private workers;
19
+ private pendingTasks;
20
+ private nextTaskId;
21
+ private isInitialized;
22
+ private roundRobinIndex;
23
+ constructor(config: NodejsThreadPoolConfig);
24
+ initialize(): Promise<void>;
25
+ private handleWorkerMessage;
26
+ processChunks(method: string, chunks: Uint8Array[], options: any): Promise<Uint8Array[]>;
27
+ destroy(): void;
28
+ }
29
+ declare function chunkDataNodejs(data: Uint8Array, numChunks: number): Uint8Array[];
30
+ declare function mergeResultsNodejs(results: Uint8Array[], format: string): Uint8Array;
31
+
32
+ export { NodejsThreadPool, type NodejsThreadPoolConfig, type WorkerResult, type WorkerTask, chunkDataNodejs, mergeResultsNodejs };
@@ -0,0 +1,215 @@
1
+ import { Worker } from "worker_threads";
2
+ import { fileURLToPath } from "url";
3
+ import { dirname, join } from "path";
4
+ const __filename = fileURLToPath(import.meta.url);
5
+ const __dirname = dirname(__filename);
6
+ class NodejsThreadPool {
7
+ constructor(config) {
8
+ this.config = config;
9
+ }
10
+ workers = [];
11
+ pendingTasks = /* @__PURE__ */ new Map();
12
+ nextTaskId = 0;
13
+ isInitialized = false;
14
+ roundRobinIndex = 0;
15
+ async initialize() {
16
+ if (this.isInitialized) return;
17
+ const workerScript = `
18
+ import { parentPort, workerData } from 'worker_threads';
19
+ import { createRequire } from 'node:module';
20
+
21
+ const require = createRequire(import.meta.url);
22
+
23
+ let wasmModule = null;
24
+
25
+ async function initWasm() {
26
+ if (!wasmModule) {
27
+ // Import the Node.js WASM module
28
+ wasmModule = require('${this.config.wasmPath}');
29
+ wasmModule.init(false); // Initialize without debug logs in workers
30
+ }
31
+ return wasmModule;
32
+ }
33
+
34
+ parentPort.on('message', async (task) => {
35
+ try {
36
+ const { id, method, data, options } = task;
37
+
38
+ if (!wasmModule) {
39
+ await initWasm();
40
+ }
41
+
42
+ const converter = new wasmModule.Converter(false);
43
+
44
+ // Configure converter based on options
45
+ if (options.outputFormat) {
46
+ converter.set_output_format(options.outputFormat);
47
+ }
48
+ if (options.inputFormat) {
49
+ converter.set_input_format(options.inputFormat);
50
+ }
51
+
52
+ // Process the data
53
+ const output = converter.push(data);
54
+ const final = converter.finish();
55
+
56
+ // Combine outputs
57
+ const result = new Uint8Array(output.length + final.length);
58
+ result.set(output, 0);
59
+ result.set(final, output.length);
60
+
61
+ parentPort.postMessage({ id, result });
62
+ } catch (error) {
63
+ parentPort.postMessage({ id, error: error.message });
64
+ }
65
+ });
66
+
67
+ // Initialize WASM when worker starts
68
+ initWasm().catch(console.error);
69
+ `;
70
+ const workerPath = join(__dirname, `worker-${Date.now()}.mjs`);
71
+ await import("fs").then((fs) => {
72
+ fs.writeFileSync(workerPath, workerScript);
73
+ });
74
+ try {
75
+ for (let i = 0; i < this.config.maxWorkers; i++) {
76
+ const worker = new Worker(workerPath, { type: "module" });
77
+ worker.on("message", (response) => {
78
+ this.handleWorkerMessage(response);
79
+ });
80
+ worker.on("error", (error) => {
81
+ console.error("Worker error:", error);
82
+ });
83
+ this.workers.push(worker);
84
+ }
85
+ this.isInitialized = true;
86
+ } finally {
87
+ setTimeout(() => {
88
+ import("fs").then((fs) => {
89
+ try {
90
+ fs.unlinkSync(workerPath);
91
+ } catch {
92
+ }
93
+ });
94
+ }, 1e3);
95
+ }
96
+ }
97
+ handleWorkerMessage(response) {
98
+ const pending = this.pendingTasks.get(response.id);
99
+ if (pending) {
100
+ this.pendingTasks.delete(response.id);
101
+ if (response.error) {
102
+ pending.reject(new Error(response.error));
103
+ } else {
104
+ pending.resolve(response.result);
105
+ }
106
+ }
107
+ }
108
+ async processChunks(method, chunks, options) {
109
+ if (!this.isInitialized) {
110
+ await this.initialize();
111
+ }
112
+ const promises = chunks.map((chunk, index) => {
113
+ const taskId = `${this.nextTaskId++}`;
114
+ const workerIndex = this.roundRobinIndex++ % this.workers.length;
115
+ return new Promise((resolve, reject) => {
116
+ this.pendingTasks.set(taskId, { resolve, reject });
117
+ const task = {
118
+ id: taskId,
119
+ method,
120
+ data: chunk,
121
+ options
122
+ };
123
+ this.workers[workerIndex].postMessage(task);
124
+ });
125
+ });
126
+ return Promise.all(promises);
127
+ }
128
+ destroy() {
129
+ this.workers.forEach((worker) => worker.terminate());
130
+ this.workers = [];
131
+ this.pendingTasks.clear();
132
+ this.isInitialized = false;
133
+ }
134
+ }
135
+ function chunkDataNodejs(data, numChunks) {
136
+ if (numChunks <= 1 || data.length < 1024) {
137
+ return [data];
138
+ }
139
+ const chunkSize = Math.ceil(data.length / numChunks);
140
+ const chunks = [];
141
+ let start = 0;
142
+ while (start < data.length) {
143
+ let end = Math.min(start + chunkSize, data.length);
144
+ if (end < data.length) {
145
+ const searchStart = Math.max(start + chunkSize - 2048, start);
146
+ const searchEnd = Math.min(end + 2048, data.length);
147
+ let foundNewline = false;
148
+ for (let i = searchEnd - 1; i >= searchStart; i--) {
149
+ if (data[i] === 10) {
150
+ end = i + 1;
151
+ foundNewline = true;
152
+ break;
153
+ }
154
+ }
155
+ if (!foundNewline) {
156
+ for (let i = end - 1; i >= searchStart; i--) {
157
+ if (data[i] === 44) {
158
+ end = i + 1;
159
+ break;
160
+ }
161
+ }
162
+ }
163
+ }
164
+ chunks.push(data.slice(start, end));
165
+ start = end;
166
+ }
167
+ return chunks;
168
+ }
169
+ function mergeResultsNodejs(results, format) {
170
+ if (results.length === 1) {
171
+ return results[0];
172
+ }
173
+ const totalLength = results.reduce((sum, chunk) => sum + chunk.length, 0);
174
+ const merged = new Uint8Array(totalLength);
175
+ let offset = 0;
176
+ switch (format) {
177
+ case "ndjson":
178
+ for (const chunk of results) {
179
+ merged.set(chunk, offset);
180
+ offset += chunk.length;
181
+ }
182
+ break;
183
+ case "csv":
184
+ const [first, ...rest] = results;
185
+ merged.set(first, offset);
186
+ offset += first.length;
187
+ for (const chunk of rest) {
188
+ let headerEnd = 0;
189
+ for (let i = 0; i < chunk.length; i++) {
190
+ if (chunk[i] === 10) {
191
+ headerEnd = i + 1;
192
+ break;
193
+ }
194
+ }
195
+ const dataWithoutHeader = chunk.slice(headerEnd);
196
+ merged.set(dataWithoutHeader, offset);
197
+ offset += dataWithoutHeader.length;
198
+ }
199
+ break;
200
+ case "json":
201
+ default:
202
+ for (const chunk of results) {
203
+ merged.set(chunk, offset);
204
+ offset += chunk.length;
205
+ }
206
+ break;
207
+ }
208
+ return merged.slice(0, offset);
209
+ }
210
+ export {
211
+ NodejsThreadPool,
212
+ chunkDataNodejs,
213
+ mergeResultsNodejs
214
+ };
215
+ //# sourceMappingURL=nodejs-thread-pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/nodejs-thread-pool.ts"],"sourcesContent":["// Node.js specific threading implementation using Worker Threads\r\n// This provides better performance than the browser web worker approach\r\n\r\nimport { Worker, isMainThread, parentPort, workerData } from 'worker_threads';\r\nimport { fileURLToPath } from 'url';\r\nimport { dirname, join } from 'path';\r\n\r\nconst __filename = fileURLToPath(import.meta.url);\r\nconst __dirname = dirname(__filename);\r\n\r\nexport interface NodejsThreadPoolConfig {\r\n maxWorkers: number;\r\n wasmPath: string;\r\n}\r\n\r\nexport interface WorkerTask {\r\n id: string;\r\n method: string;\r\n data: Uint8Array;\r\n options: any;\r\n}\r\n\r\nexport interface WorkerResult {\r\n id: string;\r\n result?: Uint8Array;\r\n error?: string;\r\n}\r\n\r\nexport class NodejsThreadPool {\r\n private workers: Worker[] = [];\r\n private pendingTasks = new Map<string, { resolve: Function; reject: Function }>();\r\n private nextTaskId = 0;\r\n private isInitialized = false;\r\n private roundRobinIndex = 0;\r\n\r\n constructor(private config: NodejsThreadPoolConfig) {}\r\n\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n\r\n // Create the worker script inline\r\n const workerScript = `\r\n import { parentPort, workerData } from 'worker_threads';\r\n import { createRequire } from 'node:module';\r\n \r\n const require = createRequire(import.meta.url);\r\n \r\n let wasmModule = null;\r\n \r\n async function initWasm() {\r\n if (!wasmModule) {\r\n // Import the Node.js WASM module\r\n wasmModule = require('${this.config.wasmPath}');\r\n wasmModule.init(false); // Initialize without debug logs in workers\r\n }\r\n return wasmModule;\r\n }\r\n \r\n parentPort.on('message', async (task) => {\r\n try {\r\n const { id, method, data, options } = task;\r\n \r\n if (!wasmModule) {\r\n await initWasm();\r\n }\r\n \r\n const converter = new wasmModule.Converter(false);\r\n \r\n // Configure converter based on options\r\n if (options.outputFormat) {\r\n converter.set_output_format(options.outputFormat);\r\n }\r\n if (options.inputFormat) {\r\n converter.set_input_format(options.inputFormat);\r\n }\r\n \r\n // Process the data\r\n const output = converter.push(data);\r\n const final = converter.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 parentPort.postMessage({ id, result });\r\n } catch (error) {\r\n parentPort.postMessage({ id, error: error.message });\r\n }\r\n });\r\n \r\n // Initialize WASM when worker starts\r\n initWasm().catch(console.error);\r\n `;\r\n\r\n // Write worker script to a temporary file\r\n const workerPath = join(__dirname, `worker-${Date.now()}.mjs`);\r\n await import('fs').then(fs => {\r\n fs.writeFileSync(workerPath, workerScript);\r\n });\r\n\r\n try {\r\n for (let i = 0; i < this.config.maxWorkers; i++) {\r\n const worker = new Worker(workerPath, { type: 'module' } as any);\r\n \r\n worker.on('message', (response: WorkerResult) => {\r\n this.handleWorkerMessage(response);\r\n });\r\n \r\n worker.on('error', (error) => {\r\n console.error('Worker error:', error);\r\n });\r\n \r\n this.workers.push(worker);\r\n }\r\n \r\n this.isInitialized = true;\r\n } finally {\r\n // Clean up the temporary worker file\r\n setTimeout(() => {\r\n import('fs').then(fs => {\r\n try {\r\n fs.unlinkSync(workerPath);\r\n } catch {}\r\n });\r\n }, 1000);\r\n }\r\n }\r\n\r\n private handleWorkerMessage(response: WorkerResult): void {\r\n const pending = this.pendingTasks.get(response.id);\r\n if (pending) {\r\n this.pendingTasks.delete(response.id);\r\n if (response.error) {\r\n pending.reject(new Error(response.error));\r\n } else {\r\n pending.resolve(response.result);\r\n }\r\n }\r\n }\r\n\r\n async processChunks(method: string, chunks: Uint8Array[], options: any): Promise<Uint8Array[]> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n\r\n const promises = chunks.map((chunk, index) => {\r\n const taskId = `${this.nextTaskId++}`;\r\n const workerIndex = this.roundRobinIndex++ % this.workers.length;\r\n \r\n return new Promise<Uint8Array>((resolve, reject) => {\r\n this.pendingTasks.set(taskId, { resolve, reject });\r\n \r\n const task: WorkerTask = {\r\n id: taskId,\r\n method,\r\n data: chunk,\r\n options\r\n };\r\n \r\n this.workers[workerIndex].postMessage(task);\r\n });\r\n });\r\n\r\n return Promise.all(promises);\r\n }\r\n\r\n destroy(): void {\r\n this.workers.forEach(worker => worker.terminate());\r\n this.workers = [];\r\n this.pendingTasks.clear();\r\n this.isInitialized = false;\r\n }\r\n}\r\n\r\n// Utility functions for chunking data at byte boundaries (optimized for Node.js)\r\nexport function chunkDataNodejs(data: Uint8Array, numChunks: number): Uint8Array[] {\r\n if (numChunks <= 1 || data.length < 1024) {\r\n return [data];\r\n }\r\n\r\n const chunkSize = Math.ceil(data.length / numChunks);\r\n const chunks: Uint8Array[] = [];\r\n \r\n let start = 0;\r\n while (start < data.length) {\r\n let end = Math.min(start + chunkSize, data.length);\r\n \r\n // For CSV/NDJSON, align to line boundaries (more aggressive search)\r\n if (end < data.length) {\r\n const searchStart = Math.max(start + chunkSize - 2048, start); // Search back up to 2KB\r\n const searchEnd = Math.min(end + 2048, data.length); // Search forward up to 2KB\r\n \r\n // Look for newline\r\n let foundNewline = false;\r\n for (let i = searchEnd - 1; i >= searchStart; i--) {\r\n if (data[i] === 0x0A) { // '\\n'\r\n end = i + 1;\r\n foundNewline = true;\r\n break;\r\n }\r\n }\r\n \r\n // If no newline found, search for comma (CSV field boundary)\r\n if (!foundNewline) {\r\n for (let i = end - 1; i >= searchStart; i--) {\r\n if (data[i] === 0x2C) { // ','\r\n end = i + 1;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n \r\n chunks.push(data.slice(start, end));\r\n start = end;\r\n }\r\n \r\n return chunks;\r\n}\r\n\r\n// Smart result merging optimized for Node.js Buffer operations\r\nexport function mergeResultsNodejs(results: Uint8Array[], format: string): Uint8Array {\r\n if (results.length === 1) {\r\n return results[0];\r\n }\r\n\r\n // Calculate total size for efficient allocation\r\n const totalLength = results.reduce((sum, chunk) => sum + chunk.length, 0);\r\n const merged = new Uint8Array(totalLength);\r\n \r\n let offset = 0;\r\n \r\n switch (format) {\r\n case 'ndjson':\r\n // Simple concatenation for NDJSON\r\n for (const chunk of results) {\r\n merged.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n break;\r\n \r\n case 'csv':\r\n // Merge CSV: keep header from first chunk only\r\n const [first, ...rest] = results;\r\n merged.set(first, offset);\r\n offset += first.length;\r\n \r\n for (const chunk of rest) {\r\n // Find first newline (skip header)\r\n let headerEnd = 0;\r\n for (let i = 0; i < chunk.length; i++) {\r\n if (chunk[i] === 0x0A) {\r\n headerEnd = i + 1;\r\n break;\r\n }\r\n }\r\n \r\n const dataWithoutHeader = chunk.slice(headerEnd);\r\n merged.set(dataWithoutHeader, offset);\r\n offset += dataWithoutHeader.length;\r\n }\r\n break;\r\n \r\n case 'json':\r\n default:\r\n // Default concatenation\r\n for (const chunk of results) {\r\n merged.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n break;\r\n }\r\n \r\n return merged.slice(0, offset);\r\n}"],"mappings":"AAGA,SAAS,cAAoD;AAC7D,SAAS,qBAAqB;AAC9B,SAAS,SAAS,YAAY;AAE9B,MAAM,aAAa,cAAc,YAAY,GAAG;AAChD,MAAM,YAAY,QAAQ,UAAU;AAoB7B,MAAM,iBAAiB;AAAA,EAO5B,YAAoB,QAAgC;AAAhC;AAAA,EAAiC;AAAA,EAN7C,UAAoB,CAAC;AAAA,EACrB,eAAe,oBAAI,IAAqD;AAAA,EACxE,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAI1B,MAAM,aAA4B;AAChC,QAAI,KAAK,cAAe;AAGxB,UAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kCAWS,KAAK,OAAO,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4ClD,UAAM,aAAa,KAAK,WAAW,UAAU,KAAK,IAAI,CAAC,MAAM;AAC7D,UAAM,OAAO,IAAI,EAAE,KAAK,QAAM;AAC5B,SAAG,cAAc,YAAY,YAAY;AAAA,IAC3C,CAAC;AAED,QAAI;AACF,eAAS,IAAI,GAAG,IAAI,KAAK,OAAO,YAAY,KAAK;AAC/C,cAAM,SAAS,IAAI,OAAO,YAAY,EAAE,MAAM,SAAS,CAAQ;AAE/D,eAAO,GAAG,WAAW,CAAC,aAA2B;AAC/C,eAAK,oBAAoB,QAAQ;AAAA,QACnC,CAAC;AAED,eAAO,GAAG,SAAS,CAAC,UAAU;AAC5B,kBAAQ,MAAM,iBAAiB,KAAK;AAAA,QACtC,CAAC;AAED,aAAK,QAAQ,KAAK,MAAM;AAAA,MAC1B;AAEA,WAAK,gBAAgB;AAAA,IACvB,UAAE;AAEA,iBAAW,MAAM;AACf,eAAO,IAAI,EAAE,KAAK,QAAM;AACtB,cAAI;AACF,eAAG,WAAW,UAAU;AAAA,UAC1B,QAAQ;AAAA,UAAC;AAAA,QACX,CAAC;AAAA,MACH,GAAG,GAAI;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,oBAAoB,UAA8B;AACxD,UAAM,UAAU,KAAK,aAAa,IAAI,SAAS,EAAE;AACjD,QAAI,SAAS;AACX,WAAK,aAAa,OAAO,SAAS,EAAE;AACpC,UAAI,SAAS,OAAO;AAClB,gBAAQ,OAAO,IAAI,MAAM,SAAS,KAAK,CAAC;AAAA,MAC1C,OAAO;AACL,gBAAQ,QAAQ,SAAS,MAAM;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,QAAgB,QAAsB,SAAqC;AAC7F,QAAI,CAAC,KAAK,eAAe;AACvB,YAAM,KAAK,WAAW;AAAA,IACxB;AAEA,UAAM,WAAW,OAAO,IAAI,CAAC,OAAO,UAAU;AAC5C,YAAM,SAAS,GAAG,KAAK,YAAY;AACnC,YAAM,cAAc,KAAK,oBAAoB,KAAK,QAAQ;AAE1D,aAAO,IAAI,QAAoB,CAAC,SAAS,WAAW;AAClD,aAAK,aAAa,IAAI,QAAQ,EAAE,SAAS,OAAO,CAAC;AAEjD,cAAM,OAAmB;AAAA,UACvB,IAAI;AAAA,UACJ;AAAA,UACA,MAAM;AAAA,UACN;AAAA,QACF;AAEA,aAAK,QAAQ,WAAW,EAAE,YAAY,IAAI;AAAA,MAC5C,CAAC;AAAA,IACH,CAAC;AAED,WAAO,QAAQ,IAAI,QAAQ;AAAA,EAC7B;AAAA,EAEA,UAAgB;AACd,SAAK,QAAQ,QAAQ,YAAU,OAAO,UAAU,CAAC;AACjD,SAAK,UAAU,CAAC;AAChB,SAAK,aAAa,MAAM;AACxB,SAAK,gBAAgB;AAAA,EACvB;AACF;AAGO,SAAS,gBAAgB,MAAkB,WAAiC;AACjF,MAAI,aAAa,KAAK,KAAK,SAAS,MAAM;AACxC,WAAO,CAAC,IAAI;AAAA,EACd;AAEA,QAAM,YAAY,KAAK,KAAK,KAAK,SAAS,SAAS;AACnD,QAAM,SAAuB,CAAC;AAE9B,MAAI,QAAQ;AACZ,SAAO,QAAQ,KAAK,QAAQ;AAC1B,QAAI,MAAM,KAAK,IAAI,QAAQ,WAAW,KAAK,MAAM;AAGjD,QAAI,MAAM,KAAK,QAAQ;AACrB,YAAM,cAAc,KAAK,IAAI,QAAQ,YAAY,MAAM,KAAK;AAC5D,YAAM,YAAY,KAAK,IAAI,MAAM,MAAM,KAAK,MAAM;AAGlD,UAAI,eAAe;AACnB,eAAS,IAAI,YAAY,GAAG,KAAK,aAAa,KAAK;AACjD,YAAI,KAAK,CAAC,MAAM,IAAM;AACpB,gBAAM,IAAI;AACV,yBAAe;AACf;AAAA,QACF;AAAA,MACF;AAGA,UAAI,CAAC,cAAc;AACjB,iBAAS,IAAI,MAAM,GAAG,KAAK,aAAa,KAAK;AAC3C,cAAI,KAAK,CAAC,MAAM,IAAM;AACpB,kBAAM,IAAI;AACV;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK,KAAK,MAAM,OAAO,GAAG,CAAC;AAClC,YAAQ;AAAA,EACV;AAEA,SAAO;AACT;AAGO,SAAS,mBAAmB,SAAuB,QAA4B;AACpF,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,QAAQ,CAAC;AAAA,EAClB;AAGA,QAAM,cAAc,QAAQ,OAAO,CAAC,KAAK,UAAU,MAAM,MAAM,QAAQ,CAAC;AACxE,QAAM,SAAS,IAAI,WAAW,WAAW;AAEzC,MAAI,SAAS;AAEb,UAAQ,QAAQ;AAAA,IACd,KAAK;AAEH,iBAAW,SAAS,SAAS;AAC3B,eAAO,IAAI,OAAO,MAAM;AACxB,kBAAU,MAAM;AAAA,MAClB;AACA;AAAA,IAEF,KAAK;AAEH,YAAM,CAAC,OAAO,GAAG,IAAI,IAAI;AACzB,aAAO,IAAI,OAAO,MAAM;AACxB,gBAAU,MAAM;AAEhB,iBAAW,SAAS,MAAM;AAExB,YAAI,YAAY;AAChB,iBAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAI,MAAM,CAAC,MAAM,IAAM;AACrB,wBAAY,IAAI;AAChB;AAAA,UACF;AAAA,QACF;AAEA,cAAM,oBAAoB,MAAM,MAAM,SAAS;AAC/C,eAAO,IAAI,mBAAmB,MAAM;AACpC,kBAAU,kBAAkB;AAAA,MAC9B;AACA;AAAA,IAEF,KAAK;AAAA,IACL;AAEE,iBAAW,SAAS,SAAS;AAC3B,eAAO,IAAI,OAAO,MAAM;AACxB,kBAAU,MAAM;AAAA,MAClB;AACA;AAAA,EACJ;AAEA,SAAO,OAAO,MAAM,GAAG,MAAM;AAC/B;","names":[]}
@@ -0,0 +1,31 @@
1
+ interface ThreadPoolConfig {
2
+ maxWorkers: number;
3
+ wasmPath: string;
4
+ }
5
+ interface WorkerMessage {
6
+ id: string;
7
+ method: string;
8
+ data: string;
9
+ options: any;
10
+ }
11
+ interface WorkerResponse {
12
+ id: string;
13
+ result?: string;
14
+ error?: string;
15
+ }
16
+ declare class WasmThreadPool {
17
+ private config;
18
+ private workers;
19
+ private pendingTasks;
20
+ private nextTaskId;
21
+ private isInitialized;
22
+ constructor(config: ThreadPoolConfig);
23
+ initialize(): Promise<void>;
24
+ private handleWorkerMessage;
25
+ processChunks(method: string, chunks: string[], options: any): Promise<string[]>;
26
+ destroy(): void;
27
+ }
28
+ declare function chunkData(data: string, numChunks: number): string[];
29
+ declare function mergeResults(results: string[], format: string): string;
30
+
31
+ export { type ThreadPoolConfig, WasmThreadPool, type WorkerMessage, type WorkerResponse, chunkData, mergeResults };
@@ -0,0 +1,154 @@
1
+ class WasmThreadPool {
2
+ constructor(config) {
3
+ this.config = config;
4
+ }
5
+ workers = [];
6
+ pendingTasks = /* @__PURE__ */ new Map();
7
+ nextTaskId = 0;
8
+ isInitialized = false;
9
+ async initialize() {
10
+ if (this.isInitialized) return;
11
+ const workerCode = `
12
+ let wasmModule = null;
13
+
14
+ async function initWasm() {
15
+ if (!wasmModule) {
16
+ const wasmImport = await import('${this.config.wasmPath}');
17
+ wasmModule = wasmImport;
18
+ }
19
+ return wasmModule;
20
+ }
21
+
22
+ self.onmessage = async function(e) {
23
+ try {
24
+ const { id, method, data, options } = e.data;
25
+
26
+ if (!wasmModule) {
27
+ await initWasm();
28
+ }
29
+
30
+ let result;
31
+ switch (method) {
32
+ case 'parseCSV':
33
+ result = wasmModule.csv_to_ndjson(data, options);
34
+ break;
35
+ case 'parseJSON':
36
+ result = wasmModule.json_to_csv(data, options);
37
+ break;
38
+ case 'parseNDJSON':
39
+ result = wasmModule.ndjson_to_csv(data, options);
40
+ break;
41
+ case 'parseXML':
42
+ result = wasmModule.xml_to_json(data, options);
43
+ break;
44
+ default:
45
+ throw new Error('Unknown method: ' + method);
46
+ }
47
+
48
+ self.postMessage({ id, result });
49
+ } catch (error) {
50
+ self.postMessage({ id, error: error.message });
51
+ }
52
+ };
53
+ `;
54
+ const workerBlob = new Blob([workerCode], { type: "application/javascript" });
55
+ const workerUrl = URL.createObjectURL(workerBlob);
56
+ for (let i = 0; i < this.config.maxWorkers; i++) {
57
+ const worker = new Worker(workerUrl, { type: "module" });
58
+ worker.onmessage = (e) => {
59
+ this.handleWorkerMessage(e.data);
60
+ };
61
+ this.workers.push(worker);
62
+ }
63
+ URL.revokeObjectURL(workerUrl);
64
+ this.isInitialized = true;
65
+ }
66
+ handleWorkerMessage(response) {
67
+ const pending = this.pendingTasks.get(response.id);
68
+ if (pending) {
69
+ this.pendingTasks.delete(response.id);
70
+ if (response.error) {
71
+ pending.reject(new Error(response.error));
72
+ } else {
73
+ pending.resolve(response.result);
74
+ }
75
+ }
76
+ }
77
+ async processChunks(method, chunks, options) {
78
+ if (!this.isInitialized) {
79
+ await this.initialize();
80
+ }
81
+ const promises = chunks.map((chunk, index) => {
82
+ const taskId = `${this.nextTaskId++}`;
83
+ const workerIndex = index % this.workers.length;
84
+ return new Promise((resolve, reject) => {
85
+ this.pendingTasks.set(taskId, { resolve, reject });
86
+ const message = {
87
+ id: taskId,
88
+ method,
89
+ data: chunk,
90
+ options
91
+ };
92
+ this.workers[workerIndex].postMessage(message);
93
+ });
94
+ });
95
+ return Promise.all(promises);
96
+ }
97
+ destroy() {
98
+ this.workers.forEach((worker) => worker.terminate());
99
+ this.workers = [];
100
+ this.pendingTasks.clear();
101
+ this.isInitialized = false;
102
+ }
103
+ }
104
+ function chunkData(data, numChunks) {
105
+ if (numChunks <= 1 || data.length < 1e3) {
106
+ return [data];
107
+ }
108
+ const chunkSize = Math.ceil(data.length / numChunks);
109
+ const chunks = [];
110
+ let start = 0;
111
+ while (start < data.length) {
112
+ let end = Math.min(start + chunkSize, data.length);
113
+ if (end < data.length) {
114
+ const nextNewline = data.indexOf("\n", end);
115
+ if (nextNewline !== -1 && nextNewline < end + 500) {
116
+ end = nextNewline + 1;
117
+ }
118
+ }
119
+ chunks.push(data.slice(start, end));
120
+ start = end;
121
+ }
122
+ return chunks;
123
+ }
124
+ function mergeResults(results, format) {
125
+ if (results.length === 1) {
126
+ return results[0];
127
+ }
128
+ switch (format) {
129
+ case "ndjson":
130
+ return results.join("");
131
+ case "csv":
132
+ const [first, ...rest] = results;
133
+ const restWithoutHeaders = rest.map((chunk) => {
134
+ const lines = chunk.split("\n");
135
+ return lines.slice(1).join("\n");
136
+ });
137
+ return [first, ...restWithoutHeaders].join("");
138
+ case "json":
139
+ try {
140
+ const arrays = results.map((r) => JSON.parse(r));
141
+ return JSON.stringify(arrays.flat());
142
+ } catch {
143
+ return results.join("\n");
144
+ }
145
+ default:
146
+ return results.join("");
147
+ }
148
+ }
149
+ export {
150
+ WasmThreadPool,
151
+ chunkData,
152
+ mergeResults
153
+ };
154
+ //# sourceMappingURL=thread-pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/thread-pool.ts"],"sourcesContent":["// Custom WASM threading implementation using web workers\r\n// This bypasses wasm-bindgen-rayon issues by implementing parallelism at the JS level\r\n\r\nexport interface ThreadPoolConfig {\r\n maxWorkers: number;\r\n wasmPath: string;\r\n}\r\n\r\nexport interface WorkerMessage {\r\n id: string;\r\n method: string;\r\n data: string;\r\n options: any;\r\n}\r\n\r\nexport interface WorkerResponse {\r\n id: string;\r\n result?: string;\r\n error?: string;\r\n}\r\n\r\nexport class WasmThreadPool {\r\n private workers: Worker[] = [];\r\n private pendingTasks = new Map<string, { resolve: Function; reject: Function }>();\r\n private nextTaskId = 0;\r\n private isInitialized = false;\r\n\r\n constructor(private config: ThreadPoolConfig) {}\r\n\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n\r\n // Create worker code inline to avoid external file dependencies\r\n const workerCode = `\r\n let wasmModule = null;\r\n \r\n async function initWasm() {\r\n if (!wasmModule) {\r\n const wasmImport = await import('${this.config.wasmPath}');\r\n wasmModule = wasmImport;\r\n }\r\n return wasmModule;\r\n }\r\n \r\n self.onmessage = async function(e) {\r\n try {\r\n const { id, method, data, options } = e.data;\r\n \r\n if (!wasmModule) {\r\n await initWasm();\r\n }\r\n \r\n let result;\r\n switch (method) {\r\n case 'parseCSV':\r\n result = wasmModule.csv_to_ndjson(data, options);\r\n break;\r\n case 'parseJSON':\r\n result = wasmModule.json_to_csv(data, options);\r\n break;\r\n case 'parseNDJSON':\r\n result = wasmModule.ndjson_to_csv(data, options);\r\n break;\r\n case 'parseXML':\r\n result = wasmModule.xml_to_json(data, options);\r\n break;\r\n default:\r\n throw new Error('Unknown method: ' + method);\r\n }\r\n \r\n self.postMessage({ id, result });\r\n } catch (error) {\r\n self.postMessage({ id, error: error.message });\r\n }\r\n };\r\n `;\r\n\r\n const workerBlob = new Blob([workerCode], { type: 'application/javascript' });\r\n const workerUrl = URL.createObjectURL(workerBlob);\r\n\r\n for (let i = 0; i < this.config.maxWorkers; i++) {\r\n const worker = new Worker(workerUrl, { type: 'module' });\r\n worker.onmessage = (e: MessageEvent<WorkerResponse>) => {\r\n this.handleWorkerMessage(e.data);\r\n };\r\n this.workers.push(worker);\r\n }\r\n\r\n URL.revokeObjectURL(workerUrl);\r\n this.isInitialized = true;\r\n }\r\n\r\n private handleWorkerMessage(response: WorkerResponse): void {\r\n const pending = this.pendingTasks.get(response.id);\r\n if (pending) {\r\n this.pendingTasks.delete(response.id);\r\n if (response.error) {\r\n pending.reject(new Error(response.error));\r\n } else {\r\n pending.resolve(response.result);\r\n }\r\n }\r\n }\r\n\r\n async processChunks(method: string, chunks: string[], options: any): Promise<string[]> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n\r\n const promises = chunks.map((chunk, index) => {\r\n const taskId = `${this.nextTaskId++}`;\r\n const workerIndex = index % this.workers.length;\r\n \r\n return new Promise<string>((resolve, reject) => {\r\n this.pendingTasks.set(taskId, { resolve, reject });\r\n \r\n const message: WorkerMessage = {\r\n id: taskId,\r\n method,\r\n data: chunk,\r\n options\r\n };\r\n \r\n this.workers[workerIndex].postMessage(message);\r\n });\r\n });\r\n\r\n return Promise.all(promises);\r\n }\r\n\r\n destroy(): void {\r\n this.workers.forEach(worker => worker.terminate());\r\n this.workers = [];\r\n this.pendingTasks.clear();\r\n this.isInitialized = false;\r\n }\r\n}\r\n\r\n// Utility functions for chunking data intelligently\r\nexport function chunkData(data: string, numChunks: number): string[] {\r\n if (numChunks <= 1 || data.length < 1000) {\r\n return [data];\r\n }\r\n\r\n const chunkSize = Math.ceil(data.length / numChunks);\r\n const chunks: string[] = [];\r\n \r\n let start = 0;\r\n while (start < data.length) {\r\n let end = Math.min(start + chunkSize, data.length);\r\n \r\n // For CSV/NDJSON, align to line boundaries\r\n if (end < data.length) {\r\n const nextNewline = data.indexOf('\\n', end);\r\n if (nextNewline !== -1 && nextNewline < end + 500) {\r\n end = nextNewline + 1;\r\n }\r\n }\r\n \r\n chunks.push(data.slice(start, end));\r\n start = end;\r\n }\r\n \r\n return chunks;\r\n}\r\n\r\n// Smart chunk merging that preserves data structure\r\nexport function mergeResults(results: string[], format: string): string {\r\n if (results.length === 1) {\r\n return results[0];\r\n }\r\n\r\n switch (format) {\r\n case 'ndjson':\r\n return results.join('');\r\n case 'csv':\r\n // Merge CSV: keep header from first chunk only\r\n const [first, ...rest] = results;\r\n const restWithoutHeaders = rest.map(chunk => {\r\n const lines = chunk.split('\\n');\r\n return lines.slice(1).join('\\n');\r\n });\r\n return [first, ...restWithoutHeaders].join('');\r\n case 'json':\r\n // Merge JSON arrays\r\n try {\r\n const arrays = results.map(r => JSON.parse(r));\r\n return JSON.stringify(arrays.flat());\r\n } catch {\r\n return results.join('\\n');\r\n }\r\n default:\r\n return results.join('');\r\n }\r\n}"],"mappings":"AAqBO,MAAM,eAAe;AAAA,EAM1B,YAAoB,QAA0B;AAA1B;AAAA,EAA2B;AAAA,EALvC,UAAoB,CAAC;AAAA,EACrB,eAAe,oBAAI,IAAqD;AAAA,EACxE,aAAa;AAAA,EACb,gBAAgB;AAAA,EAIxB,MAAM,aAA4B;AAChC,QAAI,KAAK,cAAe;AAGxB,UAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,6CAKsB,KAAK,OAAO,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuC7D,UAAM,aAAa,IAAI,KAAK,CAAC,UAAU,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAC5E,UAAM,YAAY,IAAI,gBAAgB,UAAU;AAEhD,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,YAAY,KAAK;AAC/C,YAAM,SAAS,IAAI,OAAO,WAAW,EAAE,MAAM,SAAS,CAAC;AACvD,aAAO,YAAY,CAAC,MAAoC;AACtD,aAAK,oBAAoB,EAAE,IAAI;AAAA,MACjC;AACA,WAAK,QAAQ,KAAK,MAAM;AAAA,IAC1B;AAEA,QAAI,gBAAgB,SAAS;AAC7B,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEQ,oBAAoB,UAAgC;AAC1D,UAAM,UAAU,KAAK,aAAa,IAAI,SAAS,EAAE;AACjD,QAAI,SAAS;AACX,WAAK,aAAa,OAAO,SAAS,EAAE;AACpC,UAAI,SAAS,OAAO;AAClB,gBAAQ,OAAO,IAAI,MAAM,SAAS,KAAK,CAAC;AAAA,MAC1C,OAAO;AACL,gBAAQ,QAAQ,SAAS,MAAM;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,QAAgB,QAAkB,SAAiC;AACrF,QAAI,CAAC,KAAK,eAAe;AACvB,YAAM,KAAK,WAAW;AAAA,IACxB;AAEA,UAAM,WAAW,OAAO,IAAI,CAAC,OAAO,UAAU;AAC5C,YAAM,SAAS,GAAG,KAAK,YAAY;AACnC,YAAM,cAAc,QAAQ,KAAK,QAAQ;AAEzC,aAAO,IAAI,QAAgB,CAAC,SAAS,WAAW;AAC9C,aAAK,aAAa,IAAI,QAAQ,EAAE,SAAS,OAAO,CAAC;AAEjD,cAAM,UAAyB;AAAA,UAC7B,IAAI;AAAA,UACJ;AAAA,UACA,MAAM;AAAA,UACN;AAAA,QACF;AAEA,aAAK,QAAQ,WAAW,EAAE,YAAY,OAAO;AAAA,MAC/C,CAAC;AAAA,IACH,CAAC;AAED,WAAO,QAAQ,IAAI,QAAQ;AAAA,EAC7B;AAAA,EAEA,UAAgB;AACd,SAAK,QAAQ,QAAQ,YAAU,OAAO,UAAU,CAAC;AACjD,SAAK,UAAU,CAAC;AAChB,SAAK,aAAa,MAAM;AACxB,SAAK,gBAAgB;AAAA,EACvB;AACF;AAGO,SAAS,UAAU,MAAc,WAA6B;AACnE,MAAI,aAAa,KAAK,KAAK,SAAS,KAAM;AACxC,WAAO,CAAC,IAAI;AAAA,EACd;AAEA,QAAM,YAAY,KAAK,KAAK,KAAK,SAAS,SAAS;AACnD,QAAM,SAAmB,CAAC;AAE1B,MAAI,QAAQ;AACZ,SAAO,QAAQ,KAAK,QAAQ;AAC1B,QAAI,MAAM,KAAK,IAAI,QAAQ,WAAW,KAAK,MAAM;AAGjD,QAAI,MAAM,KAAK,QAAQ;AACrB,YAAM,cAAc,KAAK,QAAQ,MAAM,GAAG;AAC1C,UAAI,gBAAgB,MAAM,cAAc,MAAM,KAAK;AACjD,cAAM,cAAc;AAAA,MACtB;AAAA,IACF;AAEA,WAAO,KAAK,KAAK,MAAM,OAAO,GAAG,CAAC;AAClC,YAAQ;AAAA,EACV;AAEA,SAAO;AACT;AAGO,SAAS,aAAa,SAAmB,QAAwB;AACtE,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,QAAQ,CAAC;AAAA,EAClB;AAEA,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,QAAQ,KAAK,EAAE;AAAA,IACxB,KAAK;AAEH,YAAM,CAAC,OAAO,GAAG,IAAI,IAAI;AACzB,YAAM,qBAAqB,KAAK,IAAI,WAAS;AAC3C,cAAM,QAAQ,MAAM,MAAM,IAAI;AAC9B,eAAO,MAAM,MAAM,CAAC,EAAE,KAAK,IAAI;AAAA,MACjC,CAAC;AACD,aAAO,CAAC,OAAO,GAAG,kBAAkB,EAAE,KAAK,EAAE;AAAA,IAC/C,KAAK;AAEH,UAAI;AACF,cAAM,SAAS,QAAQ,IAAI,OAAK,KAAK,MAAM,CAAC,CAAC;AAC7C,eAAO,KAAK,UAAU,OAAO,KAAK,CAAC;AAAA,MACrC,QAAQ;AACN,eAAO,QAAQ,KAAK,IAAI;AAAA,MAC1B;AAAA,IACF;AACE,aAAO,QAAQ,KAAK,EAAE;AAAA,EAC1B;AACF;","names":[]}
@@ -0,0 +1,712 @@
1
+
2
+ let imports = {};
3
+ imports['__wbindgen_placeholder__'] = module.exports;
4
+ let wasm;
5
+ const { TextDecoder, TextEncoder } = require(`util`);
6
+
7
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
8
+
9
+ cachedTextDecoder.decode();
10
+
11
+ let cachedUint8ArrayMemory0 = null;
12
+
13
+ function getUint8ArrayMemory0() {
14
+ if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
15
+ cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
16
+ }
17
+ return cachedUint8ArrayMemory0;
18
+ }
19
+
20
+ function getStringFromWasm0(ptr, len) {
21
+ ptr = ptr >>> 0;
22
+ return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
23
+ }
24
+
25
+ function addToExternrefTable0(obj) {
26
+ const idx = wasm.__externref_table_alloc();
27
+ wasm.__wbindgen_export_3.set(idx, obj);
28
+ return idx;
29
+ }
30
+
31
+ function handleError(f, args) {
32
+ try {
33
+ return f.apply(this, args);
34
+ } catch (e) {
35
+ const idx = addToExternrefTable0(e);
36
+ wasm.__wbindgen_exn_store(idx);
37
+ }
38
+ }
39
+
40
+ let WASM_VECTOR_LEN = 0;
41
+
42
+ let cachedTextEncoder = new TextEncoder('utf-8');
43
+
44
+ const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
45
+ ? function (arg, view) {
46
+ return cachedTextEncoder.encodeInto(arg, view);
47
+ }
48
+ : function (arg, view) {
49
+ const buf = cachedTextEncoder.encode(arg);
50
+ view.set(buf);
51
+ return {
52
+ read: arg.length,
53
+ written: buf.length
54
+ };
55
+ });
56
+
57
+ function passStringToWasm0(arg, malloc, realloc) {
58
+
59
+ if (realloc === undefined) {
60
+ const buf = cachedTextEncoder.encode(arg);
61
+ const ptr = malloc(buf.length, 1) >>> 0;
62
+ getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
63
+ WASM_VECTOR_LEN = buf.length;
64
+ return ptr;
65
+ }
66
+
67
+ let len = arg.length;
68
+ let ptr = malloc(len, 1) >>> 0;
69
+
70
+ const mem = getUint8ArrayMemory0();
71
+
72
+ let offset = 0;
73
+
74
+ for (; offset < len; offset++) {
75
+ const code = arg.charCodeAt(offset);
76
+ if (code > 0x7F) break;
77
+ mem[ptr + offset] = code;
78
+ }
79
+
80
+ if (offset !== len) {
81
+ if (offset !== 0) {
82
+ arg = arg.slice(offset);
83
+ }
84
+ ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
85
+ const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
86
+ const ret = encodeString(arg, view);
87
+
88
+ offset += ret.written;
89
+ ptr = realloc(ptr, len, offset, 1) >>> 0;
90
+ }
91
+
92
+ WASM_VECTOR_LEN = offset;
93
+ return ptr;
94
+ }
95
+
96
+ let cachedDataViewMemory0 = null;
97
+
98
+ function getDataViewMemory0() {
99
+ if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
100
+ cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
101
+ }
102
+ return cachedDataViewMemory0;
103
+ }
104
+
105
+ function debugString(val) {
106
+ // primitive types
107
+ const type = typeof val;
108
+ if (type == 'number' || type == 'boolean' || val == null) {
109
+ return `${val}`;
110
+ }
111
+ if (type == 'string') {
112
+ return `"${val}"`;
113
+ }
114
+ if (type == 'symbol') {
115
+ const description = val.description;
116
+ if (description == null) {
117
+ return 'Symbol';
118
+ } else {
119
+ return `Symbol(${description})`;
120
+ }
121
+ }
122
+ if (type == 'function') {
123
+ const name = val.name;
124
+ if (typeof name == 'string' && name.length > 0) {
125
+ return `Function(${name})`;
126
+ } else {
127
+ return 'Function';
128
+ }
129
+ }
130
+ // objects
131
+ if (Array.isArray(val)) {
132
+ const length = val.length;
133
+ let debug = '[';
134
+ if (length > 0) {
135
+ debug += debugString(val[0]);
136
+ }
137
+ for(let i = 1; i < length; i++) {
138
+ debug += ', ' + debugString(val[i]);
139
+ }
140
+ debug += ']';
141
+ return debug;
142
+ }
143
+ // Test for built-in
144
+ const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
145
+ let className;
146
+ if (builtInMatches && builtInMatches.length > 1) {
147
+ className = builtInMatches[1];
148
+ } else {
149
+ // Failed to match the standard '[object ClassName]'
150
+ return toString.call(val);
151
+ }
152
+ if (className == 'Object') {
153
+ // we're a user defined class or Object
154
+ // JSON.stringify avoids problems with cycles, and is generally much
155
+ // easier than looping through ownProperties of `val`.
156
+ try {
157
+ return 'Object(' + JSON.stringify(val) + ')';
158
+ } catch (_) {
159
+ return 'Object';
160
+ }
161
+ }
162
+ // errors
163
+ if (val instanceof Error) {
164
+ return `${val.name}: ${val.message}\n${val.stack}`;
165
+ }
166
+ // TODO we could test for more things here, like `Set`s and `Map`s.
167
+ return className;
168
+ }
169
+
170
+ function isLikeNone(x) {
171
+ return x === undefined || x === null;
172
+ }
173
+ /**
174
+ * Check if threading is enabled in this build.
175
+ * @returns {boolean}
176
+ */
177
+ module.exports.getThreadingEnabled = function() {
178
+ const ret = wasm.getSimdEnabled();
179
+ return ret !== 0;
180
+ };
181
+
182
+ function passArray8ToWasm0(arg, malloc) {
183
+ const ptr = malloc(arg.length * 1, 1) >>> 0;
184
+ getUint8ArrayMemory0().set(arg, ptr / 1);
185
+ WASM_VECTOR_LEN = arg.length;
186
+ return ptr;
187
+ }
188
+ /**
189
+ * Detect XML elements from a sample of bytes.
190
+ * @param {Uint8Array} sample
191
+ * @returns {any}
192
+ */
193
+ module.exports.detectXmlElements = function(sample) {
194
+ const ptr0 = passArray8ToWasm0(sample, wasm.__wbindgen_malloc);
195
+ const len0 = WASM_VECTOR_LEN;
196
+ const ret = wasm.detectXmlElements(ptr0, len0);
197
+ return ret;
198
+ };
199
+
200
+ /**
201
+ * Detect CSV fields and delimiter from a sample of bytes.
202
+ * @param {Uint8Array} sample
203
+ * @returns {any}
204
+ */
205
+ module.exports.detectCsvFields = function(sample) {
206
+ const ptr0 = passArray8ToWasm0(sample, wasm.__wbindgen_malloc);
207
+ const len0 = WASM_VECTOR_LEN;
208
+ const ret = wasm.detectCsvFields(ptr0, len0);
209
+ return ret;
210
+ };
211
+
212
+ /**
213
+ * @param {boolean} debug_enabled
214
+ */
215
+ module.exports.init = function(debug_enabled) {
216
+ wasm.init(debug_enabled);
217
+ };
218
+
219
+ /**
220
+ * Check if SIMD is enabled in this build.
221
+ * @returns {boolean}
222
+ */
223
+ module.exports.getSimdEnabled = function() {
224
+ const ret = wasm.getSimdEnabled();
225
+ return ret !== 0;
226
+ };
227
+
228
+ /**
229
+ * @returns {any}
230
+ */
231
+ module.exports.get_threading_support_info = function() {
232
+ const ret = wasm.get_threading_support_info();
233
+ return ret;
234
+ };
235
+
236
+ /**
237
+ * Detect the input format from a sample of bytes.
238
+ * @param {Uint8Array} sample
239
+ * @returns {string | undefined}
240
+ */
241
+ module.exports.detectFormat = function(sample) {
242
+ const ptr0 = passArray8ToWasm0(sample, wasm.__wbindgen_malloc);
243
+ const len0 = WASM_VECTOR_LEN;
244
+ const ret = wasm.detectFormat(ptr0, len0);
245
+ let v2;
246
+ if (ret[0] !== 0) {
247
+ v2 = getStringFromWasm0(ret[0], ret[1]).slice();
248
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
249
+ }
250
+ return v2;
251
+ };
252
+
253
+ function takeFromExternrefTable0(idx) {
254
+ const value = wasm.__wbindgen_export_3.get(idx);
255
+ wasm.__externref_table_dealloc(idx);
256
+ return value;
257
+ }
258
+
259
+ function getArrayU8FromWasm0(ptr, len) {
260
+ ptr = ptr >>> 0;
261
+ return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
262
+ }
263
+
264
+ const ConverterFinalization = (typeof FinalizationRegistry === 'undefined')
265
+ ? { register: () => {}, unregister: () => {} }
266
+ : new FinalizationRegistry(ptr => wasm.__wbg_converter_free(ptr >>> 0, 1));
267
+ /**
268
+ * A streaming converter state machine.
269
+ * Converts between CSV, NDJSON, JSON, and XML formats with high performance.
270
+ */
271
+ class Converter {
272
+
273
+ static __wrap(ptr) {
274
+ ptr = ptr >>> 0;
275
+ const obj = Object.create(Converter.prototype);
276
+ obj.__wbg_ptr = ptr;
277
+ ConverterFinalization.register(obj, obj.__wbg_ptr, obj);
278
+ return obj;
279
+ }
280
+
281
+ __destroy_into_raw() {
282
+ const ptr = this.__wbg_ptr;
283
+ this.__wbg_ptr = 0;
284
+ ConverterFinalization.unregister(this);
285
+ return ptr;
286
+ }
287
+
288
+ free() {
289
+ const ptr = this.__destroy_into_raw();
290
+ wasm.__wbg_converter_free(ptr, 0);
291
+ }
292
+ /**
293
+ * Create a new converter with specific configuration
294
+ * @param {boolean} debug
295
+ * @param {string} input_format
296
+ * @param {string} output_format
297
+ * @param {number} chunk_target_bytes
298
+ * @param {boolean} enable_stats
299
+ * @param {any} csv_config
300
+ * @param {any} xml_config
301
+ * @returns {Converter}
302
+ */
303
+ static withConfig(debug, input_format, output_format, chunk_target_bytes, enable_stats, csv_config, xml_config) {
304
+ const ptr0 = passStringToWasm0(input_format, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
305
+ const len0 = WASM_VECTOR_LEN;
306
+ const ptr1 = passStringToWasm0(output_format, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
307
+ const len1 = WASM_VECTOR_LEN;
308
+ const ret = wasm.converter_withConfig(debug, ptr0, len0, ptr1, len1, chunk_target_bytes, enable_stats, csv_config, xml_config);
309
+ if (ret[2]) {
310
+ throw takeFromExternrefTable0(ret[1]);
311
+ }
312
+ return Converter.__wrap(ret[0]);
313
+ }
314
+ /**
315
+ * @param {boolean} debug
316
+ */
317
+ constructor(debug) {
318
+ const ret = wasm.converter_new(debug);
319
+ this.__wbg_ptr = ret >>> 0;
320
+ ConverterFinalization.register(this, this.__wbg_ptr, this);
321
+ return this;
322
+ }
323
+ /**
324
+ * Push a chunk of bytes. Returns converted output bytes for that chunk.
325
+ * @param {Uint8Array} chunk
326
+ * @returns {Uint8Array}
327
+ */
328
+ push(chunk) {
329
+ const ptr0 = passArray8ToWasm0(chunk, wasm.__wbindgen_malloc);
330
+ const len0 = WASM_VECTOR_LEN;
331
+ const ret = wasm.converter_push(this.__wbg_ptr, ptr0, len0);
332
+ if (ret[3]) {
333
+ throw takeFromExternrefTable0(ret[2]);
334
+ }
335
+ var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
336
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
337
+ return v2;
338
+ }
339
+ /**
340
+ * Finish the stream and return any remaining buffered output.
341
+ * @returns {Uint8Array}
342
+ */
343
+ finish() {
344
+ const ret = wasm.converter_finish(this.__wbg_ptr);
345
+ if (ret[3]) {
346
+ throw takeFromExternrefTable0(ret[2]);
347
+ }
348
+ var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
349
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
350
+ return v1;
351
+ }
352
+ /**
353
+ * Get performance statistics
354
+ * @returns {Stats}
355
+ */
356
+ getStats() {
357
+ const ret = wasm.converter_getStats(this.__wbg_ptr);
358
+ return Stats.__wrap(ret);
359
+ }
360
+ }
361
+ module.exports.Converter = Converter;
362
+
363
+ const StatsFinalization = (typeof FinalizationRegistry === 'undefined')
364
+ ? { register: () => {}, unregister: () => {} }
365
+ : new FinalizationRegistry(ptr => wasm.__wbg_stats_free(ptr >>> 0, 1));
366
+ /**
367
+ * Performance statistics for the converter
368
+ */
369
+ class Stats {
370
+
371
+ static __wrap(ptr) {
372
+ ptr = ptr >>> 0;
373
+ const obj = Object.create(Stats.prototype);
374
+ obj.__wbg_ptr = ptr;
375
+ StatsFinalization.register(obj, obj.__wbg_ptr, obj);
376
+ return obj;
377
+ }
378
+
379
+ __destroy_into_raw() {
380
+ const ptr = this.__wbg_ptr;
381
+ this.__wbg_ptr = 0;
382
+ StatsFinalization.unregister(this);
383
+ return ptr;
384
+ }
385
+
386
+ free() {
387
+ const ptr = this.__destroy_into_raw();
388
+ wasm.__wbg_stats_free(ptr, 0);
389
+ }
390
+ /**
391
+ * @returns {number}
392
+ */
393
+ get parse_time_ms() {
394
+ const ret = wasm.stats_parse_time_ms(this.__wbg_ptr);
395
+ return ret;
396
+ }
397
+ /**
398
+ * @returns {number}
399
+ */
400
+ get write_time_ms() {
401
+ const ret = wasm.stats_write_time_ms(this.__wbg_ptr);
402
+ return ret;
403
+ }
404
+ /**
405
+ * @returns {number}
406
+ */
407
+ get max_buffer_size() {
408
+ const ret = wasm.stats_max_buffer_size(this.__wbg_ptr);
409
+ return ret >>> 0;
410
+ }
411
+ /**
412
+ * @returns {number}
413
+ */
414
+ get records_processed() {
415
+ const ret = wasm.stats_records_processed(this.__wbg_ptr);
416
+ return ret;
417
+ }
418
+ /**
419
+ * @returns {number}
420
+ */
421
+ get transform_time_ms() {
422
+ const ret = wasm.stats_transform_time_ms(this.__wbg_ptr);
423
+ return ret;
424
+ }
425
+ /**
426
+ * @returns {number}
427
+ */
428
+ get current_partial_size() {
429
+ const ret = wasm.stats_current_partial_size(this.__wbg_ptr);
430
+ return ret >>> 0;
431
+ }
432
+ /**
433
+ * @returns {number}
434
+ */
435
+ get throughput_mb_per_sec() {
436
+ const ret = wasm.stats_throughput_mb_per_sec(this.__wbg_ptr);
437
+ return ret;
438
+ }
439
+ /**
440
+ * @returns {number}
441
+ */
442
+ get bytes_in() {
443
+ const ret = wasm.stats_bytes_in(this.__wbg_ptr);
444
+ return ret;
445
+ }
446
+ /**
447
+ * @returns {number}
448
+ */
449
+ get bytes_out() {
450
+ const ret = wasm.stats_bytes_out(this.__wbg_ptr);
451
+ return ret;
452
+ }
453
+ /**
454
+ * @returns {number}
455
+ */
456
+ get chunks_in() {
457
+ const ret = wasm.stats_chunks_in(this.__wbg_ptr);
458
+ return ret;
459
+ }
460
+ }
461
+ module.exports.Stats = Stats;
462
+
463
+ module.exports.__wbg_buffer_61b7ce01341d7f88 = function(arg0) {
464
+ const ret = arg0.buffer;
465
+ return ret;
466
+ };
467
+
468
+ module.exports.__wbg_debug_156ca727dbc3150f = function(arg0) {
469
+ console.debug(arg0);
470
+ };
471
+
472
+ module.exports.__wbg_error_7534b8e9a36f1ab4 = function(arg0, arg1) {
473
+ let deferred0_0;
474
+ let deferred0_1;
475
+ try {
476
+ deferred0_0 = arg0;
477
+ deferred0_1 = arg1;
478
+ console.error(getStringFromWasm0(arg0, arg1));
479
+ } finally {
480
+ wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
481
+ }
482
+ };
483
+
484
+ module.exports.__wbg_error_fab41a42d22bf2bc = function(arg0) {
485
+ console.error(arg0);
486
+ };
487
+
488
+ module.exports.__wbg_getwithrefkey_1dc361bd10053bfe = function(arg0, arg1) {
489
+ const ret = arg0[arg1];
490
+ return ret;
491
+ };
492
+
493
+ module.exports.__wbg_info_c3044c86ae29faab = function(arg0) {
494
+ console.info(arg0);
495
+ };
496
+
497
+ module.exports.__wbg_instanceof_ArrayBuffer_670ddde44cdb2602 = function(arg0) {
498
+ let result;
499
+ try {
500
+ result = arg0 instanceof ArrayBuffer;
501
+ } catch (_) {
502
+ result = false;
503
+ }
504
+ const ret = result;
505
+ return ret;
506
+ };
507
+
508
+ module.exports.__wbg_instanceof_Uint8Array_28af5bc19d6acad8 = function(arg0) {
509
+ let result;
510
+ try {
511
+ result = arg0 instanceof Uint8Array;
512
+ } catch (_) {
513
+ result = false;
514
+ }
515
+ const ret = result;
516
+ return ret;
517
+ };
518
+
519
+ module.exports.__wbg_length_65d1cd11729ced11 = function(arg0) {
520
+ const ret = arg0.length;
521
+ return ret;
522
+ };
523
+
524
+ module.exports.__wbg_log_464d1b2190ca1e04 = function(arg0) {
525
+ console.log(arg0);
526
+ };
527
+
528
+ module.exports.__wbg_new_254fa9eac11932ae = function() {
529
+ const ret = new Array();
530
+ return ret;
531
+ };
532
+
533
+ module.exports.__wbg_new_3ff5b33b1ce712df = function(arg0) {
534
+ const ret = new Uint8Array(arg0);
535
+ return ret;
536
+ };
537
+
538
+ module.exports.__wbg_new_688846f374351c92 = function() {
539
+ const ret = new Object();
540
+ return ret;
541
+ };
542
+
543
+ module.exports.__wbg_new_8a6f238a6ece86ea = function() {
544
+ const ret = new Error();
545
+ return ret;
546
+ };
547
+
548
+ module.exports.__wbg_new_bc96c6a1c0786643 = function() {
549
+ const ret = new Map();
550
+ return ret;
551
+ };
552
+
553
+ module.exports.__wbg_now_64d0bb151e5d3889 = function() {
554
+ const ret = Date.now();
555
+ return ret;
556
+ };
557
+
558
+ module.exports.__wbg_push_6edad0df4b546b2c = function(arg0, arg1) {
559
+ const ret = arg0.push(arg1);
560
+ return ret;
561
+ };
562
+
563
+ module.exports.__wbg_set_1d80752d0d5f0b21 = function(arg0, arg1, arg2) {
564
+ arg0[arg1 >>> 0] = arg2;
565
+ };
566
+
567
+ module.exports.__wbg_set_23d69db4e5c66a6e = function(arg0, arg1, arg2) {
568
+ arg0.set(arg1, arg2 >>> 0);
569
+ };
570
+
571
+ module.exports.__wbg_set_3f1d0b984ed272ed = function(arg0, arg1, arg2) {
572
+ arg0[arg1] = arg2;
573
+ };
574
+
575
+ module.exports.__wbg_set_4e647025551483bd = function() { return handleError(function (arg0, arg1, arg2) {
576
+ const ret = Reflect.set(arg0, arg1, arg2);
577
+ return ret;
578
+ }, arguments) };
579
+
580
+ module.exports.__wbg_set_76818dc3c59a63d5 = function(arg0, arg1, arg2) {
581
+ const ret = arg0.set(arg1, arg2);
582
+ return ret;
583
+ };
584
+
585
+ module.exports.__wbg_stack_0ed75d68575b0f3c = function(arg0, arg1) {
586
+ const ret = arg1.stack;
587
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
588
+ const len1 = WASM_VECTOR_LEN;
589
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
590
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
591
+ };
592
+
593
+ module.exports.__wbg_warn_123db6aa8948382e = function(arg0) {
594
+ console.warn(arg0);
595
+ };
596
+
597
+ module.exports.__wbindgen_bigint_from_i64 = function(arg0) {
598
+ const ret = arg0;
599
+ return ret;
600
+ };
601
+
602
+ module.exports.__wbindgen_bigint_from_u64 = function(arg0) {
603
+ const ret = BigInt.asUintN(64, arg0);
604
+ return ret;
605
+ };
606
+
607
+ module.exports.__wbindgen_boolean_get = function(arg0) {
608
+ const v = arg0;
609
+ const ret = typeof(v) === 'boolean' ? (v ? 1 : 0) : 2;
610
+ return ret;
611
+ };
612
+
613
+ module.exports.__wbindgen_debug_string = function(arg0, arg1) {
614
+ const ret = debugString(arg1);
615
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
616
+ const len1 = WASM_VECTOR_LEN;
617
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
618
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
619
+ };
620
+
621
+ module.exports.__wbindgen_error_new = function(arg0, arg1) {
622
+ const ret = new Error(getStringFromWasm0(arg0, arg1));
623
+ return ret;
624
+ };
625
+
626
+ module.exports.__wbindgen_in = function(arg0, arg1) {
627
+ const ret = arg0 in arg1;
628
+ return ret;
629
+ };
630
+
631
+ module.exports.__wbindgen_init_externref_table = function() {
632
+ const table = wasm.__wbindgen_export_3;
633
+ const offset = table.grow(4);
634
+ table.set(0, undefined);
635
+ table.set(offset + 0, undefined);
636
+ table.set(offset + 1, null);
637
+ table.set(offset + 2, true);
638
+ table.set(offset + 3, false);
639
+ ;
640
+ };
641
+
642
+ module.exports.__wbindgen_is_null = function(arg0) {
643
+ const ret = arg0 === null;
644
+ return ret;
645
+ };
646
+
647
+ module.exports.__wbindgen_is_object = function(arg0) {
648
+ const val = arg0;
649
+ const ret = typeof(val) === 'object' && val !== null;
650
+ return ret;
651
+ };
652
+
653
+ module.exports.__wbindgen_is_string = function(arg0) {
654
+ const ret = typeof(arg0) === 'string';
655
+ return ret;
656
+ };
657
+
658
+ module.exports.__wbindgen_is_undefined = function(arg0) {
659
+ const ret = arg0 === undefined;
660
+ return ret;
661
+ };
662
+
663
+ module.exports.__wbindgen_jsval_loose_eq = function(arg0, arg1) {
664
+ const ret = arg0 == arg1;
665
+ return ret;
666
+ };
667
+
668
+ module.exports.__wbindgen_memory = function() {
669
+ const ret = wasm.memory;
670
+ return ret;
671
+ };
672
+
673
+ module.exports.__wbindgen_number_get = function(arg0, arg1) {
674
+ const obj = arg1;
675
+ const ret = typeof(obj) === 'number' ? obj : undefined;
676
+ getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);
677
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
678
+ };
679
+
680
+ module.exports.__wbindgen_number_new = function(arg0) {
681
+ const ret = arg0;
682
+ return ret;
683
+ };
684
+
685
+ module.exports.__wbindgen_string_get = function(arg0, arg1) {
686
+ const obj = arg1;
687
+ const ret = typeof(obj) === 'string' ? obj : undefined;
688
+ var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
689
+ var len1 = WASM_VECTOR_LEN;
690
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
691
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
692
+ };
693
+
694
+ module.exports.__wbindgen_string_new = function(arg0, arg1) {
695
+ const ret = getStringFromWasm0(arg0, arg1);
696
+ return ret;
697
+ };
698
+
699
+ module.exports.__wbindgen_throw = function(arg0, arg1) {
700
+ throw new Error(getStringFromWasm0(arg0, arg1));
701
+ };
702
+
703
+ const path = require('path').join(__dirname, 'convert_buddy_bg.wasm');
704
+ const bytes = require('fs').readFileSync(path);
705
+
706
+ const wasmModule = new WebAssembly.Module(bytes);
707
+ const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
708
+ wasm = wasmInstance.exports;
709
+ module.exports.__wasm = wasm;
710
+
711
+ wasm.__wbindgen_start();
712
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "convert-buddy-js",
3
- "version": "0.9.7",
3
+ "version": "0.9.8",
4
4
  "description": "TypeScript wrapper for convert-buddy (Rust/WASM core)",
5
5
  "license": "MIT",
6
6
  "type": "module",