@push.rocks/smartstream 3.0.35 → 3.0.37

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.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartstream',
6
- version: '3.0.35',
7
- description: 'simplifies access to node streams'
6
+ version: '3.0.37',
7
+ description: 'A library to simplify the creation and manipulation of Node.js streams, providing utilities for handling transform, duplex, and readable/writable streams effectively in TypeScript.'
8
8
  };
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx5QkFBeUI7SUFDL0IsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLG1DQUFtQztDQUNqRCxDQUFBIn0=
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx5QkFBeUI7SUFDL0IsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLHNMQUFzTDtDQUNwTSxDQUFBIn0=
@@ -11,7 +11,7 @@ export class StreamIntake extends plugins.stream.Readable {
11
11
  _read(size) {
12
12
  // console.log('get next');
13
13
  const pushChunk = () => {
14
- if (this.chunkStore.length > 0) {
14
+ while (this.chunkStore.length > 0) {
15
15
  // If push returns false, then we should stop reading
16
16
  if (!this.push(this.chunkStore.shift())) {
17
17
  return;
@@ -44,4 +44,4 @@ export class StreamIntake extends plugins.stream.Readable {
44
44
  this.pushNextObservable.signalComplete();
45
45
  }
46
46
  }
47
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzdHJlYW0uY2xhc3Nlcy5zdHJlYW1pbnRha2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydHN0cmVhbS5jbGFzc2VzLnN0cmVhbWludGFrZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDBCQUEwQixDQUFDO0FBRXBELE1BQU0sT0FBTyxZQUFnQixTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUTtJQU0xRCxZQUFZLE9BQXdDO1FBQ2xELEtBQUssQ0FBQyxFQUFFLEdBQUcsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMscUNBQXFDO1FBTnhFLHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUN6QixlQUFVLEdBQVEsRUFBRSxDQUFDO1FBQ3RCLHVCQUFrQixHQUFHLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBTyxDQUFDO1FBQ2hFLHVCQUFrQixHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7UUFJeEQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRCxLQUFLLENBQUMsSUFBWTtRQUNoQiwyQkFBMkI7UUFDM0IsTUFBTSxTQUFTLEdBQUcsR0FBUyxFQUFFO1lBQzNCLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQy9CLHFEQUFxRDtnQkFDckQsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUM7b0JBQ3hDLE9BQU87Z0JBQ1QsQ0FBQztZQUNILENBQUM7WUFFRCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNqQyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO29CQUMxQiwyREFBMkQ7b0JBQzNELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ2xCLENBQUM7cUJBQU0sQ0FBQztvQkFDTiw2QkFBNkI7b0JBQzdCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztvQkFDakQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO3dCQUN4QyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLHFCQUFxQjt3QkFDN0UsU0FBUyxFQUFFLENBQUMsQ0FBQyw2QkFBNkI7b0JBQzVDLENBQUMsQ0FBQyxDQUFDO2dCQUNMLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQyxDQUFDO1FBRUYsU0FBUyxFQUFFLENBQUM7SUFDZCxDQUFDO0lBRU0sUUFBUSxDQUFDLFNBQVk7UUFDMUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3BDLENBQUM7SUFFTSxTQUFTO1FBQ2QsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztRQUM3QixJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQzNDLENBQUM7Q0FDRiJ9
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzdHJlYW0uY2xhc3Nlcy5zdHJlYW1pbnRha2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydHN0cmVhbS5jbGFzc2VzLnN0cmVhbWludGFrZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDBCQUEwQixDQUFDO0FBRXBELE1BQU0sT0FBTyxZQUFnQixTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUTtJQU0xRCxZQUFZLE9BQXdDO1FBQ2xELEtBQUssQ0FBQyxFQUFFLEdBQUcsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMscUNBQXFDO1FBTnhFLHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUN6QixlQUFVLEdBQVEsRUFBRSxDQUFDO1FBQ3RCLHVCQUFrQixHQUFHLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBTyxDQUFDO1FBQ2hFLHVCQUFrQixHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7UUFJeEQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRCxLQUFLLENBQUMsSUFBWTtRQUNoQiwyQkFBMkI7UUFDM0IsTUFBTSxTQUFTLEdBQUcsR0FBUyxFQUFFO1lBQzNCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2xDLHFEQUFxRDtnQkFDckQsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUM7b0JBQ3hDLE9BQU87Z0JBQ1QsQ0FBQztZQUNILENBQUM7WUFFRCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNqQyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO29CQUMxQiwyREFBMkQ7b0JBQzNELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ2xCLENBQUM7cUJBQU0sQ0FBQztvQkFDTiw2QkFBNkI7b0JBQzdCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztvQkFDakQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO3dCQUN4QyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLHFCQUFxQjt3QkFDN0UsU0FBUyxFQUFFLENBQUMsQ0FBQyw2QkFBNkI7b0JBQzVDLENBQUMsQ0FBQyxDQUFDO2dCQUNMLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQyxDQUFDO1FBRUYsU0FBUyxFQUFFLENBQUM7SUFDZCxDQUFDO0lBRU0sUUFBUSxDQUFDLFNBQVk7UUFDMUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3BDLENBQUM7SUFFTSxTQUFTO1FBQ2QsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztRQUM3QixJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQzNDLENBQUM7Q0FDRiJ9
package/npmextra.json CHANGED
@@ -9,27 +9,27 @@
9
9
  "githost": "code.foss.global",
10
10
  "gitscope": "push.rocks",
11
11
  "gitrepo": "smartstream",
12
- "description": "simplifies access to node streams",
12
+ "description": "A library to simplify the creation and manipulation of Node.js streams, providing utilities for handling transform, duplex, and readable/writable streams effectively in TypeScript.",
13
13
  "npmPackagename": "@push.rocks/smartstream",
14
14
  "license": "MIT",
15
15
  "keywords": [
16
+ "stream",
16
17
  "node.js",
17
- "streams",
18
+ "typescript",
18
19
  "stream manipulation",
19
- "pipeline",
20
20
  "data processing",
21
+ "pipeline",
21
22
  "async transformation",
22
23
  "event handling",
23
- "backpressure management",
24
- "readable streams",
25
- "writable streams",
26
- "duplex streams",
27
- "transform streams",
24
+ "backpressure",
25
+ "readable stream",
26
+ "writable stream",
27
+ "duplex stream",
28
+ "transform stream",
28
29
  "file streaming",
29
- "buffer streams",
30
+ "buffer",
30
31
  "stream utilities",
31
- "stream intake",
32
- "stream output"
32
+ "esm"
33
33
  ]
34
34
  }
35
35
  },
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@push.rocks/smartstream",
3
- "version": "3.0.35",
3
+ "version": "3.0.37",
4
4
  "private": false,
5
- "description": "simplifies access to node streams",
5
+ "description": "A library to simplify the creation and manipulation of Node.js streams, providing utilities for handling transform, duplex, and readable/writable streams effectively in TypeScript.",
6
6
  "main": "dist_ts/index.js",
7
7
  "typings": "dist_ts/index.d.ts",
8
8
  "type": "module",
@@ -46,23 +46,23 @@
46
46
  "readme.md"
47
47
  ],
48
48
  "keywords": [
49
+ "stream",
49
50
  "node.js",
50
- "streams",
51
+ "typescript",
51
52
  "stream manipulation",
52
- "pipeline",
53
53
  "data processing",
54
+ "pipeline",
54
55
  "async transformation",
55
56
  "event handling",
56
- "backpressure management",
57
- "readable streams",
58
- "writable streams",
59
- "duplex streams",
60
- "transform streams",
57
+ "backpressure",
58
+ "readable stream",
59
+ "writable stream",
60
+ "duplex stream",
61
+ "transform stream",
61
62
  "file streaming",
62
- "buffer streams",
63
+ "buffer",
63
64
  "stream utilities",
64
- "stream intake",
65
- "stream output"
65
+ "esm"
66
66
  ],
67
67
  "scripts": {
68
68
  "test": "(tstest test/)",
package/readme.hints.md CHANGED
@@ -1 +1 @@
1
-
1
+ - make sure to respect backpressure handling.
package/readme.md CHANGED
@@ -1,5 +1,6 @@
1
+ ```markdown
1
2
  # @push.rocks/smartstream
2
- simplifies access to node streams
3
+ A TypeScript library to simplify the creation and manipulation of Node.js streams, providing utilities for transform, duplex, and readable/writable stream handling while managing backpressure effectively.
3
4
 
4
5
  ## Install
5
6
  To install `@push.rocks/smartstream`, you can use npm or yarn as follows:
@@ -14,7 +15,7 @@ This will add `@push.rocks/smartstream` to your project's dependencies.
14
15
 
15
16
  ## Usage
16
17
 
17
- The `@push.rocks/smartstream` module is designed to simplify working with Node.js streams by providing a set of utilities for creating and manipulating streams. This module makes heavy use of TypeScript for improved code quality, readability, and maintenance. ESM syntax is utilized throughout the examples.
18
+ The `@push.rocks/smartstream` module is designed to simplify working with Node.js streams by providing a set of utilities for creating and manipulating streams. This module makes extensive use of TypeScript for improved code quality, readability, and maintenance. ESM syntax is utilized throughout the examples.
18
19
 
19
20
  ### Importing the Module
20
21
 
@@ -24,6 +25,12 @@ Start by importing the module into your TypeScript file:
24
25
  import * as smartstream from '@push.rocks/smartstream';
25
26
  ```
26
27
 
28
+ For a more specific import, you may do the following:
29
+
30
+ ```typescript
31
+ import { SmartDuplex, StreamWrapper, StreamIntake, createTransformFunction, createPassThrough } from '@push.rocks/smartstream';
32
+ ```
33
+
27
34
  ### Creating Basic Transform Streams
28
35
 
29
36
  The module provides utilities for creating transform streams. For example, to create a transform stream that modifies chunks of data, you can use the `createTransformFunction` utility:
@@ -58,7 +65,7 @@ const processDataDuplex = new SmartDuplex({
58
65
  sourceStream.pipe(processDataDuplex).pipe(destinationStream);
59
66
  ```
60
67
 
61
- ### Stream Combiners
68
+ ### Combining Multiple Streams
62
69
 
63
70
  `Smartstream` facilitates easy combining of multiple streams into a single pipeline, handling errors and cleanup automatically. Here's how you can combine multiple streams:
64
71
 
@@ -101,7 +108,7 @@ Consider a scenario where you need to process a large CSV file, transform the da
101
108
  ```typescript
102
109
  import { SmartDuplex, createTransformFunction } from '@push.rocks/smartstream';
103
110
  import fs from 'fs';
104
- import csvParser from 'csv-parser'; // Assume this is a CSV parsing library
111
+ import csvParser from 'csv-parser';
105
112
 
106
113
  const csvReadTransform = createTransformFunction<any, any>(async (row) => {
107
114
  // Process row
@@ -121,11 +128,232 @@ fs.createReadStream('path/to/largeFile.csv')
121
128
 
122
129
  This example demonstrates reading a large CSV file, transforming each row with `createTransformFunction`, and using a `SmartDuplex` to manage the processed data flow efficiently, ensuring no data is lost due to backpressure issues.
123
130
 
124
- ### Conclusion
131
+ ### Advanced Use Case: Backpressure Handling
132
+
133
+ Effective backpressure handling is crucial when working with streams to avoid overwhelming the downstream consumers. Here’s a comprehensive example that demonstrates handling backpressure in a pipeline with multiple `SmartDuplex` instances:
134
+
135
+ ```typescript
136
+ import { SmartDuplex } from '@push.rocks/smartstream';
137
+
138
+ // Define the first SmartDuplex, which writes data slowly to simulate backpressure
139
+ const slowProcessingStream = new SmartDuplex({
140
+ name: 'SlowProcessor',
141
+ objectMode: true,
142
+ writeFunction: async (chunk, { push }) => {
143
+ await new Promise(resolve => setTimeout(resolve, 100)); // Simulated delay
144
+ console.log('Processed chunk:', chunk);
145
+ push(chunk);
146
+ }
147
+ });
148
+
149
+ // Define the second SmartDuplex as a fast processor
150
+ const fastProcessingStream = new SmartDuplex({
151
+ name: 'FastProcessor',
152
+ objectMode: true,
153
+ writeFunction: async (chunk, { push }) => {
154
+ console.log('Fast processing chunk:', chunk);
155
+ push(chunk);
156
+ }
157
+ });
158
+
159
+ // Create a StreamIntake to dynamically handle incoming data
160
+ const streamIntake = new StreamIntake<string>();
161
+
162
+ // Chain the streams together and handle the backpressure scenario
163
+ streamIntake
164
+ .pipe(fastProcessingStream)
165
+ .pipe(slowProcessingStream)
166
+ .pipe(createPassThrough()) // Use Pass-Through to provide intermediary handling
167
+ .on('data', data => console.log('Final output:', data))
168
+ .on('error', error => console.error('Stream encountered an error:', error));
169
+
170
+ // Simulate data pushing with intervals to observe backpressure handling
171
+ let counter = 0;
172
+ const interval = setInterval(() => {
173
+ if (counter >= 10) {
174
+ streamIntake.signalEnd();
175
+ clearInterval(interval);
176
+ } else {
177
+ streamIntake.pushData(`Chunk ${counter}`);
178
+ counter++;
179
+ }
180
+ }, 50);
181
+ ```
182
+
183
+ In this advanced use case, a `SlowProcessor` and `FastProcessor` are created using `SmartDuplex`, simulating a situation where one stream is slower than another. The `StreamIntake` dynamically handles incoming chunks of data and the intermediary Pass-Through handles any potential interruptions.
184
+
185
+ ### Transform Streams in Parallel
186
+
187
+ For scenarios where you need to process data in parallel:
188
+
189
+ ```typescript
190
+ import { SmartDuplex, createTransformFunction } from '@push.rocks/smartstream';
191
+
192
+ const parallelTransform = createTransformFunction<any, any>(async (chunk) => {
193
+ // Parallel Processing
194
+ const results = await Promise.all(chunk.map(async item => await processItem(item)));
195
+ return results;
196
+ });
197
+
198
+ const streamIntake = new StreamIntake<any[]>();
199
+
200
+ streamIntake
201
+ .pipe(parallelTransform)
202
+ .pipe(new SmartDuplex({
203
+ async writeFunction(chunk, { push }) {
204
+ console.log('Processed parallel chunk:', chunk);
205
+ push(chunk);
206
+ }
207
+ }))
208
+ .on('finish', () => console.log('Parallel processing completed.'));
209
+
210
+ // Simulate data pushing
211
+ streamIntake.pushData([1, 2, 3, 4]);
212
+ streamIntake.pushData([5, 6, 7, 8]);
213
+ streamIntake.signalEnd();
214
+ ```
215
+
216
+ ### Error Handling in Stream Pipelines
217
+
218
+ Error handling is an essential part of working with streams. The `StreamWrapper` assists in combining multiple streams while managing errors seamlessly:
219
+
220
+ ```typescript
221
+ import { StreamWrapper } from '@push.rocks/smartstream';
222
+
223
+ const faultyStream = new SmartDuplex({
224
+ async writeFunction(chunk, { push }) {
225
+ if (chunk === 'bad data') {
226
+ throw new Error('Faulty data encountered');
227
+ }
228
+ push(chunk);
229
+ }
230
+ });
125
231
 
126
- `@push.rocks/smartstream` offers a robust set of tools for working with Node.js streams, providing a more intuitive and reliable way to create, manipulate, and combine streams. By leveraging TypeScript and ESM syntax, `smartstream` enables developers to build more maintainable and type-safe stream-based solutions.
232
+ const readStream = new StreamIntake<string>();
233
+ const writeStream = new SmartDuplex({
234
+ async writeFunction(chunk) {
235
+ console.log('Written chunk:', chunk);
236
+ }
237
+ });
238
+
239
+ const combinedStream = new StreamWrapper([readStream, faultyStream, writeStream]);
240
+
241
+ combinedStream.run()
242
+ .then(() => console.log('Stream processing completed.'))
243
+ .catch(err => console.error('Stream error:', err.message));
244
+
245
+ // Push Data
246
+ readStream.pushData('good data');
247
+ readStream.pushData('bad data'); // This will throw an error
248
+ readStream.pushData('more good data');
249
+ readStream.signalEnd();
250
+ ```
251
+
252
+ ### Testing Streams
253
+
254
+ Here's an example test case using the `tap` testing framework to verify the integrity of the `SmartDuplex` from a buffer:
255
+
256
+ ```typescript
257
+ import { expect, tap } from '@push.rocks/tapbundle';
258
+ import { SmartDuplex } from '@push.rocks/smartstream';
259
+
260
+ tap.test('should create a SmartStream from a Buffer', async () => {
261
+ const bufferData = Buffer.from('This is a test buffer');
262
+ const smartStream = SmartDuplex.fromBuffer(bufferData, {});
263
+
264
+ let receivedData = Buffer.alloc(0);
265
+
266
+ return new Promise<void>((resolve) => {
267
+ smartStream.on('data', (chunk: Buffer) => {
268
+ receivedData = Buffer.concat([receivedData, chunk]);
269
+ });
270
+
271
+ smartStream.on('end', () => {
272
+ expect(receivedData.toString()).toEqual(bufferData.toString());
273
+ resolve();
274
+ });
275
+ });
276
+ });
277
+
278
+ tap.start();
279
+ ```
280
+
281
+ ### Working with Files and Buffers
282
+
283
+ You can easily stream files and buffers with `smartstream`. Here’s a test illustrating reading and writing with file streams using `smartfile` combined with `smartstream` utilities:
284
+
285
+ ```typescript
286
+ import { tap } from '@push.rocks/tapbundle';
287
+ import * as smartfile from '@push.rocks/smartfile';
288
+ import { SmartDuplex, StreamWrapper } from '@push.rocks/smartstream';
289
+
290
+ tap.test('should handle file read and write streams', async () => {
291
+ const readStream = smartfile.fsStream.createReadStream('./test/assets/readabletext.txt');
292
+ const writeStream = smartfile.fsStream.createWriteStream('./test/assets/writabletext.txt');
293
+
294
+ const transformStream = new SmartDuplex({
295
+ async writeFunction(chunk, { push }) {
296
+ const transformedChunk = chunk.toString().toUpperCase();
297
+ push(transformedChunk);
298
+ }
299
+ });
300
+
301
+ const streamWrapper = new StreamWrapper([readStream, transformStream, writeStream]);
302
+
303
+ await streamWrapper.run();
304
+
305
+ const outputContent = await smartfile.fs.promises.readFile('./test/assets/writabletext.txt', 'utf-8');
306
+ console.log('Output Content:', outputContent);
307
+ });
308
+
309
+ tap.start();
310
+ ```
311
+
312
+ ### Modular and Scoped Transformations
313
+
314
+ Creating modular and scoped transformations is straightforward with `SmartDuplex`:
315
+
316
+ ```typescript
317
+ import { SmartDuplex } from '@push.rocks/smartstream';
318
+
319
+ type DataChunk = {
320
+ id: number;
321
+ data: string;
322
+ };
323
+
324
+ const transformationStream1 = new SmartDuplex<DataChunk, DataChunk>({
325
+ async writeFunction(chunk, { push }) {
326
+ chunk.data = chunk.data.toUpperCase();
327
+ push(chunk);
328
+ }
329
+ })
330
+
331
+ const transformationStream2 = new SmartDuplex<DataChunk, DataChunk>({
332
+ async writeFunction(chunk, { push }) {
333
+ chunk.data = `${chunk.data} processed with transformation 2`;
334
+ push(chunk);
335
+ }
336
+ });
337
+
338
+ const initialData: DataChunk[] = [
339
+ { id: 1, data: 'first' },
340
+ { id: 2, data: 'second' }
341
+ ];
342
+
343
+ const intakeStream = new StreamIntake<DataChunk>();
344
+
345
+ intakeStream
346
+ .pipe(transformationStream1)
347
+ .pipe(transformationStream2)
348
+ .on('data', data => console.log('Transformed Data:', data));
349
+
350
+ initialData.forEach(item => intakeStream.pushData(item));
351
+ intakeStream.signalEnd();
352
+ ```
353
+
354
+ By leveraging `SmartDuplex`, `StreamWrapper`, and `StreamIntake`, you can streamline and enhance your data transformation pipelines in Node.js with a clear, efficient, and backpressure-friendly approach.
355
+ ```
127
356
 
128
- For more detailed examples and documentation, visit the [GitLab Repository](https://gitlab.com/push.rocks/smartstream) or the [GitHub Mirror](https://github.com/pushrocks/smartstream).
129
357
 
130
358
  ## License and Legal Information
131
359
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartstream',
6
- version: '3.0.35',
7
- description: 'simplifies access to node streams'
6
+ version: '3.0.37',
7
+ description: 'A library to simplify the creation and manipulation of Node.js streams, providing utilities for handling transform, duplex, and readable/writable streams effectively in TypeScript.'
8
8
  }
@@ -14,7 +14,7 @@ export class StreamIntake<T> extends plugins.stream.Readable {
14
14
  _read(size: number): void {
15
15
  // console.log('get next');
16
16
  const pushChunk = (): void => {
17
- if (this.chunkStore.length > 0) {
17
+ while (this.chunkStore.length > 0) {
18
18
  // If push returns false, then we should stop reading
19
19
  if (!this.push(this.chunkStore.shift())) {
20
20
  return;