jtcsv 2.2.8 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/README.md +204 -115
  2. package/bin/jtcsv.ts +2612 -0
  3. package/browser.d.ts +142 -0
  4. package/dist/benchmark.js +446 -0
  5. package/dist/benchmark.js.map +1 -0
  6. package/dist/bin/jtcsv.js +1940 -0
  7. package/dist/bin/jtcsv.js.map +1 -0
  8. package/dist/csv-to-json.js +1262 -0
  9. package/dist/csv-to-json.js.map +1 -0
  10. package/dist/errors.js +291 -0
  11. package/dist/errors.js.map +1 -0
  12. package/dist/eslint.config.js +147 -0
  13. package/dist/eslint.config.js.map +1 -0
  14. package/dist/index-core.js +95 -0
  15. package/dist/index-core.js.map +1 -0
  16. package/dist/index.js +93 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/json-save.js +229 -0
  19. package/dist/json-save.js.map +1 -0
  20. package/dist/json-to-csv.js +576 -0
  21. package/dist/json-to-csv.js.map +1 -0
  22. package/dist/jtcsv-core.cjs.js +1736 -0
  23. package/dist/jtcsv-core.cjs.js.map +1 -0
  24. package/dist/jtcsv-core.esm.js +1708 -0
  25. package/dist/jtcsv-core.esm.js.map +1 -0
  26. package/dist/jtcsv-core.umd.js +1742 -0
  27. package/dist/jtcsv-core.umd.js.map +1 -0
  28. package/dist/jtcsv-full.cjs.js +2241 -0
  29. package/dist/jtcsv-full.cjs.js.map +1 -0
  30. package/dist/jtcsv-full.esm.js +2209 -0
  31. package/dist/jtcsv-full.esm.js.map +1 -0
  32. package/dist/jtcsv-full.umd.js +2247 -0
  33. package/dist/jtcsv-full.umd.js.map +1 -0
  34. package/dist/jtcsv-workers.esm.js +768 -0
  35. package/dist/jtcsv-workers.esm.js.map +1 -0
  36. package/dist/jtcsv-workers.umd.js +782 -0
  37. package/dist/jtcsv-workers.umd.js.map +1 -0
  38. package/dist/jtcsv.cjs.js +1996 -2048
  39. package/dist/jtcsv.cjs.js.map +1 -1
  40. package/dist/jtcsv.esm.js +1992 -2048
  41. package/dist/jtcsv.esm.js.map +1 -1
  42. package/dist/jtcsv.umd.js +2157 -2209
  43. package/dist/jtcsv.umd.js.map +1 -1
  44. package/dist/plugins/express-middleware/index.js +350 -0
  45. package/dist/plugins/express-middleware/index.js.map +1 -0
  46. package/dist/plugins/fastify-plugin/index.js +315 -0
  47. package/dist/plugins/fastify-plugin/index.js.map +1 -0
  48. package/dist/plugins/hono/index.js +111 -0
  49. package/dist/plugins/hono/index.js.map +1 -0
  50. package/dist/plugins/nestjs/index.js +112 -0
  51. package/dist/plugins/nestjs/index.js.map +1 -0
  52. package/dist/plugins/nuxt/index.js +53 -0
  53. package/dist/plugins/nuxt/index.js.map +1 -0
  54. package/dist/plugins/remix/index.js +133 -0
  55. package/dist/plugins/remix/index.js.map +1 -0
  56. package/dist/plugins/sveltekit/index.js +155 -0
  57. package/dist/plugins/sveltekit/index.js.map +1 -0
  58. package/dist/plugins/trpc/index.js +136 -0
  59. package/dist/plugins/trpc/index.js.map +1 -0
  60. package/dist/run-demo.js +49 -0
  61. package/dist/run-demo.js.map +1 -0
  62. package/dist/src/browser/browser-functions.js +193 -0
  63. package/dist/src/browser/browser-functions.js.map +1 -0
  64. package/dist/src/browser/core.js +123 -0
  65. package/dist/src/browser/core.js.map +1 -0
  66. package/dist/src/browser/csv-to-json-browser.js +353 -0
  67. package/dist/src/browser/csv-to-json-browser.js.map +1 -0
  68. package/dist/src/browser/errors-browser.js +219 -0
  69. package/dist/src/browser/errors-browser.js.map +1 -0
  70. package/dist/src/browser/extensions/plugins.js +106 -0
  71. package/dist/src/browser/extensions/plugins.js.map +1 -0
  72. package/dist/src/browser/extensions/workers.js +66 -0
  73. package/dist/src/browser/extensions/workers.js.map +1 -0
  74. package/dist/src/browser/index.js +140 -0
  75. package/dist/src/browser/index.js.map +1 -0
  76. package/dist/src/browser/json-to-csv-browser.js +225 -0
  77. package/dist/src/browser/json-to-csv-browser.js.map +1 -0
  78. package/dist/src/browser/streams.js +340 -0
  79. package/dist/src/browser/streams.js.map +1 -0
  80. package/dist/src/browser/workers/csv-parser.worker.js +264 -0
  81. package/dist/src/browser/workers/csv-parser.worker.js.map +1 -0
  82. package/dist/src/browser/workers/worker-pool.js +338 -0
  83. package/dist/src/browser/workers/worker-pool.js.map +1 -0
  84. package/dist/src/core/delimiter-cache.js +196 -0
  85. package/dist/src/core/delimiter-cache.js.map +1 -0
  86. package/dist/src/core/node-optimizations.js +279 -0
  87. package/dist/src/core/node-optimizations.js.map +1 -0
  88. package/dist/src/core/plugin-system.js +399 -0
  89. package/dist/src/core/plugin-system.js.map +1 -0
  90. package/dist/src/core/transform-hooks.js +348 -0
  91. package/dist/src/core/transform-hooks.js.map +1 -0
  92. package/dist/src/engines/fast-path-engine-new.js +262 -0
  93. package/dist/src/engines/fast-path-engine-new.js.map +1 -0
  94. package/dist/src/engines/fast-path-engine.js +671 -0
  95. package/dist/src/engines/fast-path-engine.js.map +1 -0
  96. package/dist/src/errors.js +18 -0
  97. package/dist/src/errors.js.map +1 -0
  98. package/dist/src/formats/ndjson-parser.js +332 -0
  99. package/dist/src/formats/ndjson-parser.js.map +1 -0
  100. package/dist/src/formats/tsv-parser.js +230 -0
  101. package/dist/src/formats/tsv-parser.js.map +1 -0
  102. package/dist/src/index-with-plugins.js +259 -0
  103. package/dist/src/index-with-plugins.js.map +1 -0
  104. package/dist/src/types/index.js +3 -0
  105. package/dist/src/types/index.js.map +1 -0
  106. package/dist/src/utils/bom-utils.js +267 -0
  107. package/dist/src/utils/bom-utils.js.map +1 -0
  108. package/dist/src/utils/encoding-support.js +77 -0
  109. package/dist/src/utils/encoding-support.js.map +1 -0
  110. package/dist/src/utils/schema-validator.js +609 -0
  111. package/dist/src/utils/schema-validator.js.map +1 -0
  112. package/dist/src/utils/transform-loader.js +281 -0
  113. package/dist/src/utils/transform-loader.js.map +1 -0
  114. package/dist/src/utils/validators.js +40 -0
  115. package/dist/src/utils/validators.js.map +1 -0
  116. package/dist/src/utils/zod-adapter.js +144 -0
  117. package/dist/src/utils/zod-adapter.js.map +1 -0
  118. package/dist/src/web-server/index.js +648 -0
  119. package/dist/src/web-server/index.js.map +1 -0
  120. package/dist/src/workers/csv-multithreaded.js +211 -0
  121. package/dist/src/workers/csv-multithreaded.js.map +1 -0
  122. package/dist/src/workers/csv-parser.worker.js +179 -0
  123. package/dist/src/workers/csv-parser.worker.js.map +1 -0
  124. package/dist/src/workers/worker-pool.js +228 -0
  125. package/dist/src/workers/worker-pool.js.map +1 -0
  126. package/dist/stream-csv-to-json.js +665 -0
  127. package/dist/stream-csv-to-json.js.map +1 -0
  128. package/dist/stream-json-to-csv.js +389 -0
  129. package/dist/stream-json-to-csv.js.map +1 -0
  130. package/examples/advanced/conditional-transformations.ts +446 -0
  131. package/examples/advanced/csv-parser.worker.ts +89 -0
  132. package/examples/advanced/nested-objects-example.ts +306 -0
  133. package/examples/advanced/performance-optimization.ts +504 -0
  134. package/examples/advanced/run-demo-server.ts +116 -0
  135. package/examples/advanced/web-worker-usage.html +874 -0
  136. package/examples/async-multithreaded-example.ts +335 -0
  137. package/examples/cli-advanced-usage.md +290 -0
  138. package/examples/{cli-batch-processing.js → cli-batch-processing.ts} +38 -38
  139. package/examples/{cli-tool.js → cli-tool.ts} +5 -8
  140. package/examples/{error-handling.js → error-handling.ts} +356 -324
  141. package/examples/{express-api.js → express-api.ts} +161 -164
  142. package/examples/{large-dataset-example.js → large-dataset-example.ts} +201 -182
  143. package/examples/{ndjson-processing.js → ndjson-processing.ts} +456 -434
  144. package/examples/{plugin-excel-exporter.js → plugin-excel-exporter.ts} +6 -7
  145. package/examples/react-integration.tsx +637 -0
  146. package/examples/{schema-validation.js → schema-validation.ts} +2 -2
  147. package/examples/simple-usage.ts +194 -0
  148. package/examples/{streaming-example.js → streaming-example.ts} +12 -12
  149. package/index.d.ts +187 -18
  150. package/package.json +75 -81
  151. package/plugins.d.ts +37 -0
  152. package/schema.d.ts +103 -0
  153. package/src/browser/browser-functions.ts +402 -0
  154. package/src/browser/core.ts +152 -0
  155. package/src/browser/csv-to-json-browser.d.ts +3 -0
  156. package/src/browser/csv-to-json-browser.ts +494 -0
  157. package/src/browser/{errors-browser.js → errors-browser.ts} +305 -197
  158. package/src/browser/extensions/plugins.ts +93 -0
  159. package/src/browser/extensions/workers.ts +39 -0
  160. package/src/browser/globals.d.ts +5 -0
  161. package/src/browser/index.ts +192 -0
  162. package/src/browser/json-to-csv-browser.d.ts +3 -0
  163. package/src/browser/json-to-csv-browser.ts +338 -0
  164. package/src/browser/streams.ts +403 -0
  165. package/src/browser/workers/{csv-parser.worker.js → csv-parser.worker.ts} +3 -3
  166. package/src/browser/workers/{worker-pool.js → worker-pool.ts} +51 -30
  167. package/src/core/delimiter-cache.ts +320 -0
  168. package/src/core/{node-optimizations.js → node-optimizations.ts} +448 -407
  169. package/src/core/plugin-system.ts +588 -0
  170. package/src/core/transform-hooks.ts +566 -0
  171. package/src/engines/{fast-path-engine-new.js → fast-path-engine-new.ts} +11 -2
  172. package/src/engines/{fast-path-engine.js → fast-path-engine.ts} +79 -53
  173. package/src/errors.ts +1 -0
  174. package/src/formats/{ndjson-parser.js → ndjson-parser.ts} +24 -16
  175. package/src/formats/{tsv-parser.js → tsv-parser.ts} +18 -17
  176. package/src/{index-with-plugins.js → index-with-plugins.ts} +381 -357
  177. package/src/types/index.ts +275 -0
  178. package/src/utils/bom-utils.ts +373 -0
  179. package/src/utils/encoding-support.ts +155 -0
  180. package/src/utils/{schema-validator.js → schema-validator.ts} +814 -589
  181. package/src/utils/transform-loader.ts +389 -0
  182. package/src/utils/validators.ts +35 -0
  183. package/src/utils/zod-adapter.ts +280 -0
  184. package/src/web-server/{index.js → index.ts} +19 -19
  185. package/src/workers/csv-multithreaded.ts +310 -0
  186. package/src/workers/csv-parser.worker.ts +227 -0
  187. package/src/workers/worker-pool.ts +409 -0
  188. package/bin/jtcsv.js +0 -2462
  189. package/csv-to-json.js +0 -688
  190. package/errors.js +0 -208
  191. package/examples/simple-usage.js +0 -282
  192. package/index.js +0 -68
  193. package/json-save.js +0 -254
  194. package/json-to-csv.js +0 -526
  195. package/plugins/README.md +0 -91
  196. package/plugins/express-middleware/README.md +0 -64
  197. package/plugins/express-middleware/example.js +0 -136
  198. package/plugins/express-middleware/index.d.ts +0 -114
  199. package/plugins/express-middleware/index.js +0 -360
  200. package/plugins/express-middleware/package.json +0 -52
  201. package/plugins/fastify-plugin/index.js +0 -406
  202. package/plugins/fastify-plugin/package.json +0 -55
  203. package/plugins/hono/README.md +0 -28
  204. package/plugins/hono/index.d.ts +0 -12
  205. package/plugins/hono/index.js +0 -36
  206. package/plugins/hono/package.json +0 -35
  207. package/plugins/nestjs/README.md +0 -35
  208. package/plugins/nestjs/index.d.ts +0 -25
  209. package/plugins/nestjs/index.js +0 -77
  210. package/plugins/nestjs/package.json +0 -37
  211. package/plugins/nextjs-api/README.md +0 -57
  212. package/plugins/nextjs-api/examples/ConverterComponent.jsx +0 -386
  213. package/plugins/nextjs-api/examples/api-convert.js +0 -69
  214. package/plugins/nextjs-api/index.js +0 -387
  215. package/plugins/nextjs-api/package.json +0 -63
  216. package/plugins/nextjs-api/route.js +0 -371
  217. package/plugins/nuxt/README.md +0 -24
  218. package/plugins/nuxt/index.js +0 -21
  219. package/plugins/nuxt/package.json +0 -35
  220. package/plugins/nuxt/runtime/composables/useJtcsv.js +0 -6
  221. package/plugins/nuxt/runtime/plugin.js +0 -6
  222. package/plugins/remix/README.md +0 -26
  223. package/plugins/remix/index.d.ts +0 -16
  224. package/plugins/remix/index.js +0 -62
  225. package/plugins/remix/package.json +0 -35
  226. package/plugins/sveltekit/README.md +0 -28
  227. package/plugins/sveltekit/index.d.ts +0 -17
  228. package/plugins/sveltekit/index.js +0 -54
  229. package/plugins/sveltekit/package.json +0 -33
  230. package/plugins/trpc/README.md +0 -25
  231. package/plugins/trpc/index.d.ts +0 -7
  232. package/plugins/trpc/index.js +0 -32
  233. package/plugins/trpc/package.json +0 -34
  234. package/src/browser/browser-functions.js +0 -219
  235. package/src/browser/csv-to-json-browser.js +0 -700
  236. package/src/browser/index.js +0 -113
  237. package/src/browser/json-to-csv-browser.js +0 -309
  238. package/src/browser/streams.js +0 -393
  239. package/src/core/delimiter-cache.js +0 -186
  240. package/src/core/plugin-system.js +0 -476
  241. package/src/core/transform-hooks.js +0 -350
  242. package/src/errors.js +0 -26
  243. package/src/utils/transform-loader.js +0 -205
  244. package/stream-csv-to-json.js +0 -542
  245. package/stream-json-to-csv.js +0 -464
  246. /package/examples/{web-workers-advanced.js → web-workers-advanced.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/web-server/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * JTCSV Web Server\n * \n * Simple web server for browser-based CSV/JSON conversion\n * with REST API endpoints\n */\n\nimport http from \"http\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport url from \"url\";\nimport * as jtcsv from \"../../index\";\n\nconst PORT = process.env.PORT || 3000;\nconst HOST = process.env.HOST || 'localhost';\n\n/**\n * Parse JSON body from request\n */\nfunction parseBody(req): Promise<any> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', chunk => {\n body += chunk.toString();\n });\n req.on('end', () => {\n try {\n resolve(JSON.parse(body));\n } catch (error) {\n reject(new Error('Invalid JSON'));\n }\n });\n req.on('error', reject);\n });\n}\n\n/**\n * Send JSON response\n */\nfunction sendJson(res, statusCode, data) {\n res.statusCode = statusCode;\n res.setHeader('Content-Type', 'application/json');\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n res.end(JSON.stringify(data));\n}\n\n/**\n * Send error response\n */\nfunction sendError(res, statusCode, message) {\n sendJson(res, statusCode, {\n success: false,\n error: message\n });\n}\n\n/**\n * API Handler: Convert JSON to CSV\n */\nasync function handleJsonToCsv(req, res) {\n try {\n const body = await parseBody(req);\n const { data, options = {} } = body;\n\n if (!Array.isArray(data)) {\n return sendError(res, 400, 'Data must be an array of objects');\n }\n\n const csv = jtcsv.jsonToCsv(data, {\n delimiter: options.delimiter || ',',\n includeHeaders: options.includeHeaders !== false,\n preventCsvInjection: options.preventCsvInjection !== false,\n rfc4180Compliant: options.rfc4180Compliant !== false\n });\n\n sendJson(res, 200, {\n success: true,\n result: csv,\n records: data.length,\n bytes: csv.length\n });\n } catch (error) {\n sendError(res, 500, error.message);\n }\n}\n\n/**\n * API Handler: Convert CSV to JSON\n */\nasync function handleCsvToJson(req, res) {\n try {\n const body = await parseBody(req);\n const { data, options = {} } = body;\n\n if (typeof data !== 'string') {\n return sendError(res, 400, 'Data must be a CSV string');\n }\n\n const json = jtcsv.csvToJson(data, {\n delimiter: options.delimiter,\n autoDetect: options.autoDetect !== false,\n hasHeaders: options.hasHeaders !== false,\n trim: options.trim !== false,\n parseNumbers: options.parseNumbers === true,\n parseBooleans: options.parseBooleans === true\n });\n\n sendJson(res, 200, {\n success: true,\n result: json,\n rows: json.length\n });\n } catch (error) {\n sendError(res, 500, error.message);\n }\n}\n\n/**\n * API Handler: Validate data\n */\nasync function handleValidate(req, res) {\n try {\n const body = await parseBody(req);\n const { data, format } = body;\n\n let isValid = false;\n const errors = [];\n\n if (format === 'json') {\n if (Array.isArray(data)) {\n isValid = data.every(item => typeof item === 'object' && item !== null);\n if (!isValid) {\n errors.push('All items must be objects');\n }\n } else {\n errors.push('Data must be an array');\n }\n } else if (format === 'csv') {\n if (typeof data === 'string') {\n try {\n const parsed = jtcsv.csvToJson(data);\n isValid = Array.isArray(parsed) && parsed.length > 0;\n } catch (error) {\n errors.push(error.message);\n }\n } else {\n errors.push('Data must be a string');\n }\n } else {\n errors.push('Format must be \"json\" or \"csv\"');\n }\n\n sendJson(res, 200, {\n success: true,\n valid: isValid,\n errors: errors\n });\n } catch (error) {\n sendError(res, 500, error.message);\n }\n}\n\n/**\n * API Handler: Convert NDJSON to CSV\n */\nasync function handleNdjsonToCsv(req, res) {\n try {\n const body = await parseBody(req);\n const { data, options = {} } = body;\n\n if (typeof data !== 'string') {\n return sendError(res, 400, 'Data must be an NDJSON string');\n }\n\n const json = jtcsv.ndjsonToJson(data);\n const csv = jtcsv.jsonToCsv(json, {\n delimiter: options.delimiter || ',',\n includeHeaders: options.includeHeaders !== false\n });\n\n sendJson(res, 200, {\n success: true,\n result: csv,\n records: json.length\n });\n } catch (error) {\n sendError(res, 500, error.message);\n }\n}\n\n/**\n * API Handler: Convert CSV to NDJSON\n */\nasync function handleCsvToNdjson(req, res) {\n try {\n const body = await parseBody(req);\n const { data, options = {} } = body;\n\n if (typeof data !== 'string') {\n return sendError(res, 400, 'Data must be a CSV string');\n }\n\n const json = jtcsv.csvToJson(data, {\n delimiter: options.delimiter,\n autoDetect: options.autoDetect !== false,\n hasHeaders: options.hasHeaders !== false\n });\n\n const ndjson = jtcsv.jsonToNdjson(json);\n\n sendJson(res, 200, {\n success: true,\n result: ndjson,\n records: json.length\n });\n } catch (error) {\n sendError(res, 500, error.message);\n }\n}\n\n/**\n * Serve static HTML page\n */\nfunction serveHomePage(res) {\n const html = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>JTCSV Web Interface</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n min-height: 100vh;\n padding: 20px;\n }\n .container {\n max-width: 1200px;\n margin: 0 auto;\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n overflow: hidden;\n }\n .header {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n padding: 30px;\n text-align: center;\n }\n .header h1 { font-size: 2.5em; margin-bottom: 10px; }\n .header p { font-size: 1.1em; opacity: 0.9; }\n .main { padding: 30px; }\n .controls {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 20px;\n margin-bottom: 20px;\n }\n .control-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n label {\n font-weight: 600;\n color: #333;\n font-size: 0.9em;\n }\n select, input, button {\n padding: 12px;\n border: 2px solid #e0e0e0;\n border-radius: 6px;\n font-size: 1em;\n transition: border-color 0.3s;\n }\n select:focus, input:focus {\n outline: none;\n border-color: #667eea;\n }\n .textarea-group {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 20px;\n margin-bottom: 20px;\n }\n .textarea-wrapper { display: flex; flex-direction: column; }\n .textarea-wrapper label { margin-bottom: 8px; }\n textarea {\n width: 100%;\n height: 300px;\n padding: 12px;\n border: 2px solid #e0e0e0;\n border-radius: 6px;\n font-family: 'Courier New', monospace;\n font-size: 0.9em;\n resize: vertical;\n transition: border-color 0.3s;\n }\n textarea:focus {\n outline: none;\n border-color: #667eea;\n }\n .button-group {\n display: flex;\n gap: 15px;\n justify-content: center;\n margin-bottom: 20px;\n }\n button {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: none;\n padding: 14px 30px;\n font-weight: 600;\n cursor: pointer;\n transition: transform 0.2s, box-shadow 0.2s;\n }\n button:hover {\n transform: translateY(-2px);\n box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);\n }\n button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n }\n .info-box {\n background: #f5f5f5;\n padding: 15px;\n border-radius: 6px;\n border-left: 4px solid #667eea;\n margin-bottom: 20px;\n font-size: 0.9em;\n color: #666;\n }\n .error {\n background: #fee;\n border-left-color: #f44;\n color: #c33;\n }\n .success {\n background: #efe;\n border-left-color: #4a4;\n color: #363;\n }\n .stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));\n gap: 15px;\n margin-top: 20px;\n }\n .stat-card {\n background: #f9f9f9;\n padding: 15px;\n border-radius: 6px;\n text-align: center;\n }\n .stat-value {\n font-size: 2em;\n font-weight: bold;\n color: #667eea;\n }\n .stat-label {\n font-size: 0.85em;\n color: #666;\n margin-top: 5px;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"header\">\n <h1>🔄 JTCSV Web Interface</h1>\n <p>High-performance CSV ↔ JSON converter</p>\n </div>\n \n <div class=\"main\">\n <div class=\"controls\">\n <div class=\"control-group\">\n <label for=\"operation\">Operation:</label>\n <select id=\"operation\">\n <option value=\"json-to-csv\">JSON → CSV</option>\n <option value=\"csv-to-json\">CSV → JSON</option>\n <option value=\"ndjson-to-csv\">NDJSON → CSV</option>\n <option value=\"csv-to-ndjson\">CSV → NDJSON</option>\n </select>\n </div>\n \n <div class=\"control-group\">\n <label for=\"delimiter\">CSV Delimiter:</label>\n <select id=\"delimiter\">\n <option value=\",\">Comma (,)</option>\n <option value=\";\">Semicolon (;)</option>\n <option value=\"\\t\">Tab</option>\n <option value=\"|\">Pipe (|)</option>\n </select>\n </div>\n </div>\n \n <div class=\"control-group\" style=\"margin-bottom: 20px;\">\n <label>\n <input type=\"checkbox\" id=\"parseNumbers\" style=\"width: auto; margin-right: 8px;\">\n Parse Numbers (CSV → JSON)\n </label>\n <label>\n <input type=\"checkbox\" id=\"parseBooleans\" style=\"width: auto; margin-right: 8px;\">\n Parse Booleans (CSV → JSON)\n </label>\n <label>\n <input type=\"checkbox\" id=\"includeHeaders\" checked style=\"width: auto; margin-right: 8px;\">\n Include Headers (JSON → CSV)\n </label>\n </div>\n \n <div class=\"textarea-group\">\n <div class=\"textarea-wrapper\">\n <label for=\"input\">Input:</label>\n <textarea id=\"input\" placeholder=\"Paste your JSON or CSV data here...\"></textarea>\n </div>\n \n <div class=\"textarea-wrapper\">\n <label for=\"output\">Output:</label>\n <textarea id=\"output\" placeholder=\"Converted data will appear here...\" readonly></textarea>\n </div>\n </div>\n \n <div class=\"button-group\">\n <button id=\"convertBtn\">Convert</button>\n <button id=\"clearBtn\" style=\"background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\">Clear</button>\n <button id=\"copyBtn\" style=\"background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);\">Copy Output</button>\n </div>\n \n <div id=\"messageBox\" style=\"display: none;\"></div>\n \n <div class=\"stats\" id=\"stats\" style=\"display: none;\">\n <div class=\"stat-card\">\n <div class=\"stat-value\" id=\"recordsCount\">0</div>\n <div class=\"stat-label\">Records</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\" id=\"bytesCount\">0</div>\n <div class=\"stat-label\">Bytes</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\" id=\"timeCount\">0</div>\n <div class=\"stat-label\">ms</div>\n </div>\n </div>\n </div>\n </div>\n \n <script>\n const API_URL = 'http://${HOST}:${PORT}/api';\n \n const elements = {\n operation: document.getElementById('operation'),\n delimiter: document.getElementById('delimiter'),\n parseNumbers: document.getElementById('parseNumbers'),\n parseBooleans: document.getElementById('parseBooleans'),\n includeHeaders: document.getElementById('includeHeaders'),\n input: document.getElementById('input'),\n output: document.getElementById('output'),\n convertBtn: document.getElementById('convertBtn'),\n clearBtn: document.getElementById('clearBtn'),\n copyBtn: document.getElementById('copyBtn'),\n messageBox: document.getElementById('messageBox'),\n stats: document.getElementById('stats'),\n recordsCount: document.getElementById('recordsCount'),\n bytesCount: document.getElementById('bytesCount'),\n timeCount: document.getElementById('timeCount')\n };\n \n function showMessage(message, type = 'info') {\n elements.messageBox.textContent = message;\n elements.messageBox.className = 'info-box ' + type;\n elements.messageBox.style.display = 'block';\n setTimeout(() => {\n elements.messageBox.style.display = 'none';\n }, 5000);\n }\n \n function updateStats(records, bytes, time) {\n elements.recordsCount.textContent = records || 0;\n elements.bytesCount.textContent = bytes || 0;\n elements.timeCount.textContent = time || 0;\n elements.stats.style.display = 'grid';\n }\n \n async function convert() {\n const input = elements.input.value.trim();\n if (!input) {\n showMessage('Please enter input data', 'error');\n return;\n }\n \n elements.convertBtn.disabled = true;\n elements.convertBtn.textContent = 'Converting...';\n \n try {\n const operation = elements.operation.value;\n const options = {\n delimiter: elements.delimiter.value,\n parseNumbers: elements.parseNumbers.checked,\n parseBooleans: elements.parseBooleans.checked,\n includeHeaders: elements.includeHeaders.checked\n };\n \n let endpoint = '';\n let requestData = {};\n \n if (operation === 'json-to-csv') {\n endpoint = '/json-to-csv';\n requestData = { data: JSON.parse(input), options };\n } else if (operation === 'csv-to-json') {\n endpoint = '/csv-to-json';\n requestData = { data: input, options };\n } else if (operation === 'ndjson-to-csv') {\n endpoint = '/ndjson-to-csv';\n requestData = { data: input, options };\n } else if (operation === 'csv-to-ndjson') {\n endpoint = '/csv-to-ndjson';\n requestData = { data: input, options };\n }\n \n const startTime = Date.now();\n const response = await fetch(API_URL + endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(requestData)\n });\n \n const result = await response.json();\n const elapsed = Date.now() - startTime;\n \n if (result.success) {\n if (operation.includes('json')) {\n elements.output.value = JSON.stringify(result.result, null, 2);\n } else {\n elements.output.value = result.result;\n }\n showMessage('Conversion successful!', 'success');\n updateStats(result.records || result.rows || 0, result.bytes || 0, elapsed);\n } else {\n showMessage('Error: ' + result.error, 'error');\n }\n } catch (error) {\n showMessage('Error: ' + error.message, 'error');\n } finally {\n elements.convertBtn.disabled = false;\n elements.convertBtn.textContent = 'Convert';\n }\n }\n \n function clear() {\n elements.input.value = '';\n elements.output.value = '';\n elements.stats.style.display = 'none';\n elements.messageBox.style.display = 'none';\n }\n \n function copyToClipboard() {\n const output = elements.output.value;\n if (!output) {\n showMessage('Nothing to copy', 'error');\n return;\n }\n \n navigator.clipboard.writeText(output).then(() => {\n showMessage('Copied to clipboard!', 'success');\n }).catch(() => {\n showMessage('Failed to copy', 'error');\n });\n }\n \n elements.convertBtn.addEventListener('click', convert);\n elements.clearBtn.addEventListener('click', clear);\n elements.copyBtn.addEventListener('click', copyToClipboard);\n \n // Load example data\n elements.input.value = JSON.stringify([\n { name: \"Alice\", age: 30, city: \"New York\" },\n { name: \"Bob\", age: 25, city: \"London\" },\n { name: \"Charlie\", age: 35, city: \"Paris\" }\n ], null, 2);\n </script>\n</body>\n</html>`;\n\n res.statusCode = 200;\n res.setHeader('Content-Type', 'text/html');\n res.end(html);\n}\n\n/**\n * Request handler\n */\nfunction handleRequest(req, res) {\n const parsedUrl = url.parse(req.url, true);\n const pathname = parsedUrl.pathname;\n \n // Handle CORS preflight\n if (req.method === 'OPTIONS') {\n res.statusCode = 204;\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n res.end();\n return;\n }\n \n // Home page\n if (pathname === '/' && req.method === 'GET') {\n return serveHomePage(res);\n }\n \n // API endpoints\n if (req.method === 'POST') {\n if (pathname === '/api/json-to-csv') {\n return handleJsonToCsv(req, res);\n }\n if (pathname === '/api/csv-to-json') {\n return handleCsvToJson(req, res);\n }\n if (pathname === '/api/validate') {\n return handleValidate(req, res);\n }\n if (pathname === '/api/ndjson-to-csv') {\n return handleNdjsonToCsv(req, res);\n }\n if (pathname === '/api/csv-to-ndjson') {\n return handleCsvToNdjson(req, res);\n }\n }\n \n // 404\n sendError(res, 404, 'Not found');\n}\n\n/**\n * Start server\n */\nfunction startServer(options: any = {}) {\n const port = options.port || PORT;\n const host = options.host || HOST;\n \n const server = http.createServer(handleRequest);\n \n server.listen(port, host, () => {\n console.log('\\n🌐 JTCSV Web Server started!');\n console.log(`\\n📍 URL: http://${host}:${port}`);\n console.log('\\n📡 API Endpoints:');\n console.log(' POST /api/json-to-csv');\n console.log(' POST /api/csv-to-json');\n console.log(' POST /api/ndjson-to-csv');\n console.log(' POST /api/csv-to-ndjson');\n console.log(' POST /api/validate');\n console.log('\\n✨ Press Ctrl+C to stop\\n');\n });\n \n server.on('error', (error) => {\n if ((error as any).code === 'EADDRINUSE') {\n console.error(`\\n❌ Error: Port ${port} is already in use`);\n console.error(' Try a different port: jtcsv web --port=3001\\n');\n } else {\n console.error(`\\n❌ Server error: ${error.message}\\n`);\n }\n process.exit(1);\n });\n \n return server;\n}\n\nexport default { startServer };\n\n// Run as standalone\nif (require.main === module) {\n startServer();\n}\n"]}
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.csvToJsonMultithreaded = csvToJsonMultithreaded;
37
+ exports.jsonToCsvMultithreaded = jsonToCsvMultithreaded;
38
+ exports.benchmarkMultithreaded = benchmarkMultithreaded;
39
+ exports.optimizeChunkSize = optimizeChunkSize;
40
+ exports.getResourceUsage = getResourceUsage;
41
+ const worker_pool_1 = require("./worker-pool");
42
+ const csv_parser_worker_1 = require("./csv-parser.worker");
43
+ async function csvToJsonMultithreaded(csv, options = {}) {
44
+ const { useWorkers = true, workerCount, chunkSize = 1000, onProgress, ...csvOptions } = options;
45
+ if (!useWorkers || csv.length < 10000) {
46
+ const { csvToJson } = await Promise.resolve().then(() => __importStar(require('../../csv-to-json')));
47
+ return csvToJson(csv, csvOptions);
48
+ }
49
+ const lines = csv.split('\n').filter(line => line.trim() !== '');
50
+ if (lines.length === 0) {
51
+ return [];
52
+ }
53
+ const hasHeaders = csvOptions.hasHeaders !== false;
54
+ let dataChunks;
55
+ let headers = [];
56
+ if (hasHeaders) {
57
+ headers = lines[0].split(csvOptions.delimiter || ';');
58
+ const dataLines = lines.slice(1);
59
+ dataChunks = (0, csv_parser_worker_1.chunkData)(dataLines, chunkSize);
60
+ }
61
+ else {
62
+ dataChunks = (0, csv_parser_worker_1.chunkData)(lines, chunkSize);
63
+ }
64
+ const tasks = dataChunks.map((chunk, index) => {
65
+ let chunkCsv = chunk.join('\n');
66
+ if (hasHeaders && headers.length > 0) {
67
+ chunkCsv = headers.join(csvOptions.delimiter || ';') + '\n' + chunkCsv;
68
+ }
69
+ return (0, worker_pool_1.createWorkerTask)('csv_parse', chunkCsv, {
70
+ ...csvOptions,
71
+ chunkIndex: index,
72
+ totalChunks: dataChunks.length,
73
+ hasHeaders: index === 0 ? hasHeaders : false
74
+ });
75
+ });
76
+ const workerPool = (0, worker_pool_1.getWorkerPool)(workerCount);
77
+ if (onProgress) {
78
+ workerPool.on('taskCompleted', ({ task }) => {
79
+ const chunkIndex = task.options?.chunkIndex || 0;
80
+ const totalChunks = task.options?.totalChunks || 1;
81
+ onProgress({
82
+ processed: chunkIndex + 1,
83
+ total: totalChunks,
84
+ percentage: Math.round(((chunkIndex + 1) / totalChunks) * 100)
85
+ });
86
+ });
87
+ }
88
+ const results = await workerPool.executeTasks(tasks);
89
+ const mergedResults = (0, csv_parser_worker_1.mergeChunkResults)(results);
90
+ return mergedResults;
91
+ }
92
+ async function jsonToCsvMultithreaded(data, options = {}) {
93
+ const { useWorkers = true, workerCount, chunkSize = 1000, onProgress, ...jsonOptions } = options;
94
+ const dataArray = Array.isArray(data) ? data : [data];
95
+ if (!useWorkers || dataArray.length < 1000) {
96
+ const { jsonToCsv } = await Promise.resolve().then(() => __importStar(require('../../json-to-csv')));
97
+ return jsonToCsv(dataArray, jsonOptions);
98
+ }
99
+ const dataChunks = (0, csv_parser_worker_1.chunkData)(dataArray, chunkSize);
100
+ const tasks = dataChunks.map((chunk, index) => {
101
+ return (0, worker_pool_1.createWorkerTask)('json_to_csv', chunk, {
102
+ ...jsonOptions,
103
+ chunkIndex: index,
104
+ totalChunks: dataChunks.length,
105
+ includeHeaders: index === 0
106
+ });
107
+ });
108
+ const workerPool = (0, worker_pool_1.getWorkerPool)(workerCount);
109
+ if (onProgress) {
110
+ workerPool.on('taskCompleted', ({ task }) => {
111
+ const chunkIndex = task.options?.chunkIndex || 0;
112
+ const totalChunks = task.options?.totalChunks || 1;
113
+ onProgress({
114
+ processed: chunkIndex + 1,
115
+ total: totalChunks,
116
+ percentage: Math.round(((chunkIndex + 1) / totalChunks) * 100)
117
+ });
118
+ });
119
+ }
120
+ const results = await workerPool.executeTasks(tasks);
121
+ let finalCsv = '';
122
+ for (let i = 0; i < results.length; i++) {
123
+ const chunkCsv = results[i];
124
+ if (i === 0) {
125
+ finalCsv = chunkCsv;
126
+ }
127
+ else {
128
+ const lines = chunkCsv.split('\n');
129
+ if (lines.length > 1 && jsonOptions.includeHeaders !== false) {
130
+ finalCsv += '\n' + lines.slice(1).join('\n');
131
+ }
132
+ else {
133
+ finalCsv += '\n' + chunkCsv;
134
+ }
135
+ }
136
+ }
137
+ return finalCsv;
138
+ }
139
+ async function benchmarkMultithreaded(data, iterations = 10) {
140
+ const workerPool = (0, worker_pool_1.getWorkerPool)();
141
+ const cpuCount = require('os').cpus().length;
142
+ const singleThreadStart = Date.now();
143
+ if (typeof data === 'string') {
144
+ const { csvToJson } = await Promise.resolve().then(() => __importStar(require('../../csv-to-json')));
145
+ for (let i = 0; i < iterations; i++) {
146
+ await csvToJson(data);
147
+ }
148
+ }
149
+ else {
150
+ const { jsonToCsv } = await Promise.resolve().then(() => __importStar(require('../../json-to-csv')));
151
+ for (let i = 0; i < iterations; i++) {
152
+ await jsonToCsv(data);
153
+ }
154
+ }
155
+ const singleThreadTime = Date.now() - singleThreadStart;
156
+ const multiThreadStart = Date.now();
157
+ if (typeof data === 'string') {
158
+ for (let i = 0; i < iterations; i++) {
159
+ await csvToJsonMultithreaded(data, {
160
+ useWorkers: true,
161
+ workerCount: cpuCount - 1
162
+ });
163
+ }
164
+ }
165
+ else {
166
+ for (let i = 0; i < iterations; i++) {
167
+ await jsonToCsvMultithreaded(data, {
168
+ useWorkers: true,
169
+ workerCount: cpuCount - 1
170
+ });
171
+ }
172
+ }
173
+ const multiThreadTime = Date.now() - multiThreadStart;
174
+ const speedup = singleThreadTime / multiThreadTime;
175
+ const efficiency = (speedup / (cpuCount - 1)) * 100;
176
+ return {
177
+ singleThread: singleThreadTime,
178
+ multiThread: multiThreadTime,
179
+ speedup,
180
+ efficiency
181
+ };
182
+ }
183
+ function optimizeChunkSize(dataSize, workerCount = Math.max(1, require('os').cpus().length - 1)) {
184
+ let chunkSize = 1000;
185
+ if (dataSize > 1000000) {
186
+ chunkSize = 10000;
187
+ }
188
+ else if (dataSize > 100000) {
189
+ chunkSize = 5000;
190
+ }
191
+ else if (dataSize > 10000) {
192
+ chunkSize = 2000;
193
+ }
194
+ else if (dataSize < 1000) {
195
+ chunkSize = Math.max(100, Math.ceil(dataSize / workerCount));
196
+ }
197
+ chunkSize = Math.max(chunkSize, Math.ceil(dataSize / (workerCount * 10)));
198
+ return chunkSize;
199
+ }
200
+ function getResourceUsage() {
201
+ const cpuUsage = process.cpuUsage();
202
+ const memoryUsage = process.memoryUsage();
203
+ const workerPool = (0, worker_pool_1.getWorkerPool)();
204
+ const workerStats = workerPool.getStats();
205
+ return {
206
+ cpuUsage,
207
+ memoryUsage,
208
+ workerStats
209
+ };
210
+ }
211
+ //# sourceMappingURL=csv-multithreaded.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv-multithreaded.js","sourceRoot":"","sources":["../../../src/workers/csv-multithreaded.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Многопоточная обработка CSV данных\r\n * \r\n * Интеграция Worker Pool с существующими асинхронными функциями\r\n */\r\n\r\nimport { getWorkerPool, createWorkerTask } from './worker-pool';\r\nimport { CsvToJsonOptions, AsyncCsvToJsonOptions, AnyArray, AnyObject } from '../types';\r\nimport { chunkData, createChunkTasks, mergeChunkResults } from './csv-parser.worker';\r\n\r\n/**\r\n * Многопоточная версия csvToJson\r\n * \r\n * @param csv - CSV строка для парсинга\r\n * @param options - Опции с поддержкой многопоточности\r\n * @returns Promise с результатом парсинга\r\n */\r\nexport async function csvToJsonMultithreaded(\r\n csv: string,\r\n options: AsyncCsvToJsonOptions = {}\r\n): Promise<AnyArray> {\r\n const {\r\n useWorkers = true,\r\n workerCount,\r\n chunkSize = 1000,\r\n onProgress,\r\n ...csvOptions\r\n } = options;\r\n \r\n // Если многопоточность отключена или данные маленькие, используем обычную версию\r\n if (!useWorkers || csv.length < 10000) {\r\n const { csvToJson } = await import('../../csv-to-json');\r\n return csvToJson(csv, csvOptions);\r\n }\r\n \r\n // Разделяем CSV на строки\r\n const lines = csv.split('\\n').filter(line => line.trim() !== '');\r\n \r\n if (lines.length === 0) {\r\n return [];\r\n }\r\n \r\n // Определяем есть ли заголовки\r\n const hasHeaders = csvOptions.hasHeaders !== false;\r\n \r\n // Разделяем данные на чанки\r\n let dataChunks: string[][];\r\n let headers: string[] = [];\r\n \r\n if (hasHeaders) {\r\n headers = lines[0].split(csvOptions.delimiter || ';');\r\n const dataLines = lines.slice(1);\r\n dataChunks = chunkData(dataLines, chunkSize);\r\n } else {\r\n dataChunks = chunkData(lines, chunkSize);\r\n }\r\n \r\n // Создаем задачи для воркеров\r\n const tasks = dataChunks.map((chunk, index) => {\r\n // Восстанавливаем CSV чанк с заголовками если нужно\r\n let chunkCsv = chunk.join('\\n');\r\n if (hasHeaders && headers.length > 0) {\r\n chunkCsv = headers.join(csvOptions.delimiter || ';') + '\\n' + chunkCsv;\r\n }\r\n \r\n return createWorkerTask('csv_parse', chunkCsv, {\r\n ...csvOptions,\r\n chunkIndex: index,\r\n totalChunks: dataChunks.length,\r\n hasHeaders: index === 0 ? hasHeaders : false // Только первый чанк получает заголовки\r\n });\r\n });\r\n \r\n // Получаем пул воркеров\r\n const workerPool = getWorkerPool(workerCount);\r\n \r\n // Отправляем прогресс если есть callback\r\n if (onProgress) {\r\n workerPool.on('taskCompleted', ({ task }) => {\r\n const chunkIndex = task.options?.chunkIndex || 0;\r\n const totalChunks = task.options?.totalChunks || 1;\r\n \r\n onProgress({\r\n processed: chunkIndex + 1,\r\n total: totalChunks,\r\n percentage: Math.round(((chunkIndex + 1) / totalChunks) * 100)\r\n });\r\n });\r\n }\r\n \r\n // Выполняем задачи параллельно\r\n const results = await workerPool.executeTasks(tasks);\r\n \r\n // Объединяем результаты\r\n const mergedResults = mergeChunkResults(results);\r\n \r\n return mergedResults;\r\n}\r\n\r\n/**\r\n * Многопоточная версия jsonToCsv\r\n * \r\n * @param data - JSON данные для конвертации\r\n * @param options - Опции с поддержкой многопоточности\r\n * @returns Promise с CSV строкой\r\n */\r\nexport async function jsonToCsvMultithreaded(\r\n data: AnyArray | AnyObject,\r\n options: any = {} // TODO: Добавить тип AsyncJsonToCsvOptions\r\n): Promise<string> {\r\n const {\r\n useWorkers = true,\r\n workerCount,\r\n chunkSize = 1000,\r\n onProgress,\r\n ...jsonOptions\r\n } = options;\r\n \r\n // Подготавливаем данные\r\n const dataArray = Array.isArray(data) ? data : [data];\r\n \r\n // Если многопоточность отключена или данные маленькие, используем обычную версию\r\n if (!useWorkers || dataArray.length < 1000) {\r\n const { jsonToCsv } = await import('../../json-to-csv');\r\n return jsonToCsv(dataArray, jsonOptions);\r\n }\r\n \r\n // Разделяем данные на чанки\r\n const dataChunks = chunkData(dataArray, chunkSize);\r\n \r\n // Создаем задачи для воркеров\r\n const tasks = dataChunks.map((chunk, index) => {\r\n return createWorkerTask('json_to_csv', chunk, {\r\n ...jsonOptions,\r\n chunkIndex: index,\r\n totalChunks: dataChunks.length,\r\n includeHeaders: index === 0 // Только первый чанк включает заголовки\r\n });\r\n });\r\n \r\n // Получаем пул воркеров\r\n const workerPool = getWorkerPool(workerCount);\r\n \r\n // Отправляем прогресс если есть callback\r\n if (onProgress) {\r\n workerPool.on('taskCompleted', ({ task }) => {\r\n const chunkIndex = task.options?.chunkIndex || 0;\r\n const totalChunks = task.options?.totalChunks || 1;\r\n \r\n onProgress({\r\n processed: chunkIndex + 1,\r\n total: totalChunks,\r\n percentage: Math.round(((chunkIndex + 1) / totalChunks) * 100)\r\n });\r\n });\r\n }\r\n \r\n // Выполняем задачи параллельно\r\n const results = await workerPool.executeTasks(tasks);\r\n \r\n // Объединяем CSV чанки\r\n let finalCsv = '';\r\n \r\n for (let i = 0; i < results.length; i++) {\r\n const chunkCsv = results[i];\r\n \r\n if (i === 0) {\r\n // Первый чанк включает заголовки\r\n finalCsv = chunkCsv;\r\n } else {\r\n // Последующие чанки - только данные (убираем первую строку если это заголовки)\r\n const lines = chunkCsv.split('\\n');\r\n if (lines.length > 1 && jsonOptions.includeHeaders !== false) {\r\n finalCsv += '\\n' + lines.slice(1).join('\\n');\r\n } else {\r\n finalCsv += '\\n' + chunkCsv;\r\n }\r\n }\r\n }\r\n \r\n return finalCsv;\r\n}\r\n\r\n/**\r\n * Бенчмарк многопоточной обработки\r\n * \r\n * @param data - Данные для тестирования\r\n * @param iterations - Количество итераций\r\n * @returns Результаты бенчмарка\r\n */\r\nexport async function benchmarkMultithreaded(\r\n data: AnyArray | string,\r\n iterations: number = 10\r\n): Promise<{\r\n singleThread: number;\r\n multiThread: number;\r\n speedup: number;\r\n efficiency: number;\r\n}> {\r\n const workerPool = getWorkerPool();\r\n const cpuCount = require('os').cpus().length;\r\n \r\n // Тестируем однопоточную обработку\r\n const singleThreadStart = Date.now();\r\n \r\n if (typeof data === 'string') {\r\n // CSV парсинг\r\n const { csvToJson } = await import('../../csv-to-json');\r\n for (let i = 0; i < iterations; i++) {\r\n await csvToJson(data);\r\n }\r\n } else {\r\n // JSON to CSV\r\n const { jsonToCsv } = await import('../../json-to-csv');\r\n for (let i = 0; i < iterations; i++) {\r\n await jsonToCsv(data);\r\n }\r\n }\r\n \r\n const singleThreadTime = Date.now() - singleThreadStart;\r\n \r\n // Тестируем многопоточную обработку\r\n const multiThreadStart = Date.now();\r\n \r\n if (typeof data === 'string') {\r\n for (let i = 0; i < iterations; i++) {\r\n await csvToJsonMultithreaded(data, {\r\n useWorkers: true,\r\n workerCount: cpuCount - 1\r\n });\r\n }\r\n } else {\r\n for (let i = 0; i < iterations; i++) {\r\n await jsonToCsvMultithreaded(data, {\r\n useWorkers: true,\r\n workerCount: cpuCount - 1\r\n });\r\n }\r\n }\r\n \r\n const multiThreadTime = Date.now() - multiThreadStart;\r\n \r\n // Вычисляем ускорение и эффективность\r\n const speedup = singleThreadTime / multiThreadTime;\r\n const efficiency = (speedup / (cpuCount - 1)) * 100;\r\n \r\n return {\r\n singleThread: singleThreadTime,\r\n multiThread: multiThreadTime,\r\n speedup,\r\n efficiency\r\n };\r\n}\r\n\r\n/**\r\n * Оптимизирует размер чанка на основе размера данных\r\n * \r\n * @param dataSize - Размер данных (количество строк или байт)\r\n * @param workerCount - Количество воркеров\r\n * @returns Оптимальный размер чанка\r\n */\r\nexport function optimizeChunkSize(\r\n dataSize: number,\r\n workerCount: number = Math.max(1, require('os').cpus().length - 1)\r\n): number {\r\n // Базовый размер чанка\r\n let chunkSize = 1000;\r\n \r\n if (dataSize > 1000000) {\r\n // Очень большие данные - увеличиваем размер чанка\r\n chunkSize = 10000;\r\n } else if (dataSize > 100000) {\r\n // Большие данные\r\n chunkSize = 5000;\r\n } else if (dataSize > 10000) {\r\n // Средние данные\r\n chunkSize = 2000;\r\n } else if (dataSize < 1000) {\r\n // Маленькие данные - уменьшаем размер чанка\r\n chunkSize = Math.max(100, Math.ceil(dataSize / workerCount));\r\n }\r\n \r\n // Учитываем количество воркеров\r\n chunkSize = Math.max(chunkSize, Math.ceil(dataSize / (workerCount * 10)));\r\n \r\n return chunkSize;\r\n}\r\n\r\n/**\r\n * Мониторинг использования ресурсов\r\n * \r\n * @returns Статистика использования ресурсов\r\n */\r\nexport function getResourceUsage(): {\r\n cpuUsage: NodeJS.CpuUsage;\r\n memoryUsage: NodeJS.MemoryUsage;\r\n workerStats: any;\r\n} {\r\n const cpuUsage = process.cpuUsage();\r\n const memoryUsage = process.memoryUsage();\r\n \r\n const workerPool = getWorkerPool();\r\n const workerStats = workerPool.getStats();\r\n \r\n return {\r\n cpuUsage,\r\n memoryUsage,\r\n workerStats\r\n };\r\n}"]}
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.chunkData = chunkData;
37
+ exports.mergeChunkResults = mergeChunkResults;
38
+ exports.createChunkTasks = createChunkTasks;
39
+ const worker_threads_1 = require("worker_threads");
40
+ let csvToJson = null;
41
+ let jsonToCsv = null;
42
+ async function initializeParserFunctions() {
43
+ if (!csvToJson) {
44
+ const csvModule = await Promise.resolve().then(() => __importStar(require('../../csv-to-json')));
45
+ csvToJson = csvModule.csvToJson;
46
+ }
47
+ if (!jsonToCsv) {
48
+ const jsonModule = await Promise.resolve().then(() => __importStar(require('../../json-to-csv')));
49
+ jsonToCsv = jsonModule.jsonToCsv;
50
+ }
51
+ }
52
+ async function processCsvParsing(task) {
53
+ await initializeParserFunctions();
54
+ const { data, options } = task;
55
+ if (typeof data !== 'string') {
56
+ throw new Error('CSV data must be a string');
57
+ }
58
+ return csvToJson(data, options);
59
+ }
60
+ async function processJsonToCsv(task) {
61
+ await initializeParserFunctions();
62
+ const { data, options } = task;
63
+ if (!Array.isArray(data) && (typeof data !== 'object' || data === null)) {
64
+ throw new Error('JSON data must be an array or object');
65
+ }
66
+ return jsonToCsv(data, options);
67
+ }
68
+ async function processDataChunk(task) {
69
+ const { type, data, options } = task;
70
+ switch (type) {
71
+ case 'csv_parse':
72
+ return processCsvParsing(task);
73
+ case 'json_to_csv':
74
+ return processJsonToCsv(task);
75
+ case 'transform_data':
76
+ if (Array.isArray(data)) {
77
+ return data.map((item, index) => ({
78
+ ...item,
79
+ _workerId: worker_threads_1.workerData?.workerId || 0,
80
+ _chunkIndex: index
81
+ }));
82
+ }
83
+ return data;
84
+ case 'validate_data':
85
+ if (Array.isArray(data)) {
86
+ const invalidItems = data.filter(item => item === null || item === undefined ||
87
+ (typeof item === 'object' && Object.keys(item).length === 0));
88
+ return {
89
+ valid: invalidItems.length === 0,
90
+ totalItems: data.length,
91
+ invalidItems: invalidItems.length,
92
+ invalidIndexes: data
93
+ .map((item, index) => ({ item, index }))
94
+ .filter(({ item }) => item === null || item === undefined ||
95
+ (typeof item === 'object' && Object.keys(item).length === 0))
96
+ .map(({ index }) => index)
97
+ };
98
+ }
99
+ return { valid: true, totalItems: 1 };
100
+ default:
101
+ throw new Error(`Unknown task type: ${type}`);
102
+ }
103
+ }
104
+ async function main() {
105
+ if (worker_threads_1.isMainThread) {
106
+ console.error('Worker script should not be run in main thread');
107
+ process.exit(1);
108
+ }
109
+ worker_threads_1.parentPort?.on('message', async (task) => {
110
+ const startTime = Date.now();
111
+ try {
112
+ const result = await processDataChunk(task);
113
+ const duration = Date.now() - startTime;
114
+ const workerResult = {
115
+ id: task.id,
116
+ result,
117
+ duration
118
+ };
119
+ worker_threads_1.parentPort?.postMessage(workerResult);
120
+ }
121
+ catch (error) {
122
+ const duration = Date.now() - startTime;
123
+ const workerResult = {
124
+ id: task.id,
125
+ result: null,
126
+ error: error instanceof Error ? error : new Error(String(error)),
127
+ duration
128
+ };
129
+ worker_threads_1.parentPort?.postMessage(workerResult);
130
+ }
131
+ });
132
+ worker_threads_1.parentPort?.postMessage({
133
+ type: 'worker_ready',
134
+ workerId: worker_threads_1.workerData?.workerId || 0,
135
+ pid: process.pid
136
+ });
137
+ process.on('SIGTERM', () => {
138
+ worker_threads_1.parentPort?.postMessage({
139
+ type: 'worker_shutdown',
140
+ workerId: worker_threads_1.workerData?.workerId || 0
141
+ });
142
+ process.exit(0);
143
+ });
144
+ process.on('SIGINT', () => {
145
+ worker_threads_1.parentPort?.postMessage({
146
+ type: 'worker_shutdown',
147
+ workerId: worker_threads_1.workerData?.workerId || 0
148
+ });
149
+ process.exit(0);
150
+ });
151
+ }
152
+ main().catch(error => {
153
+ console.error('Worker initialization failed:', error);
154
+ process.exit(1);
155
+ });
156
+ function chunkData(data, chunkSize) {
157
+ const chunks = [];
158
+ for (let i = 0; i < data.length; i += chunkSize) {
159
+ chunks.push(data.slice(i, i + chunkSize));
160
+ }
161
+ return chunks;
162
+ }
163
+ function mergeChunkResults(chunkResults) {
164
+ return chunkResults.flat();
165
+ }
166
+ function createChunkTasks(data, chunkSize, taskType, options) {
167
+ const chunks = chunkData(data, chunkSize);
168
+ return chunks.map((chunk, index) => ({
169
+ id: `chunk_${index}_${Date.now()}`,
170
+ type: taskType,
171
+ data: chunk,
172
+ options: {
173
+ ...options,
174
+ chunkIndex: index,
175
+ totalChunks: chunks.length
176
+ }
177
+ }));
178
+ }
179
+ //# sourceMappingURL=csv-parser.worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv-parser.worker.js","sourceRoot":"","sources":["../../../src/workers/csv-parser.worker.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Worker для парсинга CSV данных\r\n * \r\n * Выполняется в отдельном потоке для многопоточной обработки\r\n */\r\n\r\nimport { parentPort, workerData, isMainThread } from 'worker_threads';\r\nimport { WorkerTask, WorkerResult } from '../types';\r\n\r\n// Импортируем функции парсинга из основных модулей\r\n// Используем динамический импорт чтобы избежать циклических зависимостей\r\nlet csvToJson: any = null;\r\nlet jsonToCsv: any = null;\r\n\r\n/**\r\n * Инициализирует функции парсинга\r\n */\r\nasync function initializeParserFunctions(): Promise<void> {\r\n if (!csvToJson) {\r\n // Динамический импорт чтобы избежать проблем с циклическими зависимостями\r\n const csvModule = await import('../../csv-to-json');\r\n csvToJson = csvModule.csvToJson;\r\n }\r\n \r\n if (!jsonToCsv) {\r\n const jsonModule = await import('../../json-to-csv');\r\n jsonToCsv = jsonModule.jsonToCsv;\r\n }\r\n}\r\n\r\n/**\r\n * Обрабатывает задачу парсинга CSV\r\n */\r\nasync function processCsvParsing(task: WorkerTask): Promise<any> {\r\n await initializeParserFunctions();\r\n \r\n const { data, options } = task;\r\n \r\n if (typeof data !== 'string') {\r\n throw new Error('CSV data must be a string');\r\n }\r\n \r\n return csvToJson(data, options);\r\n}\r\n\r\n/**\r\n * Обрабатывает задачу конвертации JSON в CSV\r\n */\r\nasync function processJsonToCsv(task: WorkerTask): Promise<any> {\r\n await initializeParserFunctions();\r\n \r\n const { data, options } = task;\r\n \r\n if (!Array.isArray(data) && (typeof data !== 'object' || data === null)) {\r\n throw new Error('JSON data must be an array or object');\r\n }\r\n \r\n return jsonToCsv(data, options);\r\n}\r\n\r\n/**\r\n * Обрабатывает задачу обработки чанка данных\r\n */\r\nasync function processDataChunk(task: WorkerTask): Promise<any> {\r\n const { type, data, options } = task;\r\n \r\n switch (type) {\r\n case 'csv_parse':\r\n return processCsvParsing(task);\r\n \r\n case 'json_to_csv':\r\n return processJsonToCsv(task);\r\n \r\n case 'transform_data':\r\n // Простая трансформация данных\r\n if (Array.isArray(data)) {\r\n return data.map((item, index) => ({\r\n ...item,\r\n _workerId: workerData?.workerId || 0,\r\n _chunkIndex: index\r\n }));\r\n }\r\n return data;\r\n \r\n case 'validate_data':\r\n // Валидация данных\r\n if (Array.isArray(data)) {\r\n const invalidItems = data.filter(item => \r\n item === null || item === undefined || \r\n (typeof item === 'object' && Object.keys(item).length === 0)\r\n );\r\n \r\n return {\r\n valid: invalidItems.length === 0,\r\n totalItems: data.length,\r\n invalidItems: invalidItems.length,\r\n invalidIndexes: data\r\n .map((item, index) => ({ item, index }))\r\n .filter(({ item }) => \r\n item === null || item === undefined || \r\n (typeof item === 'object' && Object.keys(item).length === 0)\r\n )\r\n .map(({ index }) => index)\r\n };\r\n }\r\n return { valid: true, totalItems: 1 };\r\n \r\n default:\r\n throw new Error(`Unknown task type: ${type}`);\r\n }\r\n}\r\n\r\n/**\r\n * Основная функция воркера\r\n */\r\nasync function main() {\r\n if (isMainThread) {\r\n console.error('Worker script should not be run in main thread');\r\n process.exit(1);\r\n }\r\n \r\n // Регистрируем обработчик сообщений\r\n parentPort?.on('message', async (task: WorkerTask) => {\r\n const startTime = Date.now();\r\n \r\n try {\r\n const result = await processDataChunk(task);\r\n const duration = Date.now() - startTime;\r\n \r\n const workerResult: WorkerResult = {\r\n id: task.id,\r\n result,\r\n duration\r\n };\r\n \r\n parentPort?.postMessage(workerResult);\r\n } catch (error: any) {\r\n const duration = Date.now() - startTime;\r\n \r\n const workerResult: WorkerResult = {\r\n id: task.id,\r\n result: null,\r\n error: error instanceof Error ? error : new Error(String(error)),\r\n duration\r\n };\r\n \r\n parentPort?.postMessage(workerResult);\r\n }\r\n });\r\n \r\n // Отправляем сообщение о готовности\r\n parentPort?.postMessage({\r\n type: 'worker_ready',\r\n workerId: workerData?.workerId || 0,\r\n pid: process.pid\r\n });\r\n \r\n // Обрабатываем сигналы завершения\r\n process.on('SIGTERM', () => {\r\n parentPort?.postMessage({\r\n type: 'worker_shutdown',\r\n workerId: workerData?.workerId || 0\r\n });\r\n process.exit(0);\r\n });\r\n \r\n process.on('SIGINT', () => {\r\n parentPort?.postMessage({\r\n type: 'worker_shutdown',\r\n workerId: workerData?.workerId || 0\r\n });\r\n process.exit(0);\r\n });\r\n}\r\n\r\n// Запускаем воркер\r\nmain().catch(error => {\r\n console.error('Worker initialization failed:', error);\r\n process.exit(1);\r\n});\r\n\r\n/**\r\n * Утилитарные функции для воркера\r\n */\r\n\r\n/**\r\n * Разделяет данные на чанки для параллельной обработки\r\n */\r\nexport function chunkData<T>(data: T[], chunkSize: number): T[][] {\r\n const chunks: T[][] = [];\r\n \r\n for (let i = 0; i < data.length; i += chunkSize) {\r\n chunks.push(data.slice(i, i + chunkSize));\r\n }\r\n \r\n return chunks;\r\n}\r\n\r\n/**\r\n * Объединяет результаты обработки чанков\r\n */\r\nexport function mergeChunkResults<T>(chunkResults: T[][]): T[] {\r\n return chunkResults.flat();\r\n}\r\n\r\n/**\r\n * Создает задачи для обработки чанков\r\n */\r\nexport function createChunkTasks<T, R>(\r\n data: T[],\r\n chunkSize: number,\r\n taskType: string,\r\n options?: Record<string, any>\r\n): WorkerTask<T[], R>[] {\r\n const chunks = chunkData(data, chunkSize);\r\n \r\n return chunks.map((chunk, index) => ({\r\n id: `chunk_${index}_${Date.now()}`,\r\n type: taskType,\r\n data: chunk,\r\n options: {\r\n ...options,\r\n chunkIndex: index,\r\n totalChunks: chunks.length\r\n }\r\n }));\r\n}"]}