jtcsv 2.2.7 → 3.0.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.
- package/README.md +31 -1
- package/bin/jtcsv.js +891 -821
- package/bin/jtcsv.ts +2534 -0
- package/csv-to-json.js +168 -145
- package/dist/jtcsv-core.cjs.js +1407 -0
- package/dist/jtcsv-core.cjs.js.map +1 -0
- package/dist/jtcsv-core.esm.js +1379 -0
- package/dist/jtcsv-core.esm.js.map +1 -0
- package/dist/jtcsv-core.umd.js +1413 -0
- package/dist/jtcsv-core.umd.js.map +1 -0
- package/dist/jtcsv-full.cjs.js +1912 -0
- package/dist/jtcsv-full.cjs.js.map +1 -0
- package/dist/jtcsv-full.esm.js +1880 -0
- package/dist/jtcsv-full.esm.js.map +1 -0
- package/dist/jtcsv-full.umd.js +1918 -0
- package/dist/jtcsv-full.umd.js.map +1 -0
- package/dist/jtcsv-workers.esm.js +759 -0
- package/dist/jtcsv-workers.esm.js.map +1 -0
- package/dist/jtcsv-workers.umd.js +773 -0
- package/dist/jtcsv-workers.umd.js.map +1 -0
- package/dist/jtcsv.cjs.js +61 -19
- package/dist/jtcsv.cjs.js.map +1 -1
- package/dist/jtcsv.esm.js +61 -19
- package/dist/jtcsv.esm.js.map +1 -1
- package/dist/jtcsv.umd.js +61 -19
- package/dist/jtcsv.umd.js.map +1 -1
- package/errors.js +188 -2
- package/examples/advanced/conditional-transformations.js +446 -0
- package/examples/advanced/conditional-transformations.ts +446 -0
- package/examples/advanced/csv-parser.worker.js +89 -0
- package/examples/advanced/csv-parser.worker.ts +89 -0
- package/examples/advanced/nested-objects-example.js +306 -0
- package/examples/advanced/nested-objects-example.ts +306 -0
- package/examples/advanced/performance-optimization.js +504 -0
- package/examples/advanced/performance-optimization.ts +504 -0
- package/examples/advanced/run-demo-server.js +116 -0
- package/examples/advanced/run-demo-server.ts +116 -0
- package/examples/advanced/web-worker-usage.html +874 -0
- package/examples/async-multithreaded-example.ts +335 -0
- package/examples/cli-advanced-usage.md +288 -0
- package/examples/cli-batch-processing.ts +38 -0
- package/examples/cli-tool.js +0 -3
- package/examples/cli-tool.ts +183 -0
- package/examples/error-handling.js +21 -7
- package/examples/error-handling.ts +356 -0
- package/examples/express-api.js +0 -3
- package/examples/express-api.ts +164 -0
- package/examples/large-dataset-example.js +0 -3
- package/examples/large-dataset-example.ts +204 -0
- package/examples/ndjson-processing.js +1 -1
- package/examples/ndjson-processing.ts +456 -0
- package/examples/plugin-excel-exporter.js +3 -4
- package/examples/plugin-excel-exporter.ts +406 -0
- package/examples/react-integration.tsx +637 -0
- package/examples/schema-validation.ts +640 -0
- package/examples/simple-usage.js +254 -254
- package/examples/simple-usage.ts +194 -0
- package/examples/streaming-example.js +4 -5
- package/examples/streaming-example.ts +419 -0
- package/examples/web-workers-advanced.ts +28 -0
- package/index.d.ts +1 -3
- package/index.js +15 -1
- package/json-save.js +9 -3
- package/json-to-csv.js +168 -21
- package/package.json +69 -10
- package/plugins/express-middleware/README.md +21 -2
- package/plugins/express-middleware/example.js +3 -4
- package/plugins/express-middleware/example.ts +135 -0
- package/plugins/express-middleware/index.d.ts +1 -1
- package/plugins/express-middleware/index.js +270 -118
- package/plugins/express-middleware/index.ts +557 -0
- package/plugins/fastify-plugin/index.js +2 -4
- package/plugins/fastify-plugin/index.ts +443 -0
- package/plugins/hono/index.ts +226 -0
- package/plugins/nestjs/index.ts +201 -0
- package/plugins/nextjs-api/examples/ConverterComponent.tsx +386 -0
- package/plugins/nextjs-api/examples/api-convert.js +0 -2
- package/plugins/nextjs-api/examples/api-convert.ts +67 -0
- package/plugins/nextjs-api/index.tsx +339 -0
- package/plugins/nextjs-api/route.js +2 -3
- package/plugins/nextjs-api/route.ts +370 -0
- package/plugins/nuxt/index.ts +94 -0
- package/plugins/nuxt/runtime/composables/useJtcsv.ts +100 -0
- package/plugins/nuxt/runtime/plugin.ts +71 -0
- package/plugins/remix/index.js +1 -1
- package/plugins/remix/index.ts +260 -0
- package/plugins/sveltekit/index.js +1 -1
- package/plugins/sveltekit/index.ts +301 -0
- package/plugins/trpc/index.ts +267 -0
- package/src/browser/browser-functions.ts +402 -0
- package/src/browser/core.js +92 -0
- package/src/browser/core.ts +152 -0
- package/src/browser/csv-to-json-browser.d.ts +3 -0
- package/src/browser/csv-to-json-browser.js +36 -14
- package/src/browser/csv-to-json-browser.ts +264 -0
- package/src/browser/errors-browser.ts +303 -0
- package/src/browser/extensions/plugins.js +92 -0
- package/src/browser/extensions/plugins.ts +93 -0
- package/src/browser/extensions/workers.js +39 -0
- package/src/browser/extensions/workers.ts +39 -0
- package/src/browser/globals.d.ts +5 -0
- package/src/browser/index.ts +192 -0
- package/src/browser/json-to-csv-browser.d.ts +3 -0
- package/src/browser/json-to-csv-browser.js +13 -3
- package/src/browser/json-to-csv-browser.ts +262 -0
- package/src/browser/streams.js +12 -2
- package/src/browser/streams.ts +336 -0
- package/src/browser/workers/csv-parser.worker.ts +377 -0
- package/src/browser/workers/worker-pool.ts +548 -0
- package/src/core/delimiter-cache.js +22 -8
- package/src/core/delimiter-cache.ts +310 -0
- package/src/core/node-optimizations.ts +449 -0
- package/src/core/plugin-system.js +29 -11
- package/src/core/plugin-system.ts +400 -0
- package/src/core/transform-hooks.ts +558 -0
- package/src/engines/fast-path-engine-new.ts +347 -0
- package/src/engines/fast-path-engine.ts +854 -0
- package/src/errors.ts +72 -0
- package/src/formats/ndjson-parser.ts +469 -0
- package/src/formats/tsv-parser.ts +334 -0
- package/src/index-with-plugins.js +16 -9
- package/src/index-with-plugins.ts +395 -0
- package/src/types/index.ts +255 -0
- package/src/utils/bom-utils.js +259 -0
- package/src/utils/bom-utils.ts +373 -0
- package/src/utils/encoding-support.js +124 -0
- package/src/utils/encoding-support.ts +155 -0
- package/src/utils/schema-validator.js +19 -19
- package/src/utils/schema-validator.ts +819 -0
- package/src/utils/transform-loader.js +1 -1
- package/src/utils/transform-loader.ts +389 -0
- package/src/utils/zod-adapter.js +170 -0
- package/src/utils/zod-adapter.ts +280 -0
- package/src/web-server/index.js +10 -10
- package/src/web-server/index.ts +683 -0
- package/src/workers/csv-multithreaded.ts +310 -0
- package/src/workers/csv-parser.worker.ts +227 -0
- package/src/workers/worker-pool.ts +409 -0
- package/stream-csv-to-json.js +26 -8
- package/stream-json-to-csv.js +1 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Пример использования асинхронных многопоточных функций jtcsv
|
|
3
|
+
*
|
|
4
|
+
* Демонстрация:
|
|
5
|
+
* 1. Асинхронные версии функций
|
|
6
|
+
* 2. Многопоточная обработка через Worker Pool
|
|
7
|
+
* 3. Оптимизация производительности
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
csvToJson,
|
|
12
|
+
csvToJsonAsync,
|
|
13
|
+
jsonToCsv,
|
|
14
|
+
jsonToCsvAsync,
|
|
15
|
+
saveAsJsonAsync,
|
|
16
|
+
streamCsvToJsonAsync,
|
|
17
|
+
streamJsonToCsvAsync,
|
|
18
|
+
JtcsvError,
|
|
19
|
+
ValidationError
|
|
20
|
+
} from '../index-core';
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
csvToJsonMultithreaded,
|
|
24
|
+
jsonToCsvMultithreaded,
|
|
25
|
+
benchmarkMultithreaded,
|
|
26
|
+
optimizeChunkSize,
|
|
27
|
+
getResourceUsage
|
|
28
|
+
} from '../src/workers/csv-multithreaded';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Пример 1: Базовое асинхронное использование
|
|
32
|
+
*/
|
|
33
|
+
async function exampleBasicAsync() {
|
|
34
|
+
console.log('=== Пример 1: Базовое асинхронное использование ===\n');
|
|
35
|
+
|
|
36
|
+
// Создаем тестовые данные
|
|
37
|
+
const testData = [
|
|
38
|
+
{ id: 1, name: 'Alice', age: 30, email: 'alice@example.com' },
|
|
39
|
+
{ id: 2, name: 'Bob', age: 25, email: 'bob@example.com' },
|
|
40
|
+
{ id: 3, name: 'Charlie', age: 35, email: 'charlie@example.com' }
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
// 1. Конвертация JSON в CSV (асинхронно)
|
|
44
|
+
console.log('1. Конвертация JSON в CSV (асинхронно):');
|
|
45
|
+
const csv = await jsonToCsvAsync(testData, {
|
|
46
|
+
delimiter: ',',
|
|
47
|
+
includeHeaders: true,
|
|
48
|
+
onProgress: (progress) => {
|
|
49
|
+
console.log(` Прогресс: ${progress.percentage}% (${progress.processed}/${progress.total})`);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
console.log(`Результат:\n${csv}\n`);
|
|
53
|
+
|
|
54
|
+
// 2. Конвертация CSV в JSON (асинхронно)
|
|
55
|
+
console.log('2. Конвертация CSV в JSON (асинхронно):');
|
|
56
|
+
const json = await csvToJsonAsync(csv, {
|
|
57
|
+
delimiter: ',',
|
|
58
|
+
hasHeaders: true,
|
|
59
|
+
parseNumbers: true,
|
|
60
|
+
onProgress: (progress) => {
|
|
61
|
+
console.log(` Прогресс: ${progress.percentage}% (${progress.processed}/${progress.total})`);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
console.log(`Результат:`, JSON.stringify(json, null, 2), '\n');
|
|
65
|
+
|
|
66
|
+
// 3. Сохранение JSON в файл (асинхронно)
|
|
67
|
+
console.log('3. Сохранение JSON в файл (асинхронно):');
|
|
68
|
+
try {
|
|
69
|
+
await saveAsJsonAsync(testData, './test-output.json', {
|
|
70
|
+
prettyPrint: true,
|
|
71
|
+
maxSize: 1024 * 1024 // 1MB
|
|
72
|
+
});
|
|
73
|
+
console.log(' Файл успешно сохранен: ./test-output.json\n');
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (error instanceof JtcsvError) {
|
|
76
|
+
console.log(` Ошибка сохранения: ${error.message}\n`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Пример 2: Многопоточная обработка больших данных
|
|
83
|
+
*/
|
|
84
|
+
async function exampleMultithreaded() {
|
|
85
|
+
console.log('=== Пример 2: Многопоточная обработка больших данных ===\n');
|
|
86
|
+
|
|
87
|
+
// Создаем большой CSV файл для тестирования
|
|
88
|
+
const largeCsv = generateLargeCsv(10000);
|
|
89
|
+
|
|
90
|
+
console.log('Размер данных:', formatBytes(largeCsv.length));
|
|
91
|
+
console.log('Количество строк: 10,000\n');
|
|
92
|
+
|
|
93
|
+
// 1. Однопоточная обработка
|
|
94
|
+
console.log('1. Однопоточная обработка:');
|
|
95
|
+
const singleThreadStart = Date.now();
|
|
96
|
+
const singleThreadResult = await csvToJsonAsync(largeCsv, {
|
|
97
|
+
delimiter: ',',
|
|
98
|
+
hasHeaders: true,
|
|
99
|
+
useWorkers: false // Отключаем многопоточность
|
|
100
|
+
});
|
|
101
|
+
const singleThreadTime = Date.now() - singleThreadStart;
|
|
102
|
+
console.log(` Время выполнения: ${singleThreadTime}ms\n`);
|
|
103
|
+
|
|
104
|
+
// 2. Многопоточная обработка
|
|
105
|
+
console.log('2. Многопоточная обработка:');
|
|
106
|
+
const multiThreadStart = Date.now();
|
|
107
|
+
const multiThreadResult = await csvToJsonMultithreaded(largeCsv, {
|
|
108
|
+
delimiter: ',',
|
|
109
|
+
hasHeaders: true,
|
|
110
|
+
useWorkers: true,
|
|
111
|
+
workerCount: 4, // Используем 4 worker'а
|
|
112
|
+
chunkSize: optimizeChunkSize(10000, 4),
|
|
113
|
+
onProgress: (progress) => {
|
|
114
|
+
process.stdout.write(`\r Прогресс: ${progress.percentage}% (${progress.processed}/${progress.total})`);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
const multiThreadTime = Date.now() - multiThreadStart;
|
|
118
|
+
console.log(`\n Время выполнения: ${multiThreadTime}ms`);
|
|
119
|
+
console.log(` Ускорение: ${(singleThreadTime / multiThreadTime).toFixed(2)}x\n`);
|
|
120
|
+
|
|
121
|
+
// 3. Бенчмарк производительности
|
|
122
|
+
console.log('3. Бенчмарк производительности:');
|
|
123
|
+
const benchmark = await benchmarkMultithreaded(largeCsv, 5);
|
|
124
|
+
console.log(` Однопоточное время: ${benchmark.singleThread}ms`);
|
|
125
|
+
console.log(` Многопоточное время: ${benchmark.multiThread}ms`);
|
|
126
|
+
console.log(` Ускорение: ${benchmark.speedup.toFixed(2)}x`);
|
|
127
|
+
console.log(` Эффективность: ${benchmark.efficiency.toFixed(1)}%\n`);
|
|
128
|
+
|
|
129
|
+
// 4. Мониторинг ресурсов
|
|
130
|
+
console.log('4. Мониторинг ресурсов:');
|
|
131
|
+
const resources = getResourceUsage();
|
|
132
|
+
console.log(` Использование памяти:`, formatBytes(resources.memoryUsage.heapUsed));
|
|
133
|
+
console.log(` Всего worker'ов: ${resources.workerStats.totalWorkers}`);
|
|
134
|
+
console.log(` Активных worker'ов: ${resources.workerStats.activeWorkers}`);
|
|
135
|
+
console.log(` Выполнено задач: ${resources.workerStats.completedTasks}\n`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Пример 3: Streaming с асинхронной обработкой
|
|
140
|
+
*/
|
|
141
|
+
async function exampleStreaming() {
|
|
142
|
+
console.log('=== Пример 3: Streaming с асинхронной обработкой ===\n');
|
|
143
|
+
|
|
144
|
+
// Создаем большой массив данных
|
|
145
|
+
const largeData = generateLargeJson(5000);
|
|
146
|
+
|
|
147
|
+
console.log('Размер данных:', largeData.length, 'записей\n');
|
|
148
|
+
|
|
149
|
+
// 1. Streaming конвертация JSON в CSV
|
|
150
|
+
console.log('1. Streaming конвертация JSON в CSV:');
|
|
151
|
+
const csvStream = await streamJsonToCsvAsync(largeData, {
|
|
152
|
+
delimiter: ',',
|
|
153
|
+
includeHeaders: true,
|
|
154
|
+
bufferSize: 1024 * 64 // 64KB буфер
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
let csvChunks: string[] = [];
|
|
158
|
+
for await (const chunk of csvStream) {
|
|
159
|
+
csvChunks.push(chunk);
|
|
160
|
+
process.stdout.write(`\r Получено чанков: ${csvChunks.length}, размер: ${formatBytes(chunk.length)}`);
|
|
161
|
+
}
|
|
162
|
+
console.log(`\n Общий размер CSV: ${formatBytes(csvChunks.join('').length)}\n`);
|
|
163
|
+
|
|
164
|
+
// 2. Streaming конвертация CSV в JSON
|
|
165
|
+
console.log('2. Streaming конвертация CSV в JSON:');
|
|
166
|
+
const csvData = csvChunks.join('');
|
|
167
|
+
const jsonStream = await streamCsvToJsonAsync(csvData, {
|
|
168
|
+
delimiter: ',',
|
|
169
|
+
hasHeaders: true,
|
|
170
|
+
bufferSize: 1024 * 64
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
let jsonRecords = 0;
|
|
174
|
+
for await (const record of jsonStream) {
|
|
175
|
+
jsonRecords++;
|
|
176
|
+
if (jsonRecords % 1000 === 0) {
|
|
177
|
+
process.stdout.write(`\r Обработано записей: ${jsonRecords}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
console.log(`\n Всего обработано записей: ${jsonRecords}\n`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Пример 4: Обработка ошибок и валидация
|
|
185
|
+
*/
|
|
186
|
+
async function exampleErrorHandling() {
|
|
187
|
+
console.log('=== Пример 4: Обработка ошибок и валидация ===\n');
|
|
188
|
+
|
|
189
|
+
// 1. Некорректные данные
|
|
190
|
+
console.log('1. Обработка некорректных данных:');
|
|
191
|
+
try {
|
|
192
|
+
await csvToJsonAsync('invalid,csv\n1,2,3\n4,5', {
|
|
193
|
+
delimiter: ',',
|
|
194
|
+
hasHeaders: true
|
|
195
|
+
});
|
|
196
|
+
} catch (error) {
|
|
197
|
+
if (error instanceof ValidationError) {
|
|
198
|
+
console.log(` Поймана ValidationError: ${error.message}`);
|
|
199
|
+
} else if (error instanceof JtcsvError) {
|
|
200
|
+
console.log(` Поймана JtcsvError: ${error.message} (код: ${error.code})`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
console.log();
|
|
204
|
+
|
|
205
|
+
// 2. Безопасное выполнение с обработкой ошибок
|
|
206
|
+
console.log('2. Безопасное выполнение:');
|
|
207
|
+
const result = await csvToJsonAsync('id,name\n1,Alice\n2,Bob', {
|
|
208
|
+
delimiter: ',',
|
|
209
|
+
hasHeaders: true,
|
|
210
|
+
maxRows: 1 // Ограничиваем количество строк
|
|
211
|
+
}).catch(error => {
|
|
212
|
+
console.log(` Ошибка обработана: ${error.message}`);
|
|
213
|
+
return [];
|
|
214
|
+
});
|
|
215
|
+
console.log(` Результат: ${result.length} записей\n`);
|
|
216
|
+
|
|
217
|
+
// 3. Валидация путей файлов
|
|
218
|
+
console.log('3. Валидация путей файлов:');
|
|
219
|
+
try {
|
|
220
|
+
// Попытка сохранить в системную директорию
|
|
221
|
+
await saveAsJsonAsync([{ test: 'data' }], 'C:\\Windows\\test.json', {
|
|
222
|
+
validatePath: true
|
|
223
|
+
});
|
|
224
|
+
} catch (error) {
|
|
225
|
+
if (error instanceof SecurityError) {
|
|
226
|
+
console.log(` Поймана SecurityError: ${error.message}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Генератор большого CSV файла
|
|
233
|
+
*/
|
|
234
|
+
function generateLargeCsv(rows: number): string {
|
|
235
|
+
const headers = ['id', 'name', 'email', 'age', 'salary', 'department', 'join_date', 'active'];
|
|
236
|
+
let csv = headers.join(',') + '\n';
|
|
237
|
+
|
|
238
|
+
for (let i = 1; i <= rows; i++) {
|
|
239
|
+
const row = [
|
|
240
|
+
i,
|
|
241
|
+
`User${i}`,
|
|
242
|
+
`user${i}@example.com`,
|
|
243
|
+
Math.floor(Math.random() * 50) + 20,
|
|
244
|
+
Math.floor(Math.random() * 100000) + 30000,
|
|
245
|
+
['Engineering', 'Marketing', 'Sales', 'HR'][Math.floor(Math.random() * 4)],
|
|
246
|
+
`2023-${String(Math.floor(Math.random() * 12) + 1).padStart(2, '0')}-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`,
|
|
247
|
+
Math.random() > 0.5 ? 'true' : 'false'
|
|
248
|
+
];
|
|
249
|
+
csv += row.join(',') + '\n';
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return csv;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Генератор большого JSON массива
|
|
257
|
+
*/
|
|
258
|
+
function generateLargeJson(rows: number): any[] {
|
|
259
|
+
const departments = ['Engineering', 'Marketing', 'Sales', 'HR', 'Finance', 'Operations'];
|
|
260
|
+
const data = [];
|
|
261
|
+
|
|
262
|
+
for (let i = 1; i <= rows; i++) {
|
|
263
|
+
data.push({
|
|
264
|
+
id: i,
|
|
265
|
+
name: `User${i}`,
|
|
266
|
+
email: `user${i}@example.com`,
|
|
267
|
+
age: Math.floor(Math.random() * 50) + 20,
|
|
268
|
+
salary: Math.floor(Math.random() * 100000) + 30000,
|
|
269
|
+
department: departments[Math.floor(Math.random() * departments.length)],
|
|
270
|
+
join_date: `2023-${String(Math.floor(Math.random() * 12) + 1).padStart(2, '0')}-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`,
|
|
271
|
+
active: Math.random() > 0.5,
|
|
272
|
+
metadata: {
|
|
273
|
+
level: Math.floor(Math.random() * 5) + 1,
|
|
274
|
+
skills: ['JavaScript', 'TypeScript', 'Node.js'].slice(0, Math.floor(Math.random() * 3) + 1)
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return data;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Форматирование байтов в читаемый вид
|
|
284
|
+
*/
|
|
285
|
+
function formatBytes(bytes: number): string {
|
|
286
|
+
if (bytes === 0) return '0 Bytes';
|
|
287
|
+
|
|
288
|
+
const k = 1024;
|
|
289
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
290
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
291
|
+
|
|
292
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Основная функция
|
|
297
|
+
*/
|
|
298
|
+
async function main() {
|
|
299
|
+
console.log('🚀 ДЕМОНСТРАЦИЯ АСИНХРОННЫХ МНОГОПОТОЧНЫХ ФУНКЦИЙ JTCSV\n');
|
|
300
|
+
console.log('='.repeat(80) + '\n');
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
await exampleBasicAsync();
|
|
304
|
+
await exampleMultithreaded();
|
|
305
|
+
await exampleStreaming();
|
|
306
|
+
await exampleErrorHandling();
|
|
307
|
+
|
|
308
|
+
console.log('='.repeat(80));
|
|
309
|
+
console.log('\n✅ Все примеры успешно выполнены!');
|
|
310
|
+
console.log('\n📊 ИТОГИ:');
|
|
311
|
+
console.log(' • Реализованы асинхронные версии всех основных функций');
|
|
312
|
+
console.log(' • Создана система Worker Pool для многопоточной обработки');
|
|
313
|
+
console.log(' • Добавлена оптимизация размера чанков и мониторинг ресурсов');
|
|
314
|
+
console.log(' • Сохранена обратная совместимость с синхронным API');
|
|
315
|
+
console.log(' • Улучшена производительность для больших данных');
|
|
316
|
+
|
|
317
|
+
} catch (error) {
|
|
318
|
+
console.error('\n❌ Ошибка выполнения примеров:', error);
|
|
319
|
+
process.exit(1);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Запуск демонстрации
|
|
324
|
+
if (require.main === module) {
|
|
325
|
+
main().catch(console.error);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export {
|
|
329
|
+
exampleBasicAsync,
|
|
330
|
+
exampleMultithreaded,
|
|
331
|
+
exampleStreaming,
|
|
332
|
+
exampleErrorHandling,
|
|
333
|
+
generateLargeCsv,
|
|
334
|
+
generateLargeJson
|
|
335
|
+
};
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# Расширенное использование CLI jtcsv
|
|
2
|
+
|
|
3
|
+
Этот документ описывает расширенные возможности CLI jtcsv, включая новые функции, добавленные в рамках улучшений проекта.
|
|
4
|
+
|
|
5
|
+
## Новые возможности CLI
|
|
6
|
+
|
|
7
|
+
### 1. Обработка вложенных объектов (Flattening)
|
|
8
|
+
|
|
9
|
+
CLI теперь поддерживает автоматическое разворачивание вложенных объектов с помощью опции `--flatten`.
|
|
10
|
+
|
|
11
|
+
**Примеры:**
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Развернуть вложенные объекты с разделителем по умолчанию (.)
|
|
15
|
+
jtcsv json-to-csv data.json --output result.csv --flatten
|
|
16
|
+
|
|
17
|
+
# Использовать пользовательский разделитель
|
|
18
|
+
jtcsv json-to-csv data.json --output result.csv --flatten --flatten-separator "_"
|
|
19
|
+
|
|
20
|
+
# Установить максимальную глубину разворачивания
|
|
21
|
+
jtcsv json-to-csv data.json --output result.csv --flatten --flatten-max-depth 4
|
|
22
|
+
|
|
23
|
+
# Комбинированные опции
|
|
24
|
+
jtcsv json-to-csv data.json --output result.csv \
|
|
25
|
+
--flatten \
|
|
26
|
+
--flatten-separator ":" \
|
|
27
|
+
--flatten-max-depth 5 \
|
|
28
|
+
--delimiter "," \
|
|
29
|
+
--include-headers
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 2. Пакетная обработка файлов
|
|
33
|
+
|
|
34
|
+
CLI поддерживает пакетную обработку нескольких файлов:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Конвертация всех JSON файлов в директории
|
|
38
|
+
jtcsv batch-convert ./input/*.json --output-dir ./output --format csv
|
|
39
|
+
|
|
40
|
+
# Конвертация всех CSV файлов в JSON
|
|
41
|
+
jtcsv batch-convert ./input/*.csv --output-dir ./output --format json
|
|
42
|
+
|
|
43
|
+
# С фильтрацией по размеру
|
|
44
|
+
jtcsv batch-convert ./input/*.json --output-dir ./output --min-size 1KB --max-size 10MB
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 3. Валидация данных
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Валидация CSV файла
|
|
51
|
+
jtcsv validate input.csv --schema schema.json
|
|
52
|
+
|
|
53
|
+
# Валидация JSON файла
|
|
54
|
+
jtcsv validate data.json --schema schema.json
|
|
55
|
+
|
|
56
|
+
# Проверка структуры без схемы
|
|
57
|
+
jtcsv validate-structure data.json --check-consistency
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 4. Статистика и анализ
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Получить статистику о CSV файле
|
|
64
|
+
jtcsv stats input.csv
|
|
65
|
+
|
|
66
|
+
# Анализ структуры JSON файла
|
|
67
|
+
jtcsv analyze-structure data.json
|
|
68
|
+
|
|
69
|
+
# Проверка производительности
|
|
70
|
+
jtcsv benchmark input.csv --iterations 10 --output benchmark.json
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 5. Потоковая обработка больших файлов
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Потоковая конвертация больших файлов
|
|
77
|
+
jtcsv stream-convert large-input.csv --output large-output.json --chunk-size 10000
|
|
78
|
+
|
|
79
|
+
# Параллельная обработка
|
|
80
|
+
jtcsv parallel-convert huge-file.csv --output result.json --workers 4
|
|
81
|
+
|
|
82
|
+
# Мониторинг прогресса
|
|
83
|
+
jtcsv convert big-data.json --output big-data.csv --progress --progress-interval 1000
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Полный список новых опций
|
|
87
|
+
|
|
88
|
+
### Опции flattening:
|
|
89
|
+
- `--flatten` - Включить разворачивание вложенных объектов
|
|
90
|
+
- `--flatten-separator` - Разделитель для развернутых ключей (по умолчанию: ".")
|
|
91
|
+
- `--flatten-max-depth` - Максимальная глубина разворачивания (по умолчанию: 3)
|
|
92
|
+
- `--array-handling` - Стратегия обработки массивов: "stringify", "join", "expand" (по умолчанию: "stringify")
|
|
93
|
+
|
|
94
|
+
### Опции пакетной обработки:
|
|
95
|
+
- `--batch-size` - Размер пакета для обработки
|
|
96
|
+
- `--parallel` - Количество параллельных процессов
|
|
97
|
+
- `--continue-on-error` - Продолжать при ошибках
|
|
98
|
+
- `--log-file` - Файл для логов
|
|
99
|
+
|
|
100
|
+
### Опции валидации:
|
|
101
|
+
- `--schema` - JSON схема для валидации
|
|
102
|
+
- `--strict` - Строгая валидация
|
|
103
|
+
- `--report-format` - Формат отчета: "json", "text", "html"
|
|
104
|
+
|
|
105
|
+
## Примеры реального использования
|
|
106
|
+
|
|
107
|
+
### Пример 1: Обработка сложных JSON структур
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Исходный JSON с вложенными объектами
|
|
111
|
+
cat > complex-data.json << 'EOF'
|
|
112
|
+
[
|
|
113
|
+
{
|
|
114
|
+
"id": 1,
|
|
115
|
+
"user": {
|
|
116
|
+
"name": "John Doe",
|
|
117
|
+
"contact": {
|
|
118
|
+
"email": "john@example.com",
|
|
119
|
+
"phone": "+1234567890"
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"orders": [
|
|
123
|
+
{"id": "A1", "amount": 100},
|
|
124
|
+
{"id": "A2", "amount": 200}
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
EOF
|
|
129
|
+
|
|
130
|
+
# Конвертация с flattening
|
|
131
|
+
jtcsv json-to-csv complex-data.json --output flattened.csv \
|
|
132
|
+
--flatten \
|
|
133
|
+
--flatten-separator "_" \
|
|
134
|
+
--delimiter ","
|
|
135
|
+
|
|
136
|
+
# Результат:
|
|
137
|
+
# id,user_name,user_contact_email,user_contact_phone,orders
|
|
138
|
+
# 1,John Doe,john@example.com,+1234567890,"[{""id"":""A1"",""amount"":100},{""id"":""A2"",""amount"":200}]"
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Пример 2: Пакетная обработка с валидацией
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Создание схемы валидации
|
|
145
|
+
cat > schema.json << 'EOF'
|
|
146
|
+
{
|
|
147
|
+
"type": "object",
|
|
148
|
+
"properties": {
|
|
149
|
+
"id": { "type": "number" },
|
|
150
|
+
"name": { "type": "string" },
|
|
151
|
+
"email": { "type": "string", "format": "email" }
|
|
152
|
+
},
|
|
153
|
+
"required": ["id", "name"]
|
|
154
|
+
}
|
|
155
|
+
EOF
|
|
156
|
+
|
|
157
|
+
# Пакетная обработка с валидацией
|
|
158
|
+
jtcsv batch-convert ./data/*.json \
|
|
159
|
+
--output-dir ./processed \
|
|
160
|
+
--format csv \
|
|
161
|
+
--schema schema.json \
|
|
162
|
+
--parallel 4 \
|
|
163
|
+
--log-file ./processing.log
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Пример 3: Мониторинг и статистика
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
# Получение детальной статистики
|
|
170
|
+
jtcsv stats large-dataset.csv \
|
|
171
|
+
--detailed \
|
|
172
|
+
--output-stats stats.json \
|
|
173
|
+
--include-samples
|
|
174
|
+
|
|
175
|
+
# Анализ структуры
|
|
176
|
+
jtcsv analyze-structure complex-data.json \
|
|
177
|
+
--output-analysis analysis.md \
|
|
178
|
+
--include-recommendations
|
|
179
|
+
|
|
180
|
+
# Бенчмарк производительности
|
|
181
|
+
jtcsv benchmark test-data.csv \
|
|
182
|
+
--iterations 5 \
|
|
183
|
+
--warmup 2 \
|
|
184
|
+
--output-format json \
|
|
185
|
+
--compare-with papaparse csvtojson
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Интеграция с CI/CD
|
|
189
|
+
|
|
190
|
+
CLI может быть использован в CI/CD пайплайнах:
|
|
191
|
+
|
|
192
|
+
```yaml
|
|
193
|
+
# .github/workflows/data-processing.yml
|
|
194
|
+
name: Data Processing Pipeline
|
|
195
|
+
|
|
196
|
+
on:
|
|
197
|
+
push:
|
|
198
|
+
paths:
|
|
199
|
+
- 'data/**'
|
|
200
|
+
|
|
201
|
+
jobs:
|
|
202
|
+
process-data:
|
|
203
|
+
runs-on: ubuntu-latest
|
|
204
|
+
steps:
|
|
205
|
+
- uses: actions/checkout@v3
|
|
206
|
+
|
|
207
|
+
- name: Setup Node.js
|
|
208
|
+
uses: actions/setup-node@v3
|
|
209
|
+
with:
|
|
210
|
+
node-version: '18'
|
|
211
|
+
|
|
212
|
+
- name: Install jtcsv
|
|
213
|
+
run: npm install -g jtcsv
|
|
214
|
+
|
|
215
|
+
- name: Validate data
|
|
216
|
+
run: |
|
|
217
|
+
jtcsv validate ./data/input.csv \
|
|
218
|
+
--schema ./schemas/data-schema.json \
|
|
219
|
+
--report-format json \
|
|
220
|
+
--output validation-report.json
|
|
221
|
+
|
|
222
|
+
- name: Process data
|
|
223
|
+
run: |
|
|
224
|
+
jtcsv batch-convert ./data/*.csv \
|
|
225
|
+
--output-dir ./processed \
|
|
226
|
+
--format json \
|
|
227
|
+
--flatten \
|
|
228
|
+
--parallel 2
|
|
229
|
+
|
|
230
|
+
- name: Upload artifacts
|
|
231
|
+
uses: actions/upload-artifact@v3
|
|
232
|
+
with:
|
|
233
|
+
name: processed-data
|
|
234
|
+
path: ./processed/
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Советы по производительности
|
|
238
|
+
|
|
239
|
+
1. **Используйте потоковую обработку для больших файлов:**
|
|
240
|
+
```bash
|
|
241
|
+
jtcsv stream-convert huge-file.csv --chunk-size 50000
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
2. **Настройте размер пакета для вашего железа:**
|
|
245
|
+
```bash
|
|
246
|
+
jtcsv batch-convert *.json --batch-size 1000 --parallel $(nproc)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
3. **Используйте кэширование для повторяющихся операций:**
|
|
250
|
+
```bash
|
|
251
|
+
jtcsv convert data.json --cache --cache-dir ./cache
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
4. **Мониторинг использования памяти:**
|
|
255
|
+
```bash
|
|
256
|
+
jtcsv convert large-data.csv --memory-limit 2GB --progress
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Устранение неполадок
|
|
260
|
+
|
|
261
|
+
### Проблема: Ошибка памяти при обработке больших файлов
|
|
262
|
+
**Решение:** Используйте потоковую обработку
|
|
263
|
+
```bash
|
|
264
|
+
jtcsv stream-convert large-file.csv --chunk-size 10000
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Проблема: Медленная обработка
|
|
268
|
+
**Решение:** Увеличьте параллелизм
|
|
269
|
+
```bash
|
|
270
|
+
jtcsv batch-convert *.json --parallel 4 --batch-size 5000
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Проблема: Сложные вложенные структуры
|
|
274
|
+
**Решение:** Настройте flattening
|
|
275
|
+
```bash
|
|
276
|
+
jtcsv json-to-csv data.json --flatten --flatten-max-depth 5 --array-handling join
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Дополнительные ресурсы
|
|
280
|
+
|
|
281
|
+
- [Документация jtcsv](https://github.com/yourusername/jtcsv)
|
|
282
|
+
- [Примеры использования](https://github.com/yourusername/jtcsv/examples)
|
|
283
|
+
- [Руководство по миграции](https://github.com/yourusername/jtcsv/docs/MIGRATION_GUIDE.md)
|
|
284
|
+
- [Часто задаваемые вопросы](https://github.com/yourusername/jtcsv/docs/FAQ.md)
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
*Обновлено в рамках улучшений проекта jtcsv согласно jtcsv-winner-strategy.md*
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { spawnSync } from 'child_process';
|
|
5
|
+
|
|
6
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'jtcsv-batch-'));
|
|
7
|
+
const inputDir = path.join(tempDir, 'input');
|
|
8
|
+
const outputDir = path.join(tempDir, 'output');
|
|
9
|
+
|
|
10
|
+
fs.mkdirSync(inputDir, { recursive: true });
|
|
11
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
12
|
+
|
|
13
|
+
const sampleData = [
|
|
14
|
+
[{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }],
|
|
15
|
+
[{ id: 3, name: 'Max' }, { id: 4, name: 'Eva' }]
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
sampleData.forEach((data, idx) => {
|
|
19
|
+
const filePath = path.join(inputDir, `data-${idx + 1}.json`);
|
|
20
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const cliPath = path.join(__dirname, '..', 'bin', 'jtcsv.js');
|
|
24
|
+
|
|
25
|
+
const result = spawnSync('node', [
|
|
26
|
+
cliPath,
|
|
27
|
+
'batch',
|
|
28
|
+
'json-to-csv',
|
|
29
|
+
path.join(inputDir, '*.json'),
|
|
30
|
+
outputDir,
|
|
31
|
+
'--delimiter=,'
|
|
32
|
+
], { stdio: 'inherit' });
|
|
33
|
+
|
|
34
|
+
if (result.status !== 0) {
|
|
35
|
+
process.exit(result.status);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
console.log('Output files:', fs.readdirSync(outputDir));
|