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.
- package/README.md +204 -115
- package/bin/jtcsv.ts +2612 -0
- package/browser.d.ts +142 -0
- package/dist/benchmark.js +446 -0
- package/dist/benchmark.js.map +1 -0
- package/dist/bin/jtcsv.js +1940 -0
- package/dist/bin/jtcsv.js.map +1 -0
- package/dist/csv-to-json.js +1262 -0
- package/dist/csv-to-json.js.map +1 -0
- package/dist/errors.js +291 -0
- package/dist/errors.js.map +1 -0
- package/dist/eslint.config.js +147 -0
- package/dist/eslint.config.js.map +1 -0
- package/dist/index-core.js +95 -0
- package/dist/index-core.js.map +1 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/dist/json-save.js +229 -0
- package/dist/json-save.js.map +1 -0
- package/dist/json-to-csv.js +576 -0
- package/dist/json-to-csv.js.map +1 -0
- package/dist/jtcsv-core.cjs.js +1736 -0
- package/dist/jtcsv-core.cjs.js.map +1 -0
- package/dist/jtcsv-core.esm.js +1708 -0
- package/dist/jtcsv-core.esm.js.map +1 -0
- package/dist/jtcsv-core.umd.js +1742 -0
- package/dist/jtcsv-core.umd.js.map +1 -0
- package/dist/jtcsv-full.cjs.js +2241 -0
- package/dist/jtcsv-full.cjs.js.map +1 -0
- package/dist/jtcsv-full.esm.js +2209 -0
- package/dist/jtcsv-full.esm.js.map +1 -0
- package/dist/jtcsv-full.umd.js +2247 -0
- package/dist/jtcsv-full.umd.js.map +1 -0
- package/dist/jtcsv-workers.esm.js +768 -0
- package/dist/jtcsv-workers.esm.js.map +1 -0
- package/dist/jtcsv-workers.umd.js +782 -0
- package/dist/jtcsv-workers.umd.js.map +1 -0
- package/dist/jtcsv.cjs.js +1996 -2048
- package/dist/jtcsv.cjs.js.map +1 -1
- package/dist/jtcsv.esm.js +1992 -2048
- package/dist/jtcsv.esm.js.map +1 -1
- package/dist/jtcsv.umd.js +2157 -2209
- package/dist/jtcsv.umd.js.map +1 -1
- package/dist/plugins/express-middleware/index.js +350 -0
- package/dist/plugins/express-middleware/index.js.map +1 -0
- package/dist/plugins/fastify-plugin/index.js +315 -0
- package/dist/plugins/fastify-plugin/index.js.map +1 -0
- package/dist/plugins/hono/index.js +111 -0
- package/dist/plugins/hono/index.js.map +1 -0
- package/dist/plugins/nestjs/index.js +112 -0
- package/dist/plugins/nestjs/index.js.map +1 -0
- package/dist/plugins/nuxt/index.js +53 -0
- package/dist/plugins/nuxt/index.js.map +1 -0
- package/dist/plugins/remix/index.js +133 -0
- package/dist/plugins/remix/index.js.map +1 -0
- package/dist/plugins/sveltekit/index.js +155 -0
- package/dist/plugins/sveltekit/index.js.map +1 -0
- package/dist/plugins/trpc/index.js +136 -0
- package/dist/plugins/trpc/index.js.map +1 -0
- package/dist/run-demo.js +49 -0
- package/dist/run-demo.js.map +1 -0
- package/dist/src/browser/browser-functions.js +193 -0
- package/dist/src/browser/browser-functions.js.map +1 -0
- package/dist/src/browser/core.js +123 -0
- package/dist/src/browser/core.js.map +1 -0
- package/dist/src/browser/csv-to-json-browser.js +353 -0
- package/dist/src/browser/csv-to-json-browser.js.map +1 -0
- package/dist/src/browser/errors-browser.js +219 -0
- package/dist/src/browser/errors-browser.js.map +1 -0
- package/dist/src/browser/extensions/plugins.js +106 -0
- package/dist/src/browser/extensions/plugins.js.map +1 -0
- package/dist/src/browser/extensions/workers.js +66 -0
- package/dist/src/browser/extensions/workers.js.map +1 -0
- package/dist/src/browser/index.js +140 -0
- package/dist/src/browser/index.js.map +1 -0
- package/dist/src/browser/json-to-csv-browser.js +225 -0
- package/dist/src/browser/json-to-csv-browser.js.map +1 -0
- package/dist/src/browser/streams.js +340 -0
- package/dist/src/browser/streams.js.map +1 -0
- package/dist/src/browser/workers/csv-parser.worker.js +264 -0
- package/dist/src/browser/workers/csv-parser.worker.js.map +1 -0
- package/dist/src/browser/workers/worker-pool.js +338 -0
- package/dist/src/browser/workers/worker-pool.js.map +1 -0
- package/dist/src/core/delimiter-cache.js +196 -0
- package/dist/src/core/delimiter-cache.js.map +1 -0
- package/dist/src/core/node-optimizations.js +279 -0
- package/dist/src/core/node-optimizations.js.map +1 -0
- package/dist/src/core/plugin-system.js +399 -0
- package/dist/src/core/plugin-system.js.map +1 -0
- package/dist/src/core/transform-hooks.js +348 -0
- package/dist/src/core/transform-hooks.js.map +1 -0
- package/dist/src/engines/fast-path-engine-new.js +262 -0
- package/dist/src/engines/fast-path-engine-new.js.map +1 -0
- package/dist/src/engines/fast-path-engine.js +671 -0
- package/dist/src/engines/fast-path-engine.js.map +1 -0
- package/dist/src/errors.js +18 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/formats/ndjson-parser.js +332 -0
- package/dist/src/formats/ndjson-parser.js.map +1 -0
- package/dist/src/formats/tsv-parser.js +230 -0
- package/dist/src/formats/tsv-parser.js.map +1 -0
- package/dist/src/index-with-plugins.js +259 -0
- package/dist/src/index-with-plugins.js.map +1 -0
- package/dist/src/types/index.js +3 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/utils/bom-utils.js +267 -0
- package/dist/src/utils/bom-utils.js.map +1 -0
- package/dist/src/utils/encoding-support.js +77 -0
- package/dist/src/utils/encoding-support.js.map +1 -0
- package/dist/src/utils/schema-validator.js +609 -0
- package/dist/src/utils/schema-validator.js.map +1 -0
- package/dist/src/utils/transform-loader.js +281 -0
- package/dist/src/utils/transform-loader.js.map +1 -0
- package/dist/src/utils/validators.js +40 -0
- package/dist/src/utils/validators.js.map +1 -0
- package/dist/src/utils/zod-adapter.js +144 -0
- package/dist/src/utils/zod-adapter.js.map +1 -0
- package/dist/src/web-server/index.js +648 -0
- package/dist/src/web-server/index.js.map +1 -0
- package/dist/src/workers/csv-multithreaded.js +211 -0
- package/dist/src/workers/csv-multithreaded.js.map +1 -0
- package/dist/src/workers/csv-parser.worker.js +179 -0
- package/dist/src/workers/csv-parser.worker.js.map +1 -0
- package/dist/src/workers/worker-pool.js +228 -0
- package/dist/src/workers/worker-pool.js.map +1 -0
- package/dist/stream-csv-to-json.js +665 -0
- package/dist/stream-csv-to-json.js.map +1 -0
- package/dist/stream-json-to-csv.js +389 -0
- package/dist/stream-json-to-csv.js.map +1 -0
- package/examples/advanced/conditional-transformations.ts +446 -0
- package/examples/advanced/csv-parser.worker.ts +89 -0
- package/examples/advanced/nested-objects-example.ts +306 -0
- package/examples/advanced/performance-optimization.ts +504 -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 +290 -0
- package/examples/{cli-batch-processing.js → cli-batch-processing.ts} +38 -38
- package/examples/{cli-tool.js → cli-tool.ts} +5 -8
- package/examples/{error-handling.js → error-handling.ts} +356 -324
- package/examples/{express-api.js → express-api.ts} +161 -164
- package/examples/{large-dataset-example.js → large-dataset-example.ts} +201 -182
- package/examples/{ndjson-processing.js → ndjson-processing.ts} +456 -434
- package/examples/{plugin-excel-exporter.js → plugin-excel-exporter.ts} +6 -7
- package/examples/react-integration.tsx +637 -0
- package/examples/{schema-validation.js → schema-validation.ts} +2 -2
- package/examples/simple-usage.ts +194 -0
- package/examples/{streaming-example.js → streaming-example.ts} +12 -12
- package/index.d.ts +187 -18
- package/package.json +75 -81
- package/plugins.d.ts +37 -0
- package/schema.d.ts +103 -0
- package/src/browser/browser-functions.ts +402 -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.ts +494 -0
- package/src/browser/{errors-browser.js → errors-browser.ts} +305 -197
- package/src/browser/extensions/plugins.ts +93 -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.ts +338 -0
- package/src/browser/streams.ts +403 -0
- package/src/browser/workers/{csv-parser.worker.js → csv-parser.worker.ts} +3 -3
- package/src/browser/workers/{worker-pool.js → worker-pool.ts} +51 -30
- package/src/core/delimiter-cache.ts +320 -0
- package/src/core/{node-optimizations.js → node-optimizations.ts} +448 -407
- package/src/core/plugin-system.ts +588 -0
- package/src/core/transform-hooks.ts +566 -0
- package/src/engines/{fast-path-engine-new.js → fast-path-engine-new.ts} +11 -2
- package/src/engines/{fast-path-engine.js → fast-path-engine.ts} +79 -53
- package/src/errors.ts +1 -0
- package/src/formats/{ndjson-parser.js → ndjson-parser.ts} +24 -16
- package/src/formats/{tsv-parser.js → tsv-parser.ts} +18 -17
- package/src/{index-with-plugins.js → index-with-plugins.ts} +381 -357
- package/src/types/index.ts +275 -0
- package/src/utils/bom-utils.ts +373 -0
- package/src/utils/encoding-support.ts +155 -0
- package/src/utils/{schema-validator.js → schema-validator.ts} +814 -589
- package/src/utils/transform-loader.ts +389 -0
- package/src/utils/validators.ts +35 -0
- package/src/utils/zod-adapter.ts +280 -0
- package/src/web-server/{index.js → index.ts} +19 -19
- 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/bin/jtcsv.js +0 -2462
- package/csv-to-json.js +0 -688
- package/errors.js +0 -208
- package/examples/simple-usage.js +0 -282
- package/index.js +0 -68
- package/json-save.js +0 -254
- package/json-to-csv.js +0 -526
- package/plugins/README.md +0 -91
- package/plugins/express-middleware/README.md +0 -64
- package/plugins/express-middleware/example.js +0 -136
- package/plugins/express-middleware/index.d.ts +0 -114
- package/plugins/express-middleware/index.js +0 -360
- package/plugins/express-middleware/package.json +0 -52
- package/plugins/fastify-plugin/index.js +0 -406
- package/plugins/fastify-plugin/package.json +0 -55
- package/plugins/hono/README.md +0 -28
- package/plugins/hono/index.d.ts +0 -12
- package/plugins/hono/index.js +0 -36
- package/plugins/hono/package.json +0 -35
- package/plugins/nestjs/README.md +0 -35
- package/plugins/nestjs/index.d.ts +0 -25
- package/plugins/nestjs/index.js +0 -77
- package/plugins/nestjs/package.json +0 -37
- package/plugins/nextjs-api/README.md +0 -57
- package/plugins/nextjs-api/examples/ConverterComponent.jsx +0 -386
- package/plugins/nextjs-api/examples/api-convert.js +0 -69
- package/plugins/nextjs-api/index.js +0 -387
- package/plugins/nextjs-api/package.json +0 -63
- package/plugins/nextjs-api/route.js +0 -371
- package/plugins/nuxt/README.md +0 -24
- package/plugins/nuxt/index.js +0 -21
- package/plugins/nuxt/package.json +0 -35
- package/plugins/nuxt/runtime/composables/useJtcsv.js +0 -6
- package/plugins/nuxt/runtime/plugin.js +0 -6
- package/plugins/remix/README.md +0 -26
- package/plugins/remix/index.d.ts +0 -16
- package/plugins/remix/index.js +0 -62
- package/plugins/remix/package.json +0 -35
- package/plugins/sveltekit/README.md +0 -28
- package/plugins/sveltekit/index.d.ts +0 -17
- package/plugins/sveltekit/index.js +0 -54
- package/plugins/sveltekit/package.json +0 -33
- package/plugins/trpc/README.md +0 -25
- package/plugins/trpc/index.d.ts +0 -7
- package/plugins/trpc/index.js +0 -32
- package/plugins/trpc/package.json +0 -34
- package/src/browser/browser-functions.js +0 -219
- package/src/browser/csv-to-json-browser.js +0 -700
- package/src/browser/index.js +0 -113
- package/src/browser/json-to-csv-browser.js +0 -309
- package/src/browser/streams.js +0 -393
- package/src/core/delimiter-cache.js +0 -186
- package/src/core/plugin-system.js +0 -476
- package/src/core/transform-hooks.js +0 -350
- package/src/errors.js +0 -26
- package/src/utils/transform-loader.js +0 -205
- package/stream-csv-to-json.js +0 -542
- package/stream-json-to-csv.js +0 -464
- /package/examples/{web-workers-advanced.js → web-workers-advanced.ts} +0 -0
|
@@ -1,408 +1,449 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Node.js Runtime Optimizations
|
|
3
|
-
*
|
|
4
|
-
* Detects Node.js version and provides optimized implementations
|
|
5
|
-
* for modern runtimes while maintaining backward compatibility.
|
|
6
|
-
*
|
|
7
|
-
* Optimized for: Node 20, 22, 24
|
|
8
|
-
* Compatible with: Node 12+
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
// Parse Node.js version
|
|
12
|
-
const
|
|
13
|
-
const [major, minor] =
|
|
14
|
-
|
|
15
|
-
// Feature detection flags
|
|
16
|
-
const features = {
|
|
17
|
-
// Node 14.17+ / 16+
|
|
18
|
-
hasAbortController: typeof AbortController !== 'undefined',
|
|
19
|
-
|
|
20
|
-
// Node 15+
|
|
21
|
-
hasPromiseAny: typeof Promise.any === 'function',
|
|
22
|
-
|
|
23
|
-
// Node 16+
|
|
24
|
-
hasArrayAt: typeof Array.prototype.at === 'function',
|
|
25
|
-
hasObjectHasOwn: typeof Object.hasOwn === 'function',
|
|
26
|
-
|
|
27
|
-
// Node 17+
|
|
28
|
-
hasStructuredClone: typeof globalThis.structuredClone === 'function',
|
|
29
|
-
|
|
30
|
-
// Node 18+
|
|
31
|
-
hasFetch: typeof globalThis.fetch === 'function',
|
|
32
|
-
|
|
33
|
-
// Node 20+
|
|
34
|
-
hasWebStreams: typeof globalThis.ReadableStream !== 'undefined' && major >= 20,
|
|
35
|
-
hasArrayGroup: typeof Array.prototype.group === 'function',
|
|
36
|
-
|
|
37
|
-
// Node 21+
|
|
38
|
-
hasSetMethods: typeof Set.prototype.union === 'function',
|
|
39
|
-
|
|
40
|
-
// Node 22+
|
|
41
|
-
hasImportMeta: major >= 22,
|
|
42
|
-
hasExplicitResourceManagement: major >= 22,
|
|
43
|
-
|
|
44
|
-
// Version checks
|
|
45
|
-
isNode20Plus: major >= 20,
|
|
46
|
-
isNode22Plus: major >= 22,
|
|
47
|
-
isNode24Plus: major >= 24
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Optimized Object.hasOwn polyfill for older Node versions
|
|
52
|
-
*/
|
|
53
|
-
const hasOwn = features.hasObjectHasOwn
|
|
54
|
-
? Object.hasOwn
|
|
55
|
-
: (obj, prop) =>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
*
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
*
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
this.
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
this.currentRow
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
*
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
*
|
|
344
|
-
*/
|
|
345
|
-
async *
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Node.js Runtime Optimizations
|
|
3
|
+
*
|
|
4
|
+
* Detects Node.js version and provides optimized implementations
|
|
5
|
+
* for modern runtimes while maintaining backward compatibility.
|
|
6
|
+
*
|
|
7
|
+
* Optimized for: Node 20, 22, 24
|
|
8
|
+
* Compatible with: Node 12+
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Parse Node.js version
|
|
12
|
+
const nodeVersionStr = process.versions?.node || '12.0.0';
|
|
13
|
+
const [major, minor] = nodeVersionStr.split('.').map(Number);
|
|
14
|
+
|
|
15
|
+
// Feature detection flags
|
|
16
|
+
export const features = {
|
|
17
|
+
// Node 14.17+ / 16+
|
|
18
|
+
hasAbortController: typeof AbortController !== 'undefined',
|
|
19
|
+
|
|
20
|
+
// Node 15+
|
|
21
|
+
hasPromiseAny: typeof (Promise as any).any === 'function',
|
|
22
|
+
|
|
23
|
+
// Node 16+
|
|
24
|
+
hasArrayAt: typeof Array.prototype.at === 'function',
|
|
25
|
+
hasObjectHasOwn: typeof (Object as any).hasOwn === 'function',
|
|
26
|
+
|
|
27
|
+
// Node 17+
|
|
28
|
+
hasStructuredClone: typeof globalThis.structuredClone === 'function',
|
|
29
|
+
|
|
30
|
+
// Node 18+
|
|
31
|
+
hasFetch: typeof globalThis.fetch === 'function',
|
|
32
|
+
|
|
33
|
+
// Node 20+
|
|
34
|
+
hasWebStreams: typeof globalThis.ReadableStream !== 'undefined' && major >= 20,
|
|
35
|
+
hasArrayGroup: typeof (Array.prototype as any).group === 'function',
|
|
36
|
+
|
|
37
|
+
// Node 21+
|
|
38
|
+
hasSetMethods: typeof (Set.prototype as any).union === 'function',
|
|
39
|
+
|
|
40
|
+
// Node 22+
|
|
41
|
+
hasImportMeta: major >= 22,
|
|
42
|
+
hasExplicitResourceManagement: major >= 22,
|
|
43
|
+
|
|
44
|
+
// Version checks
|
|
45
|
+
isNode20Plus: major >= 20,
|
|
46
|
+
isNode22Plus: major >= 22,
|
|
47
|
+
isNode24Plus: major >= 24
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Optimized Object.hasOwn polyfill for older Node versions
|
|
52
|
+
*/
|
|
53
|
+
export const hasOwn = features.hasObjectHasOwn
|
|
54
|
+
? (Object as any).hasOwn
|
|
55
|
+
: (obj: object, prop: string | number | symbol): boolean =>
|
|
56
|
+
Object.prototype.hasOwnProperty.call(obj, prop);
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Optimized deep clone function
|
|
60
|
+
* Uses structuredClone on Node 17+ for best performance
|
|
61
|
+
*/
|
|
62
|
+
export const deepClone = features.hasStructuredClone
|
|
63
|
+
? <T>(obj: T): T => structuredClone(obj)
|
|
64
|
+
: <T>(obj: T): T => JSON.parse(JSON.stringify(obj));
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Optimized array access with at() method
|
|
68
|
+
*/
|
|
69
|
+
export const arrayAt = features.hasArrayAt
|
|
70
|
+
? <T>(arr: T[], index: number): T | undefined => arr.at(index)
|
|
71
|
+
: <T>(arr: T[], index: number): T | undefined => {
|
|
72
|
+
const len = arr.length;
|
|
73
|
+
const normalizedIndex = index < 0 ? len + index : index;
|
|
74
|
+
return normalizedIndex >= 0 && normalizedIndex < len ? arr[normalizedIndex] : undefined;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* High-performance string builder for large CSV generation
|
|
79
|
+
* Uses different strategies based on Node version
|
|
80
|
+
*/
|
|
81
|
+
export class StringBuilderOptimized {
|
|
82
|
+
private parts: string[];
|
|
83
|
+
private length: number;
|
|
84
|
+
private initialCapacity: number;
|
|
85
|
+
private chunkSize: number;
|
|
86
|
+
|
|
87
|
+
constructor(initialCapacity = 1024) {
|
|
88
|
+
this.parts = [];
|
|
89
|
+
this.length = 0;
|
|
90
|
+
this.initialCapacity = initialCapacity;
|
|
91
|
+
|
|
92
|
+
// Node 20+ uses more aggressive chunking
|
|
93
|
+
this.chunkSize = features.isNode20Plus ? 65536 : 16384;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
append(str: string): this {
|
|
97
|
+
if (str) {
|
|
98
|
+
this.parts.push(str);
|
|
99
|
+
this.length += str.length;
|
|
100
|
+
}
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
toString(): string {
|
|
105
|
+
return this.parts.join('');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
clear(): void {
|
|
109
|
+
this.parts = [];
|
|
110
|
+
this.length = 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
getLength(): number {
|
|
114
|
+
return this.length;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Optimized row buffer for streaming CSV parsing
|
|
120
|
+
* Minimizes allocations on modern Node versions
|
|
121
|
+
*/
|
|
122
|
+
export class RowBuffer<T = any> {
|
|
123
|
+
private rows: T[][];
|
|
124
|
+
private currentRow: T[];
|
|
125
|
+
private rowCount: number;
|
|
126
|
+
|
|
127
|
+
constructor(initialSize = 100) {
|
|
128
|
+
this.rows = [];
|
|
129
|
+
this.currentRow = [];
|
|
130
|
+
this.rowCount = 0;
|
|
131
|
+
|
|
132
|
+
// Pre-allocate on Node 20+
|
|
133
|
+
if (features.isNode20Plus) {
|
|
134
|
+
this.rows = new Array(initialSize);
|
|
135
|
+
this.rows.length = 0;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
addField(field: T): void {
|
|
140
|
+
this.currentRow.push(field);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
commitRow(): void {
|
|
144
|
+
if (this.currentRow.length > 0) {
|
|
145
|
+
this.rows.push(this.currentRow);
|
|
146
|
+
this.rowCount++;
|
|
147
|
+
this.currentRow = [];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
getRows(): T[][] {
|
|
152
|
+
return this.rows;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
clear(): void {
|
|
156
|
+
this.rows = features.isNode20Plus ? new Array(100) : [];
|
|
157
|
+
this.rows.length = 0;
|
|
158
|
+
this.currentRow = [];
|
|
159
|
+
this.rowCount = 0;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
getRowCount(): number {
|
|
163
|
+
return this.rowCount;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Optimized field parser with char code comparisons
|
|
169
|
+
* Faster than string comparisons on all Node versions
|
|
170
|
+
*/
|
|
171
|
+
export const CHAR_CODES = {
|
|
172
|
+
QUOTE: 34, // "
|
|
173
|
+
COMMA: 44, // ,
|
|
174
|
+
SEMICOLON: 59, // ;
|
|
175
|
+
TAB: 9, // \t
|
|
176
|
+
PIPE: 124, // |
|
|
177
|
+
NEWLINE: 10, // \n
|
|
178
|
+
CARRIAGE: 13, // \r
|
|
179
|
+
SPACE: 32, // space
|
|
180
|
+
EQUALS: 61, // =
|
|
181
|
+
PLUS: 43, // +
|
|
182
|
+
MINUS: 45, // -
|
|
183
|
+
AT: 64, // @
|
|
184
|
+
BACKSLASH: 92, // \
|
|
185
|
+
APOSTROPHE: 39 // '
|
|
186
|
+
} as const;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Fast delimiter detection using char codes
|
|
190
|
+
*/
|
|
191
|
+
export function fastDetectDelimiter(sample: string, candidates = [';', ',', '\t', '|']): string {
|
|
192
|
+
const firstLineEnd = sample.indexOf('\n');
|
|
193
|
+
const firstLine = firstLineEnd > -1 ? sample.slice(0, firstLineEnd) : sample;
|
|
194
|
+
|
|
195
|
+
const candidateCodes = candidates.map(c => c.charCodeAt(0));
|
|
196
|
+
const counts = new Array(candidateCodes.length).fill(0);
|
|
197
|
+
|
|
198
|
+
// Use fast char code iteration on Node 20+
|
|
199
|
+
const len = Math.min(firstLine.length, 10000);
|
|
200
|
+
|
|
201
|
+
for (let i = 0; i < len; i++) {
|
|
202
|
+
const code = firstLine.charCodeAt(i);
|
|
203
|
+
for (let j = 0; j < candidateCodes.length; j++) {
|
|
204
|
+
if (code === candidateCodes[j]) {
|
|
205
|
+
counts[j]++;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
let maxCount = 0;
|
|
211
|
+
let maxIndex = 0;
|
|
212
|
+
|
|
213
|
+
for (let i = 0; i < counts.length; i++) {
|
|
214
|
+
if (counts[i] > maxCount) {
|
|
215
|
+
maxCount = counts[i];
|
|
216
|
+
maxIndex = i;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return candidates[maxIndex];
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Optimized batch processor for large datasets
|
|
225
|
+
* Uses different chunk sizes based on Node version
|
|
226
|
+
*/
|
|
227
|
+
export function createBatchProcessor<T, R>(
|
|
228
|
+
processor: (batch: T[]) => Promise<R[]> | R[],
|
|
229
|
+
options: { batchSize?: number; parallelism?: number } = {}
|
|
230
|
+
): (items: T[]) => AsyncGenerator<R> {
|
|
231
|
+
const batchSize = options.batchSize || (features.isNode20Plus ? 10000 : 5000);
|
|
232
|
+
const parallelism = options.parallelism || (features.isNode22Plus ? 4 : 2);
|
|
233
|
+
|
|
234
|
+
return async function* processBatches(items: T[]): AsyncGenerator<R> {
|
|
235
|
+
const batches: T[][] = [];
|
|
236
|
+
|
|
237
|
+
for (let i = 0; i < items.length; i += batchSize) {
|
|
238
|
+
batches.push(items.slice(i, i + batchSize));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Process batches with limited parallelism
|
|
242
|
+
for (let i = 0; i < batches.length; i += parallelism) {
|
|
243
|
+
const chunk = batches.slice(i, i + parallelism);
|
|
244
|
+
const results = await Promise.all(chunk.map(batch => processor(batch)));
|
|
245
|
+
|
|
246
|
+
for (const result of results) {
|
|
247
|
+
yield* result;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Memory-efficient object pool for row objects
|
|
255
|
+
* Reduces GC pressure on large CSV files
|
|
256
|
+
*/
|
|
257
|
+
export class ObjectPool<T> {
|
|
258
|
+
private factory: () => T;
|
|
259
|
+
private pool: T[];
|
|
260
|
+
private inUse: number;
|
|
261
|
+
|
|
262
|
+
constructor(factory: () => T, initialSize = 100) {
|
|
263
|
+
this.factory = factory;
|
|
264
|
+
this.pool = [];
|
|
265
|
+
this.inUse = 0;
|
|
266
|
+
|
|
267
|
+
// Pre-warm pool on Node 20+
|
|
268
|
+
if (features.isNode20Plus) {
|
|
269
|
+
for (let i = 0; i < initialSize; i++) {
|
|
270
|
+
this.pool.push(factory());
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
acquire(): T {
|
|
276
|
+
this.inUse++;
|
|
277
|
+
if (this.pool.length > 0) {
|
|
278
|
+
return this.pool.pop()!;
|
|
279
|
+
}
|
|
280
|
+
return this.factory();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
release(obj: T): void {
|
|
284
|
+
this.inUse--;
|
|
285
|
+
// Clear object properties before returning to pool
|
|
286
|
+
for (const key in obj) {
|
|
287
|
+
if (hasOwn(obj, key)) {
|
|
288
|
+
delete (obj as any)[key];
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
this.pool.push(obj);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
getStats(): { poolSize: number; inUse: number } {
|
|
295
|
+
return {
|
|
296
|
+
poolSize: this.pool.length,
|
|
297
|
+
inUse: this.inUse
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Fast string escape for CSV values
|
|
304
|
+
* Uses pre-computed regex on all versions
|
|
305
|
+
*/
|
|
306
|
+
const QUOTE_REGEX = /"/g;
|
|
307
|
+
|
|
308
|
+
export function fastEscapeValue(value: any, delimiterCode: number): string {
|
|
309
|
+
if (value === null || value === undefined || value === '') {
|
|
310
|
+
return '';
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const str = typeof value === 'string' ? value : String(value);
|
|
314
|
+
const len = str.length;
|
|
315
|
+
|
|
316
|
+
// Quick scan for special characters using char codes
|
|
317
|
+
let needsQuoting = false;
|
|
318
|
+
let hasQuote = false;
|
|
319
|
+
|
|
320
|
+
for (let i = 0; i < len; i++) {
|
|
321
|
+
const code = str.charCodeAt(i);
|
|
322
|
+
if (code === CHAR_CODES.QUOTE) {
|
|
323
|
+
hasQuote = true;
|
|
324
|
+
needsQuoting = true;
|
|
325
|
+
} else if (code === delimiterCode || code === CHAR_CODES.NEWLINE || code === CHAR_CODES.CARRIAGE) {
|
|
326
|
+
needsQuoting = true;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (!needsQuoting) {
|
|
331
|
+
return str;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const escaped = hasQuote ? str.replace(QUOTE_REGEX, '""') : str;
|
|
335
|
+
return `"${escaped}"`;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Async iterator utilities for streaming
|
|
340
|
+
*/
|
|
341
|
+
export const asyncIterUtils = {
|
|
342
|
+
/**
|
|
343
|
+
* Map over async iterator with concurrency control (Node 20+)
|
|
344
|
+
*/
|
|
345
|
+
async *mapConcurrent<T, R>(
|
|
346
|
+
iterator: AsyncIterable<T>,
|
|
347
|
+
mapper: (item: T) => Promise<R> | R,
|
|
348
|
+
concurrency = 4
|
|
349
|
+
): AsyncGenerator<R> {
|
|
350
|
+
const pending: Promise<R>[] = [];
|
|
351
|
+
|
|
352
|
+
for await (const item of iterator) {
|
|
353
|
+
pending.push(Promise.resolve(mapper(item)));
|
|
354
|
+
|
|
355
|
+
if (pending.length >= concurrency) {
|
|
356
|
+
const results = await Promise.all(pending.splice(0, concurrency));
|
|
357
|
+
for (const result of results) {
|
|
358
|
+
yield result;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (pending.length > 0) {
|
|
364
|
+
const results = await Promise.all(pending);
|
|
365
|
+
for (const result of results) {
|
|
366
|
+
yield result;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Batch items from async iterator
|
|
373
|
+
*/
|
|
374
|
+
async *batch<T>(iterator: AsyncIterable<T>, size = 1000): AsyncGenerator<T[]> {
|
|
375
|
+
let batch: T[] = [];
|
|
376
|
+
|
|
377
|
+
for await (const item of iterator) {
|
|
378
|
+
batch.push(item);
|
|
379
|
+
|
|
380
|
+
if (batch.length >= size) {
|
|
381
|
+
yield batch;
|
|
382
|
+
batch = [];
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (batch.length > 0) {
|
|
387
|
+
yield batch;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Get runtime optimization hints
|
|
394
|
+
*/
|
|
395
|
+
export function getOptimizationHints(): {
|
|
396
|
+
nodeVersion: string;
|
|
397
|
+
features: typeof features;
|
|
398
|
+
recommendations: {
|
|
399
|
+
useWebStreams: boolean;
|
|
400
|
+
useStructuredClone: boolean;
|
|
401
|
+
useLargerBatches: boolean;
|
|
402
|
+
useHigherParallelism: boolean;
|
|
403
|
+
preferredChunkSize: number;
|
|
404
|
+
};
|
|
405
|
+
} {
|
|
406
|
+
return {
|
|
407
|
+
nodeVersion: `${major}.${minor}`,
|
|
408
|
+
features,
|
|
409
|
+
recommendations: {
|
|
410
|
+
useWebStreams: features.hasWebStreams,
|
|
411
|
+
useStructuredClone: features.hasStructuredClone,
|
|
412
|
+
useLargerBatches: features.isNode20Plus,
|
|
413
|
+
useHigherParallelism: features.isNode22Plus,
|
|
414
|
+
preferredChunkSize: features.isNode24Plus ? 131072 : (features.isNode20Plus ? 65536 : 16384)
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export const nodeVersionInfo = { major, minor };
|
|
420
|
+
|
|
421
|
+
export default {
|
|
422
|
+
// Feature detection
|
|
423
|
+
features,
|
|
424
|
+
nodeVersion: { major, minor },
|
|
425
|
+
|
|
426
|
+
// Polyfills and optimized functions
|
|
427
|
+
hasOwn,
|
|
428
|
+
deepClone,
|
|
429
|
+
arrayAt,
|
|
430
|
+
|
|
431
|
+
// Classes
|
|
432
|
+
StringBuilderOptimized,
|
|
433
|
+
RowBuffer,
|
|
434
|
+
ObjectPool,
|
|
435
|
+
|
|
436
|
+
// Constants
|
|
437
|
+
CHAR_CODES,
|
|
438
|
+
|
|
439
|
+
// Functions
|
|
440
|
+
fastDetectDelimiter,
|
|
441
|
+
fastEscapeValue,
|
|
442
|
+
createBatchProcessor,
|
|
443
|
+
|
|
444
|
+
// Async utilities
|
|
445
|
+
asyncIterUtils,
|
|
446
|
+
|
|
447
|
+
// Diagnostics
|
|
448
|
+
getOptimizationHints
|
|
408
449
|
};
|