From 60b404f4d98c26f33e1b5a5b182a4a78f9a2af03 Mon Sep 17 00:00:00 2001 From: Ardis Lu Date: Sat, 5 Jul 2025 19:14:40 -0700 Subject: [PATCH] Support ArrayLike outputs Could be useful for chained transformations using DOM APIs, e.g. passing through the NodeList object. --- src/core.js | 15 ++++++++++----- test/core.test.js | 11 +++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/core.js b/src/core.js index 81e13ff..d2bcc6a 100644 --- a/src/core.js +++ b/src/core.js @@ -196,7 +196,7 @@ export class CSVReader extends ReadableStream { /** * A row or rows of output CSV data, or `null` to not output anything. - * @typedef {Array>|Array|string|null} TransformationOutput + * @typedef {Array>|Array|ArrayLike|string|null} TransformationOutput */ /** @@ -402,11 +402,16 @@ export class CSVTransformer extends TransformStream { else if (this.#rawOutput || typeof row === 'string') { controller.enqueue(row); } - else if (Array.isArray(row) && Array.isArray(row[0])) { // Multiple rows returned, enqueue each row separately - row.forEach(r => controller.enqueue(JSON.stringify(r))); + else if (Array.isArray(row)) { + if (Array.isArray(row[0])) { // Multiple rows returned, enqueue each row separately + row.forEach(r => controller.enqueue(JSON.stringify(r))); + } + else { // One row returned + controller.enqueue(JSON.stringify(row)); + } } - else { - controller.enqueue(JSON.stringify(row)); + else { // Assume ArrayLike output + controller.enqueue(JSON.stringify(Array.from(row))); } } diff --git a/test/core.test.js b/test/core.test.js index 1c4918e..3e0180e 100644 --- a/test/core.test.js +++ b/test/core.test.js @@ -327,6 +327,17 @@ suite('CSVTransformer', { concurrency: true }, () => { ['abc', 'def'] ])); }); + test('handles ArrayLike outputs', { concurrency: true }, async () => { + await createCSVMockStream([ + ['columnA', 'columnB'], + ['a', 'b'] + ]) + .pipeThrough(new CSVTransformer(() => ({ length: 2, 0: 'a2', 1: 'b2' }))) + .pipeTo(csvStreamEqualWritable([ + ['columnA', 'columnB'], + ['a2', 'b2'] + ])); + }); test('consumes input row without output row when null is returned', { concurrency: true }, async () => { await createCSVMockStream([ ['columnA', 'columnB'], -- 2.47.3