]> git.ardis.lu - csvio/commitdiff
Allow transformation function to return multiple rows
authorArdis Lu <ardisglu@gmail.com>
Fri, 10 Jan 2025 06:11:13 +0000 (22:11 -0800)
committerArdis Lu <ardisglu@gmail.com>
Fri, 10 Jan 2025 06:11:13 +0000 (22:11 -0800)
src/core.js
test/core.test.js

index 48f327fe629714e5580e4daa74f579ae45e89b14..e49389b3a167ca33fed1a1344a25f59cc6ece9af 100644 (file)
@@ -118,13 +118,14 @@ export function createCSVReadableStream(path) {
 /**
  * Create a new [TransformStream](https://developer.mozilla.org/en-US/docs/Web/API/TransformStream) to process CSV data.
  * 
- * @param {function(Array<string>|string):Array<any>|string|null} fn A function to process a row of CSV data from `createCSVReadableStream`.
+ * @param {function(Array<string>|string):Array<Array<any>>|Array<any>|string|null} fn A function to process a row of CSV data from `createCSVReadableStream`.
  * 
  * If `options.rawInput` is `false` (default), the input will be a `Array<string>` representing the CSV row. If `options.rawInput` is `true`,
  * the input will be a JSON `string` representing the CSV row.
  * 
- * If `options.rawOutput` is `false` (default), the expected output is a `Array<string>` which will be serialized with `JSON.stringify()`. If
- * `options.rawOutput` is `true`, the raw output will be sent the next stream unmodified.
+ * If `options.rawOutput` is `false` (default), the expected output is a `Array<any>` which will be serialized with `JSON.stringify()` and enqueued,
+ * or a `Array<Array<any>>` which will have each of its sub-arrays serialized and enqueued separately. If `options.rawOutput` is `true`, the raw
+ * output will be sent the next stream unmodified.
  * 
  * Return `null` to consume an input row without emitting an output row.
  * @param {createCSVTransformStreamOptions} options Object containing flags to configure the stream logic.
@@ -155,6 +156,9 @@ export function createCSVTransformStream(fn, options = {}) {
       if (options.rawOutput || typeof out === 'string') {
         controller.enqueue(out);
       }
+      else if (Array.isArray(out) && Array.isArray(out[0])) { // Multiple rows returned, enqueue each row separately
+        out.forEach(row => controller.enqueue(JSON.stringify(row)));
+      }
       else {
         controller.enqueue(JSON.stringify(out));
       }
index 9fbb8e22d520228c88fbfb9f709907e1bcf46982..436e5e1cb0101a0b14bcc8d3ac06e35790757bc2 100644 (file)
@@ -202,6 +202,20 @@ suite('createCSVTransformStream', { concurrency: true }, () => {
         ['a', 'b'],
       ]));
   });
+  test('enqueues multiple rows when Array<Array<any>> is returned', { concurrency: true }, async () => {
+    await createCSVMockStream([
+      ['columnA', 'columnB'],
+      ['a', 'b']
+    ])
+      .pipeThrough(createCSVTransformStream(r => ([r, r, r, r])))
+      .pipeTo(csvStreamEqualWritable([
+        ['columnA', 'columnB'],
+        ['a', 'b'],
+        ['a', 'b'],
+        ['a', 'b'],
+        ['a', 'b']
+      ]));
+  });
 });
 
 suite('createCSVWritableStream', { concurrency: true }, () => {
This page took 0.049958 seconds and 4 git commands to generate.