@push.rocks/smartstream 2.0.8 → 3.0.2
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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/index.d.ts +1 -2
- package/dist_ts/index.js +2 -3
- package/dist_ts/smartstream.classes.smartduplex.d.ts +32 -0
- package/dist_ts/smartstream.classes.smartduplex.js +135 -0
- package/dist_ts/smartstream.classes.streamintake.d.ts +3 -12
- package/dist_ts/smartstream.classes.streamintake.js +29 -38
- package/package.json +6 -5
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/index.ts +1 -2
- package/ts/smartstream.classes.smartduplex.ts +177 -0
- package/ts/smartstream.classes.streamintake.ts +29 -43
- package/dist_ts/smartstream.classes.smartstream.d.ts +0 -12
- package/dist_ts/smartstream.classes.smartstream.js +0 -48
- package/dist_ts/smartstream.duplex.d.ts +0 -23
- package/dist_ts/smartstream.duplex.js +0 -48
- package/ts/smartstream.classes.smartstream.ts +0 -55
- package/ts/smartstream.duplex.ts +0 -83
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartstream',
|
|
6
|
-
version: '
|
|
6
|
+
version: '3.0.2',
|
|
7
7
|
description: 'simplifies access to node streams'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx5QkFBeUI7SUFDL0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLG1DQUFtQztDQUNqRCxDQUFBIn0=
|
package/dist_ts/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export * from './smartstream.classes.passthrough.js';
|
|
2
|
-
export * from './smartstream.classes.
|
|
2
|
+
export * from './smartstream.classes.smartduplex.js';
|
|
3
3
|
export * from './smartstream.classes.streamwrapper.js';
|
|
4
4
|
export * from './smartstream.classes.streamintake.js';
|
|
5
|
-
export * from './smartstream.duplex.js';
|
package/dist_ts/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from './smartstream.classes.passthrough.js';
|
|
2
|
-
export * from './smartstream.classes.
|
|
2
|
+
export * from './smartstream.classes.smartduplex.js';
|
|
3
3
|
export * from './smartstream.classes.streamwrapper.js';
|
|
4
4
|
export * from './smartstream.classes.streamintake.js';
|
|
5
|
-
|
|
6
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHNDQUFzQyxDQUFDO0FBQ3JELGNBQWMsc0NBQXNDLENBQUM7QUFDckQsY0FBYyx3Q0FBd0MsQ0FBQztBQUN2RCxjQUFjLHVDQUF1QyxDQUFDO0FBQ3RELGNBQWMseUJBQXlCLENBQUMifQ==
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHNDQUFzQyxDQUFDO0FBQ3JELGNBQWMsc0NBQXNDLENBQUM7QUFDckQsY0FBYyx3Q0FBd0MsQ0FBQztBQUN2RCxjQUFjLHVDQUF1QyxDQUFDIn0=
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
3
|
+
import * as plugins from './smartstream.plugins.js';
|
|
4
|
+
import { Duplex, type DuplexOptions } from 'stream';
|
|
5
|
+
export interface IStreamTools {
|
|
6
|
+
truncate: () => void;
|
|
7
|
+
push: (pipeObject: any) => void;
|
|
8
|
+
}
|
|
9
|
+
export interface IWriteAndTransformFunction<T, rT> {
|
|
10
|
+
(chunkArg: T, toolsArg: IStreamTools): Promise<rT>;
|
|
11
|
+
}
|
|
12
|
+
export interface IStreamEndFunction<rT> {
|
|
13
|
+
(toolsArg: IStreamTools): Promise<rT>;
|
|
14
|
+
}
|
|
15
|
+
export interface SmartStreamOptions<TInput, TOutput> extends DuplexOptions {
|
|
16
|
+
readFunction?: () => Promise<void>;
|
|
17
|
+
writeAndTransformFunction?: IWriteAndTransformFunction<TInput, TOutput>;
|
|
18
|
+
streamEndFunction?: IStreamEndFunction<TOutput>;
|
|
19
|
+
}
|
|
20
|
+
export declare class SmartDuplex<TInput = any, TOutput = any> extends Duplex {
|
|
21
|
+
static fromBuffer(buffer: Buffer, options?: DuplexOptions): SmartDuplex;
|
|
22
|
+
static fromObservable(observable: plugins.smartrx.rxjs.Observable<any>, options?: DuplexOptions): SmartDuplex;
|
|
23
|
+
static fromReplaySubject(replaySubject: plugins.smartrx.rxjs.ReplaySubject<any>, options?: DuplexOptions): SmartDuplex;
|
|
24
|
+
private readFunction?;
|
|
25
|
+
private writeAndTransformFunction?;
|
|
26
|
+
private streamEndFunction?;
|
|
27
|
+
private observableSubscription?;
|
|
28
|
+
constructor(optionsArg?: SmartStreamOptions<TInput, TOutput>);
|
|
29
|
+
_read(size: number): Promise<void>;
|
|
30
|
+
_write(chunk: TInput, encoding: string, callback: (error?: Error | null) => void): Promise<void>;
|
|
31
|
+
_final(callback: (error?: Error | null) => void): Promise<void>;
|
|
32
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import * as plugins from './smartstream.plugins.js';
|
|
2
|
+
import { Duplex } from 'stream';
|
|
3
|
+
export class SmartDuplex extends Duplex {
|
|
4
|
+
// STATIC
|
|
5
|
+
static fromBuffer(buffer, options) {
|
|
6
|
+
const smartStream = new SmartDuplex(options);
|
|
7
|
+
process.nextTick(() => {
|
|
8
|
+
smartStream.push(buffer);
|
|
9
|
+
smartStream.push(null); // Signal the end of the data
|
|
10
|
+
});
|
|
11
|
+
return smartStream;
|
|
12
|
+
}
|
|
13
|
+
static fromObservable(observable, options) {
|
|
14
|
+
const smartStream = new SmartDuplex(options);
|
|
15
|
+
smartStream.observableSubscription = observable.subscribe({
|
|
16
|
+
next: (data) => {
|
|
17
|
+
if (!smartStream.push(data)) {
|
|
18
|
+
// Pause the observable if the stream buffer is full
|
|
19
|
+
smartStream.observableSubscription?.unsubscribe();
|
|
20
|
+
smartStream.once('drain', () => {
|
|
21
|
+
// Resume the observable when the stream buffer is drained
|
|
22
|
+
smartStream.observableSubscription?.unsubscribe();
|
|
23
|
+
smartStream.observableSubscription = observable.subscribe((data) => {
|
|
24
|
+
smartStream.push(data);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
error: (err) => {
|
|
30
|
+
smartStream.emit('error', err);
|
|
31
|
+
},
|
|
32
|
+
complete: () => {
|
|
33
|
+
smartStream.push(null); // Signal the end of the data
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
return smartStream;
|
|
37
|
+
}
|
|
38
|
+
static fromReplaySubject(replaySubject, options) {
|
|
39
|
+
const smartStream = new SmartDuplex(options);
|
|
40
|
+
let isBackpressured = false;
|
|
41
|
+
// Subscribe to the ReplaySubject
|
|
42
|
+
const subscription = replaySubject.subscribe({
|
|
43
|
+
next: (data) => {
|
|
44
|
+
const canPush = smartStream.push(data);
|
|
45
|
+
if (!canPush) {
|
|
46
|
+
// If push returns false, pause the subscription because of backpressure
|
|
47
|
+
isBackpressured = true;
|
|
48
|
+
subscription.unsubscribe();
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
error: (err) => {
|
|
52
|
+
smartStream.emit('error', err);
|
|
53
|
+
},
|
|
54
|
+
complete: () => {
|
|
55
|
+
smartStream.push(null); // End the stream when the ReplaySubject completes
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
// Listen for 'drain' event to resume the subscription if it was paused
|
|
59
|
+
smartStream.on('drain', () => {
|
|
60
|
+
if (isBackpressured) {
|
|
61
|
+
isBackpressured = false;
|
|
62
|
+
// Resubscribe to the ReplaySubject since we previously paused
|
|
63
|
+
smartStream.observableSubscription = replaySubject.subscribe({
|
|
64
|
+
next: (data) => {
|
|
65
|
+
if (!smartStream.push(data)) {
|
|
66
|
+
smartStream.observableSubscription?.unsubscribe();
|
|
67
|
+
isBackpressured = true;
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
// No need to repeat error and complete handling here because it's already set up above
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
return smartStream;
|
|
75
|
+
}
|
|
76
|
+
constructor(optionsArg) {
|
|
77
|
+
super(optionsArg);
|
|
78
|
+
this.readFunction = optionsArg?.readFunction;
|
|
79
|
+
this.writeAndTransformFunction = optionsArg?.writeAndTransformFunction;
|
|
80
|
+
this.streamEndFunction = optionsArg?.streamEndFunction;
|
|
81
|
+
}
|
|
82
|
+
async _read(size) {
|
|
83
|
+
if (this.readFunction) {
|
|
84
|
+
await this.readFunction();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Ensure the _write method types the chunk as TInput and encodes TOutput
|
|
88
|
+
async _write(chunk, encoding, callback) {
|
|
89
|
+
if (!this.writeAndTransformFunction) {
|
|
90
|
+
return callback(new Error('No stream function provided'));
|
|
91
|
+
}
|
|
92
|
+
const tools = {
|
|
93
|
+
truncate: () => {
|
|
94
|
+
this.push(null);
|
|
95
|
+
callback();
|
|
96
|
+
},
|
|
97
|
+
push: (pushArg) => this.push(pushArg),
|
|
98
|
+
};
|
|
99
|
+
try {
|
|
100
|
+
const modifiedChunk = await this.writeAndTransformFunction(chunk, tools);
|
|
101
|
+
if (modifiedChunk) {
|
|
102
|
+
if (!this.push(modifiedChunk)) {
|
|
103
|
+
// Handle backpressure if necessary
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
callback();
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
callback(err);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async _final(callback) {
|
|
113
|
+
if (this.streamEndFunction) {
|
|
114
|
+
const tools = {
|
|
115
|
+
truncate: () => callback(),
|
|
116
|
+
push: (pipeObject) => this.push(pipeObject),
|
|
117
|
+
};
|
|
118
|
+
try {
|
|
119
|
+
const finalChunk = await this.streamEndFunction(tools);
|
|
120
|
+
if (finalChunk) {
|
|
121
|
+
this.push(finalChunk);
|
|
122
|
+
}
|
|
123
|
+
callback();
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
callback(err);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
this.push(null),
|
|
131
|
+
callback();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzdHJlYW0uY2xhc3Nlcy5zbWFydGR1cGxleC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0c3RyZWFtLmNsYXNzZXMuc21hcnRkdXBsZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSwwQkFBMEIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsTUFBTSxFQUFzQixNQUFNLFFBQVEsQ0FBQztBQXNCcEQsTUFBTSxPQUFPLFdBQXlDLFNBQVEsTUFBTTtJQUNsRSxTQUFTO0lBQ1QsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFjLEVBQUUsT0FBdUI7UUFDdkQsTUFBTSxXQUFXLEdBQUcsSUFBSSxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDN0MsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDcEIsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN6QixXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsNkJBQTZCO1FBQ3ZELENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxXQUFXLENBQUM7SUFDckIsQ0FBQztJQUVELE1BQU0sQ0FBQyxjQUFjLENBQ25CLFVBQWdELEVBQ2hELE9BQXVCO1FBRXZCLE1BQU0sV0FBVyxHQUFHLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzdDLFdBQVcsQ0FBQyxzQkFBc0IsR0FBRyxVQUFVLENBQUMsU0FBUyxDQUFDO1lBQ3hELElBQUksRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFO2dCQUNiLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFO29CQUMzQixvREFBb0Q7b0JBQ3BELFdBQVcsQ0FBQyxzQkFBc0IsRUFBRSxXQUFXLEVBQUUsQ0FBQztvQkFDbEQsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO3dCQUM3QiwwREFBMEQ7d0JB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
|
|
@@ -1,21 +1,12 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
/// <reference types="from2" />
|
|
3
2
|
import * as plugins from './smartstream.plugins.js';
|
|
4
|
-
export declare class StreamIntake<T> {
|
|
3
|
+
export declare class StreamIntake<T> extends plugins.stream.Readable {
|
|
5
4
|
private signalEndBoolean;
|
|
6
5
|
private chunkStore;
|
|
7
6
|
pushNextObservable: plugins.smartrx.ObservableIntake<any>;
|
|
8
7
|
private pushedNextDeferred;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* returns a new style readble stream
|
|
13
|
-
*/
|
|
14
|
-
getReadable(): plugins.stream.Readable;
|
|
15
|
-
/**
|
|
16
|
-
* returns an oldstyle readble stream
|
|
17
|
-
*/
|
|
18
|
-
getReadableStream(): plugins.from2.Stream;
|
|
8
|
+
constructor(options?: plugins.stream.ReadableOptions);
|
|
9
|
+
_read(size: number): void;
|
|
19
10
|
pushData(chunkData: T): void;
|
|
20
11
|
signalEnd(): void;
|
|
21
12
|
}
|
|
@@ -1,47 +1,38 @@
|
|
|
1
1
|
import * as plugins from './smartstream.plugins.js';
|
|
2
|
-
export class StreamIntake {
|
|
3
|
-
constructor() {
|
|
2
|
+
export class StreamIntake extends plugins.stream.Readable {
|
|
3
|
+
constructor(options) {
|
|
4
|
+
super({ ...options, objectMode: true }); // Ensure that we are in object mode.
|
|
4
5
|
this.signalEndBoolean = false;
|
|
5
6
|
this.chunkStore = [];
|
|
6
7
|
this.pushNextObservable = new plugins.smartrx.ObservableIntake();
|
|
7
8
|
this.pushedNextDeferred = plugins.smartpromise.defer();
|
|
8
|
-
this.readableStream = plugins.from2.obj(async (size, next) => {
|
|
9
|
-
// console.log('get next');
|
|
10
|
-
// execute without backpressure
|
|
11
|
-
while (this.chunkStore.length > 0) {
|
|
12
|
-
next(null, this.chunkStore.shift());
|
|
13
|
-
}
|
|
14
|
-
if (this.signalEndBoolean) {
|
|
15
|
-
next(null, null);
|
|
16
|
-
}
|
|
17
|
-
// lets trigger backpressure handling
|
|
18
|
-
this.pushNextObservable.push('please push next');
|
|
19
|
-
await this.pushedNextDeferred.promise;
|
|
20
|
-
this.pushedNextDeferred = plugins.smartpromise.defer();
|
|
21
|
-
// execute with backpressure
|
|
22
|
-
while (this.chunkStore.length > 0) {
|
|
23
|
-
next(null, this.chunkStore.shift());
|
|
24
|
-
}
|
|
25
|
-
if (this.signalEndBoolean) {
|
|
26
|
-
next(null, null);
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
9
|
this.pushNextObservable.push('please push next');
|
|
30
10
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
11
|
+
_read(size) {
|
|
12
|
+
// console.log('get next');
|
|
13
|
+
const pushChunk = () => {
|
|
14
|
+
if (this.chunkStore.length > 0) {
|
|
15
|
+
// If push returns false, then we should stop reading
|
|
16
|
+
if (!this.push(this.chunkStore.shift())) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
if (this.chunkStore.length === 0) {
|
|
21
|
+
if (this.signalEndBoolean) {
|
|
22
|
+
// If we're done, push null to signal the end of the stream
|
|
23
|
+
this.push(null);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
// Ask for more data and wait
|
|
27
|
+
this.pushNextObservable.push('please push next');
|
|
28
|
+
this.pushedNextDeferred.promise.then(() => {
|
|
29
|
+
this.pushedNextDeferred = plugins.smartpromise.defer(); // Reset the deferred
|
|
30
|
+
pushChunk(); // Try pushing the next chunk
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
pushChunk();
|
|
45
36
|
}
|
|
46
37
|
pushData(chunkData) {
|
|
47
38
|
this.chunkStore.push(chunkData);
|
|
@@ -53,4 +44,4 @@ export class StreamIntake {
|
|
|
53
44
|
this.pushNextObservable.signalComplete();
|
|
54
45
|
}
|
|
55
46
|
}
|
|
56
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
47
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzdHJlYW0uY2xhc3Nlcy5zdHJlYW1pbnRha2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydHN0cmVhbS5jbGFzc2VzLnN0cmVhbWludGFrZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDBCQUEwQixDQUFDO0FBRXBELE1BQU0sT0FBTyxZQUFnQixTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUTtJQU0xRCxZQUFZLE9BQXdDO1FBQ2xELEtBQUssQ0FBQyxFQUFFLEdBQUcsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMscUNBQXFDO1FBTnhFLHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUN6QixlQUFVLEdBQVEsRUFBRSxDQUFDO1FBQ3RCLHVCQUFrQixHQUFHLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBTyxDQUFDO1FBQ2hFLHVCQUFrQixHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7UUFJeEQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRCxLQUFLLENBQUMsSUFBWTtRQUNoQiwyQkFBMkI7UUFDM0IsTUFBTSxTQUFTLEdBQUcsR0FBUyxFQUFFO1lBQzNCLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUM5QixxREFBcUQ7Z0JBQ3JELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRTtvQkFDdkMsT0FBTztpQkFDUjthQUNGO1lBRUQsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7Z0JBQ2hDLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFO29CQUN6QiwyREFBMkQ7b0JBQzNELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7aUJBQ2pCO3FCQUFNO29CQUNMLDZCQUE2QjtvQkFDN0IsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO29CQUNqRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7d0JBQ3hDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMscUJBQXFCO3dCQUM3RSxTQUFTLEVBQUUsQ0FBQyxDQUFDLDZCQUE2QjtvQkFDNUMsQ0FBQyxDQUFDLENBQUM7aUJBQ0o7YUFDRjtRQUNILENBQUMsQ0FBQztRQUVGLFNBQVMsRUFBRSxDQUFDO0lBQ2QsQ0FBQztJQUVNLFFBQVEsQ0FBQyxTQUFZO1FBQzFCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNwQyxDQUFDO0lBRU0sU0FBUztRQUNkLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDN0IsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUMzQyxDQUFDO0NBQ0YifQ==
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@push.rocks/smartstream",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "simplifies access to node streams",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -8,18 +8,19 @@
|
|
|
8
8
|
"type": "module",
|
|
9
9
|
"scripts": {
|
|
10
10
|
"test": "(tstest test/)",
|
|
11
|
-
"build": "(tsbuild)"
|
|
11
|
+
"build": "(tsbuild)",
|
|
12
|
+
"buildDocs": "tsdoc"
|
|
12
13
|
},
|
|
13
14
|
"repository": {
|
|
14
15
|
"type": "git",
|
|
15
|
-
"url": "git+
|
|
16
|
+
"url": "git+https://gitlab.com/push.rocks/smartstream.git"
|
|
16
17
|
},
|
|
17
18
|
"author": "Lossless GmbH",
|
|
18
19
|
"license": "MIT",
|
|
19
20
|
"bugs": {
|
|
20
|
-
"url": "https://gitlab.com/
|
|
21
|
+
"url": "https://gitlab.com/push.rocks/smartstream/issues"
|
|
21
22
|
},
|
|
22
|
-
"homepage": "https://gitlab.com/
|
|
23
|
+
"homepage": "https://gitlab.com/push.rocks/smartstream#readme",
|
|
23
24
|
"devDependencies": {
|
|
24
25
|
"@git.zone/tsbuild": "^2.1.66",
|
|
25
26
|
"@git.zone/tsrun": "^1.2.44",
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/index.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export * from './smartstream.classes.passthrough.js';
|
|
2
|
-
export * from './smartstream.classes.
|
|
2
|
+
export * from './smartstream.classes.smartduplex.js';
|
|
3
3
|
export * from './smartstream.classes.streamwrapper.js';
|
|
4
4
|
export * from './smartstream.classes.streamintake.js';
|
|
5
|
-
export * from './smartstream.duplex.js';
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import * as plugins from './smartstream.plugins.js';
|
|
2
|
+
import { Duplex, type DuplexOptions } from 'stream';
|
|
3
|
+
|
|
4
|
+
export interface IStreamTools {
|
|
5
|
+
truncate: () => void;
|
|
6
|
+
push: (pipeObject: any) => void;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface IWriteAndTransformFunction<T, rT> {
|
|
10
|
+
(chunkArg: T, toolsArg: IStreamTools): Promise<rT>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface IStreamEndFunction<rT> {
|
|
14
|
+
(toolsArg: IStreamTools): Promise<rT>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface SmartStreamOptions<TInput, TOutput> extends DuplexOptions {
|
|
18
|
+
readFunction?: () => Promise<void>;
|
|
19
|
+
writeAndTransformFunction?: IWriteAndTransformFunction<TInput, TOutput>;
|
|
20
|
+
streamEndFunction?: IStreamEndFunction<TOutput>;
|
|
21
|
+
// Add other custom options if necessary
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class SmartDuplex<TInput = any, TOutput = any> extends Duplex {
|
|
25
|
+
// STATIC
|
|
26
|
+
static fromBuffer(buffer: Buffer, options?: DuplexOptions): SmartDuplex {
|
|
27
|
+
const smartStream = new SmartDuplex(options);
|
|
28
|
+
process.nextTick(() => {
|
|
29
|
+
smartStream.push(buffer);
|
|
30
|
+
smartStream.push(null); // Signal the end of the data
|
|
31
|
+
});
|
|
32
|
+
return smartStream;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static fromObservable(
|
|
36
|
+
observable: plugins.smartrx.rxjs.Observable<any>,
|
|
37
|
+
options?: DuplexOptions
|
|
38
|
+
): SmartDuplex {
|
|
39
|
+
const smartStream = new SmartDuplex(options);
|
|
40
|
+
smartStream.observableSubscription = observable.subscribe({
|
|
41
|
+
next: (data) => {
|
|
42
|
+
if (!smartStream.push(data)) {
|
|
43
|
+
// Pause the observable if the stream buffer is full
|
|
44
|
+
smartStream.observableSubscription?.unsubscribe();
|
|
45
|
+
smartStream.once('drain', () => {
|
|
46
|
+
// Resume the observable when the stream buffer is drained
|
|
47
|
+
smartStream.observableSubscription?.unsubscribe();
|
|
48
|
+
smartStream.observableSubscription = observable.subscribe((data) => {
|
|
49
|
+
smartStream.push(data);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
error: (err) => {
|
|
55
|
+
smartStream.emit('error', err);
|
|
56
|
+
},
|
|
57
|
+
complete: () => {
|
|
58
|
+
smartStream.push(null); // Signal the end of the data
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return smartStream;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static fromReplaySubject(
|
|
66
|
+
replaySubject: plugins.smartrx.rxjs.ReplaySubject<any>,
|
|
67
|
+
options?: DuplexOptions
|
|
68
|
+
): SmartDuplex {
|
|
69
|
+
const smartStream = new SmartDuplex(options);
|
|
70
|
+
let isBackpressured = false;
|
|
71
|
+
|
|
72
|
+
// Subscribe to the ReplaySubject
|
|
73
|
+
const subscription = replaySubject.subscribe({
|
|
74
|
+
next: (data) => {
|
|
75
|
+
const canPush = smartStream.push(data);
|
|
76
|
+
if (!canPush) {
|
|
77
|
+
// If push returns false, pause the subscription because of backpressure
|
|
78
|
+
isBackpressured = true;
|
|
79
|
+
subscription.unsubscribe();
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
error: (err) => {
|
|
83
|
+
smartStream.emit('error', err);
|
|
84
|
+
},
|
|
85
|
+
complete: () => {
|
|
86
|
+
smartStream.push(null); // End the stream when the ReplaySubject completes
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Listen for 'drain' event to resume the subscription if it was paused
|
|
91
|
+
smartStream.on('drain', () => {
|
|
92
|
+
if (isBackpressured) {
|
|
93
|
+
isBackpressured = false;
|
|
94
|
+
// Resubscribe to the ReplaySubject since we previously paused
|
|
95
|
+
smartStream.observableSubscription = replaySubject.subscribe({
|
|
96
|
+
next: (data) => {
|
|
97
|
+
if (!smartStream.push(data)) {
|
|
98
|
+
smartStream.observableSubscription?.unsubscribe();
|
|
99
|
+
isBackpressured = true;
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
// No need to repeat error and complete handling here because it's already set up above
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
return smartStream;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// INSTANCE
|
|
111
|
+
private readFunction?: () => Promise<void>;
|
|
112
|
+
private writeAndTransformFunction?: IWriteAndTransformFunction<TInput, TOutput>;
|
|
113
|
+
private streamEndFunction?: IStreamEndFunction<TOutput>;
|
|
114
|
+
private observableSubscription?: plugins.smartrx.rxjs.Subscription;
|
|
115
|
+
|
|
116
|
+
constructor(optionsArg?: SmartStreamOptions<TInput, TOutput>) {
|
|
117
|
+
super(optionsArg);
|
|
118
|
+
this.readFunction = optionsArg?.readFunction;
|
|
119
|
+
this.writeAndTransformFunction = optionsArg?.writeAndTransformFunction;
|
|
120
|
+
this.streamEndFunction = optionsArg?.streamEndFunction;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
public async _read(size: number): Promise<void> {
|
|
124
|
+
if (this.readFunction) {
|
|
125
|
+
await this.readFunction();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Ensure the _write method types the chunk as TInput and encodes TOutput
|
|
130
|
+
public async _write(chunk: TInput, encoding: string, callback: (error?: Error | null) => void) {
|
|
131
|
+
if (!this.writeAndTransformFunction) {
|
|
132
|
+
return callback(new Error('No stream function provided'));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const tools: IStreamTools = {
|
|
136
|
+
truncate: () => {
|
|
137
|
+
this.push(null);
|
|
138
|
+
callback();
|
|
139
|
+
},
|
|
140
|
+
push: (pushArg: TOutput) => this.push(pushArg),
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
const modifiedChunk = await this.writeAndTransformFunction(chunk, tools);
|
|
145
|
+
if (modifiedChunk) {
|
|
146
|
+
if (!this.push(modifiedChunk)) {
|
|
147
|
+
// Handle backpressure if necessary
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
callback();
|
|
151
|
+
} catch (err) {
|
|
152
|
+
callback(err);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
public async _final(callback: (error?: Error | null) => void) {
|
|
157
|
+
if (this.streamEndFunction) {
|
|
158
|
+
const tools: IStreamTools = {
|
|
159
|
+
truncate: () => callback(),
|
|
160
|
+
push: (pipeObject) => this.push(pipeObject),
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
const finalChunk = await this.streamEndFunction(tools);
|
|
165
|
+
if (finalChunk) {
|
|
166
|
+
this.push(finalChunk);
|
|
167
|
+
}
|
|
168
|
+
callback();
|
|
169
|
+
} catch (err) {
|
|
170
|
+
callback(err);
|
|
171
|
+
}
|
|
172
|
+
} else {
|
|
173
|
+
this.push(null),
|
|
174
|
+
callback();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -1,56 +1,42 @@
|
|
|
1
1
|
import * as plugins from './smartstream.plugins.js';
|
|
2
2
|
|
|
3
|
-
export class StreamIntake<T> {
|
|
3
|
+
export class StreamIntake<T> extends plugins.stream.Readable {
|
|
4
4
|
private signalEndBoolean = false;
|
|
5
5
|
private chunkStore: T[] = [];
|
|
6
|
-
|
|
7
6
|
public pushNextObservable = new plugins.smartrx.ObservableIntake<any>();
|
|
8
|
-
|
|
9
7
|
private pushedNextDeferred = plugins.smartpromise.defer();
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// execute without backpressure
|
|
14
|
-
while (this.chunkStore.length > 0) {
|
|
15
|
-
next(null, this.chunkStore.shift());
|
|
16
|
-
}
|
|
17
|
-
if (this.signalEndBoolean) {
|
|
18
|
-
next(null, null);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// lets trigger backpressure handling
|
|
22
|
-
this.pushNextObservable.push('please push next');
|
|
23
|
-
await this.pushedNextDeferred.promise;
|
|
24
|
-
this.pushedNextDeferred = plugins.smartpromise.defer();
|
|
25
|
-
|
|
26
|
-
// execute with backpressure
|
|
27
|
-
while (this.chunkStore.length > 0) {
|
|
28
|
-
next(null, this.chunkStore.shift());
|
|
29
|
-
}
|
|
30
|
-
if (this.signalEndBoolean) {
|
|
31
|
-
next(null, null);
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
constructor() {
|
|
9
|
+
constructor(options?: plugins.stream.ReadableOptions) {
|
|
10
|
+
super({ ...options, objectMode: true }); // Ensure that we are in object mode.
|
|
36
11
|
this.pushNextObservable.push('please push next');
|
|
37
12
|
}
|
|
38
13
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
14
|
+
_read(size: number): void {
|
|
15
|
+
// console.log('get next');
|
|
16
|
+
const pushChunk = (): void => {
|
|
17
|
+
if (this.chunkStore.length > 0) {
|
|
18
|
+
// If push returns false, then we should stop reading
|
|
19
|
+
if (!this.push(this.chunkStore.shift())) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (this.chunkStore.length === 0) {
|
|
25
|
+
if (this.signalEndBoolean) {
|
|
26
|
+
// If we're done, push null to signal the end of the stream
|
|
27
|
+
this.push(null);
|
|
28
|
+
} else {
|
|
29
|
+
// Ask for more data and wait
|
|
30
|
+
this.pushNextObservable.push('please push next');
|
|
31
|
+
this.pushedNextDeferred.promise.then(() => {
|
|
32
|
+
this.pushedNextDeferred = plugins.smartpromise.defer(); // Reset the deferred
|
|
33
|
+
pushChunk(); // Try pushing the next chunk
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
pushChunk();
|
|
54
40
|
}
|
|
55
41
|
|
|
56
42
|
public pushData(chunkData: T) {
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
3
|
-
import * as plugins from './smartstream.plugins.js';
|
|
4
|
-
import { Duplex, type DuplexOptions } from 'stream';
|
|
5
|
-
export declare class SmartStream extends Duplex {
|
|
6
|
-
private observableSubscription?;
|
|
7
|
-
constructor(options?: DuplexOptions);
|
|
8
|
-
_read(size: number): void;
|
|
9
|
-
_write(chunk: any, encoding: string, callback: (error?: Error | null) => void): void;
|
|
10
|
-
static fromBuffer(buffer: Buffer, options?: DuplexOptions): SmartStream;
|
|
11
|
-
static fromObservable(observable: plugins.smartrx.rxjs.Observable<any>, options?: DuplexOptions): SmartStream;
|
|
12
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import * as plugins from './smartstream.plugins.js';
|
|
2
|
-
import { Duplex } from 'stream';
|
|
3
|
-
export class SmartStream extends Duplex {
|
|
4
|
-
constructor(options) {
|
|
5
|
-
super(options);
|
|
6
|
-
}
|
|
7
|
-
_read(size) {
|
|
8
|
-
// Implement if you need custom behavior, otherwise leave it empty
|
|
9
|
-
}
|
|
10
|
-
_write(chunk, encoding, callback) {
|
|
11
|
-
// Implement if you need custom behavior
|
|
12
|
-
callback();
|
|
13
|
-
}
|
|
14
|
-
static fromBuffer(buffer, options) {
|
|
15
|
-
const smartStream = new SmartStream(options);
|
|
16
|
-
process.nextTick(() => {
|
|
17
|
-
smartStream.push(buffer);
|
|
18
|
-
smartStream.push(null); // Signal the end of the data
|
|
19
|
-
});
|
|
20
|
-
return smartStream;
|
|
21
|
-
}
|
|
22
|
-
static fromObservable(observable, options) {
|
|
23
|
-
const smartStream = new SmartStream(options);
|
|
24
|
-
smartStream.observableSubscription = observable.subscribe({
|
|
25
|
-
next: (data) => {
|
|
26
|
-
if (!smartStream.push(data)) {
|
|
27
|
-
// Pause the observable if the stream buffer is full
|
|
28
|
-
smartStream.observableSubscription?.unsubscribe();
|
|
29
|
-
smartStream.once('drain', () => {
|
|
30
|
-
// Resume the observable when the stream buffer is drained
|
|
31
|
-
smartStream.observableSubscription?.unsubscribe();
|
|
32
|
-
smartStream.observableSubscription = observable.subscribe(data => {
|
|
33
|
-
smartStream.push(data);
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
error: (err) => {
|
|
39
|
-
smartStream.emit('error', err);
|
|
40
|
-
},
|
|
41
|
-
complete: () => {
|
|
42
|
-
smartStream.push(null); // Signal the end of the data
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
return smartStream;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzdHJlYW0uY2xhc3Nlcy5zbWFydHN0cmVhbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0c3RyZWFtLmNsYXNzZXMuc21hcnRzdHJlYW0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSwwQkFBMEIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsTUFBTSxFQUFzQixNQUFNLFFBQVEsQ0FBQztBQUVwRCxNQUFNLE9BQU8sV0FBWSxTQUFRLE1BQU07SUFHckMsWUFBWSxPQUF1QjtRQUNqQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDakIsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFZO1FBQ2hCLGtFQUFrRTtJQUNwRSxDQUFDO0lBRUQsTUFBTSxDQUFDLEtBQVUsRUFBRSxRQUFnQixFQUFFLFFBQXdDO1FBQzNFLHdDQUF3QztRQUN4QyxRQUFRLEVBQUUsQ0FBQztJQUNiLENBQUM7SUFFRCxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQWMsRUFBRSxPQUF1QjtRQUN2RCxNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM3QyxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUNwQixXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3pCLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyw2QkFBNkI7UUFDdkQsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDO0lBRUQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxVQUFnRCxFQUFFLE9BQXVCO1FBQzdGLE1BQU0sV0FBVyxHQUFHLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzdDLFdBQVcsQ0FBQyxzQkFBc0IsR0FBRyxVQUFVLENBQUMsU0FBUyxDQUFDO1lBQ3hELElBQUksRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFO2dCQUNiLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFO29CQUMzQixvREFBb0Q7b0JBQ3BELFdBQVcsQ0FBQyxzQkFBc0IsRUFBRSxXQUFXLEVBQUUsQ0FBQztvQkFDbEQsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO3dCQUM3QiwwREFBMEQ7d0JBQzFELFdBQVcsQ0FBQyxzQkFBc0IsRUFBRSxXQUFXLEVBQUUsQ0FBQzt3QkFDbEQsV0FBVyxDQUFDLHNCQUFzQixHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUU7NEJBQy9ELFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ3pCLENBQUMsQ0FBQyxDQUFDO29CQUNMLENBQUMsQ0FBQyxDQUFDO2lCQUNKO1lBQ0gsQ0FBQztZQUNELEtBQUssRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUNiLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ2pDLENBQUM7WUFDRCxRQUFRLEVBQUUsR0FBRyxFQUFFO2dCQUNiLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyw2QkFBNkI7WUFDdkQsQ0FBQztTQUNGLENBQUMsQ0FBQztRQUVILE9BQU8sV0FBVyxDQUFDO0lBQ3JCLENBQUM7Q0FDRiJ9
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import * as plugins from './smartstream.plugins.js';
|
|
2
|
-
export interface ITruncateFunc {
|
|
3
|
-
(): void;
|
|
4
|
-
}
|
|
5
|
-
export interface IPipeMoreFunc {
|
|
6
|
-
(pipeObject: any): void;
|
|
7
|
-
}
|
|
8
|
-
export interface IStreamTools {
|
|
9
|
-
truncate: ITruncateFunc;
|
|
10
|
-
pipeMore: IPipeMoreFunc;
|
|
11
|
-
}
|
|
12
|
-
export interface IStreamFunction<T, rT> {
|
|
13
|
-
(chunkArg: T, toolsArg: IStreamTools): Promise<rT>;
|
|
14
|
-
}
|
|
15
|
-
export interface IStreamEndFunction<rT> {
|
|
16
|
-
(toolsArg: IStreamTools): Promise<rT>;
|
|
17
|
-
}
|
|
18
|
-
export interface IStreamOptions {
|
|
19
|
-
objectMode?: boolean;
|
|
20
|
-
readableObjectMode?: boolean;
|
|
21
|
-
writableObjectMode?: boolean;
|
|
22
|
-
}
|
|
23
|
-
export declare let createDuplexStream: <T, rT>(funcArg: IStreamFunction<T, rT>, endFuncArg?: IStreamEndFunction<rT>, optionsArg?: IStreamOptions) => plugins.stream.Transform;
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import * as plugins from './smartstream.plugins.js';
|
|
2
|
-
export let createDuplexStream = (funcArg, endFuncArg, optionsArg = {
|
|
3
|
-
objectMode: false,
|
|
4
|
-
readableObjectMode: true,
|
|
5
|
-
writableObjectMode: true,
|
|
6
|
-
}) => {
|
|
7
|
-
return plugins.through2(optionsArg, function (chunk, enc, cb) {
|
|
8
|
-
let truncated = false;
|
|
9
|
-
const tools = {
|
|
10
|
-
truncate: () => {
|
|
11
|
-
truncated = true;
|
|
12
|
-
cb(null, null);
|
|
13
|
-
},
|
|
14
|
-
pipeMore: (pipeObject) => {
|
|
15
|
-
this.push(pipeObject);
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
const asyncWrapper = async () => {
|
|
19
|
-
const resultChunk = await funcArg(chunk, tools);
|
|
20
|
-
if (!truncated) {
|
|
21
|
-
cb(null, resultChunk);
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
asyncWrapper().catch((err) => {
|
|
25
|
-
console.log(err);
|
|
26
|
-
});
|
|
27
|
-
}, function (cb) {
|
|
28
|
-
const tools = {
|
|
29
|
-
truncate: () => {
|
|
30
|
-
cb();
|
|
31
|
-
},
|
|
32
|
-
pipeMore: (pushArg) => {
|
|
33
|
-
this.push(pushArg);
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
|
-
const asyncWrapper = async () => {
|
|
37
|
-
if (endFuncArg) {
|
|
38
|
-
const result = await endFuncArg(tools);
|
|
39
|
-
this.push(result);
|
|
40
|
-
}
|
|
41
|
-
cb();
|
|
42
|
-
};
|
|
43
|
-
asyncWrapper().catch((err) => {
|
|
44
|
-
console.log(err);
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
};
|
|
48
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzdHJlYW0uZHVwbGV4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRzdHJlYW0uZHVwbGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sMEJBQTBCLENBQUM7QUE2QnBELE1BQU0sQ0FBQyxJQUFJLGtCQUFrQixHQUFHLENBQzlCLE9BQStCLEVBQy9CLFVBQW1DLEVBQ25DLGFBQTZCO0lBQzNCLFVBQVUsRUFBRSxLQUFLO0lBQ2pCLGtCQUFrQixFQUFFLElBQUk7SUFDeEIsa0JBQWtCLEVBQUUsSUFBSTtDQUN6QixFQUNELEVBQUU7SUFDRixPQUFPLE9BQU8sQ0FBQyxRQUFRLENBQ3JCLFVBQVUsRUFDVixVQUFVLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUN0QixJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDdEIsTUFBTSxLQUFLLEdBQWlCO1lBQzFCLFFBQVEsRUFBRSxHQUFHLEVBQUU7Z0JBQ2IsU0FBUyxHQUFHLElBQUksQ0FBQztnQkFDakIsRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNqQixDQUFDO1lBQ0QsUUFBUSxFQUFFLENBQUMsVUFBVSxFQUFFLEVBQUU7Z0JBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEIsQ0FBQztTQUNGLENBQUM7UUFDRixNQUFNLFlBQVksR0FBRyxLQUFLLElBQUksRUFBRTtZQUM5QixNQUFNLFdBQVcsR0FBTyxNQUFNLE9BQU8sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDcEQsSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFDZCxFQUFFLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO2FBQ3ZCO1FBQ0gsQ0FBQyxDQUFDO1FBQ0YsWUFBWSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDM0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNuQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsRUFDRCxVQUFVLEVBQUU7UUFDVixNQUFNLEtBQUssR0FBaUI7WUFDMUIsUUFBUSxFQUFFLEdBQUcsRUFBRTtnQkFDYixFQUFFLEVBQUUsQ0FBQztZQUNQLENBQUM7WUFDRCxRQUFRLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRTtnQkFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNyQixDQUFDO1NBQ0YsQ0FBQztRQUNGLE1BQU0sWUFBWSxHQUFHLEtBQUssSUFBSSxFQUFFO1lBQzlCLElBQUksVUFBVSxFQUFFO2dCQUNkLE1BQU0sTUFBTSxHQUFHLE1BQU0sVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUN2QyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQ25CO1lBQ0QsRUFBRSxFQUFFLENBQUM7UUFDUCxDQUFDLENBQUM7UUFDRixZQUFZLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUMzQixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25CLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUNGLENBQUM7QUFDSixDQUFDLENBQUMifQ==
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import * as plugins from './smartstream.plugins.js';
|
|
2
|
-
import { Duplex, type DuplexOptions } from 'stream';
|
|
3
|
-
|
|
4
|
-
export class SmartStream extends Duplex {
|
|
5
|
-
private observableSubscription?: plugins.smartrx.rxjs.Subscription;
|
|
6
|
-
|
|
7
|
-
constructor(options?: DuplexOptions) {
|
|
8
|
-
super(options);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
_read(size: number) {
|
|
12
|
-
// Implement if you need custom behavior, otherwise leave it empty
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
_write(chunk: any, encoding: string, callback: (error?: Error | null) => void) {
|
|
16
|
-
// Implement if you need custom behavior
|
|
17
|
-
callback();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
static fromBuffer(buffer: Buffer, options?: DuplexOptions): SmartStream {
|
|
21
|
-
const smartStream = new SmartStream(options);
|
|
22
|
-
process.nextTick(() => {
|
|
23
|
-
smartStream.push(buffer);
|
|
24
|
-
smartStream.push(null); // Signal the end of the data
|
|
25
|
-
});
|
|
26
|
-
return smartStream;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
static fromObservable(observable: plugins.smartrx.rxjs.Observable<any>, options?: DuplexOptions): SmartStream {
|
|
30
|
-
const smartStream = new SmartStream(options);
|
|
31
|
-
smartStream.observableSubscription = observable.subscribe({
|
|
32
|
-
next: (data) => {
|
|
33
|
-
if (!smartStream.push(data)) {
|
|
34
|
-
// Pause the observable if the stream buffer is full
|
|
35
|
-
smartStream.observableSubscription?.unsubscribe();
|
|
36
|
-
smartStream.once('drain', () => {
|
|
37
|
-
// Resume the observable when the stream buffer is drained
|
|
38
|
-
smartStream.observableSubscription?.unsubscribe();
|
|
39
|
-
smartStream.observableSubscription = observable.subscribe(data => {
|
|
40
|
-
smartStream.push(data);
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
error: (err) => {
|
|
46
|
-
smartStream.emit('error', err);
|
|
47
|
-
},
|
|
48
|
-
complete: () => {
|
|
49
|
-
smartStream.push(null); // Signal the end of the data
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
return smartStream;
|
|
54
|
-
}
|
|
55
|
-
}
|
package/ts/smartstream.duplex.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import * as plugins from './smartstream.plugins.js';
|
|
2
|
-
|
|
3
|
-
export interface ITruncateFunc {
|
|
4
|
-
(): void;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface IPipeMoreFunc {
|
|
8
|
-
(pipeObject: any): void;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface IStreamTools {
|
|
12
|
-
truncate: ITruncateFunc;
|
|
13
|
-
pipeMore: IPipeMoreFunc;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface IStreamFunction<T, rT> {
|
|
17
|
-
(chunkArg: T, toolsArg: IStreamTools): Promise<rT>;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface IStreamEndFunction<rT> {
|
|
21
|
-
(toolsArg: IStreamTools): Promise<rT>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface IStreamOptions {
|
|
25
|
-
objectMode?: boolean;
|
|
26
|
-
readableObjectMode?: boolean;
|
|
27
|
-
writableObjectMode?: boolean;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export let createDuplexStream = <T, rT>(
|
|
31
|
-
funcArg: IStreamFunction<T, rT>,
|
|
32
|
-
endFuncArg?: IStreamEndFunction<rT>,
|
|
33
|
-
optionsArg: IStreamOptions = {
|
|
34
|
-
objectMode: false,
|
|
35
|
-
readableObjectMode: true,
|
|
36
|
-
writableObjectMode: true,
|
|
37
|
-
}
|
|
38
|
-
) => {
|
|
39
|
-
return plugins.through2(
|
|
40
|
-
optionsArg,
|
|
41
|
-
function (chunk, enc, cb) {
|
|
42
|
-
let truncated = false;
|
|
43
|
-
const tools: IStreamTools = {
|
|
44
|
-
truncate: () => {
|
|
45
|
-
truncated = true;
|
|
46
|
-
cb(null, null);
|
|
47
|
-
},
|
|
48
|
-
pipeMore: (pipeObject) => {
|
|
49
|
-
this.push(pipeObject);
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
const asyncWrapper = async () => {
|
|
53
|
-
const resultChunk: rT = await funcArg(chunk, tools);
|
|
54
|
-
if (!truncated) {
|
|
55
|
-
cb(null, resultChunk);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
asyncWrapper().catch((err) => {
|
|
59
|
-
console.log(err);
|
|
60
|
-
});
|
|
61
|
-
},
|
|
62
|
-
function (cb) {
|
|
63
|
-
const tools: IStreamTools = {
|
|
64
|
-
truncate: () => {
|
|
65
|
-
cb();
|
|
66
|
-
},
|
|
67
|
-
pipeMore: (pushArg) => {
|
|
68
|
-
this.push(pushArg);
|
|
69
|
-
},
|
|
70
|
-
};
|
|
71
|
-
const asyncWrapper = async () => {
|
|
72
|
-
if (endFuncArg) {
|
|
73
|
-
const result = await endFuncArg(tools);
|
|
74
|
-
this.push(result);
|
|
75
|
-
}
|
|
76
|
-
cb();
|
|
77
|
-
};
|
|
78
|
-
asyncWrapper().catch((err) => {
|
|
79
|
-
console.log(err);
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
);
|
|
83
|
-
};
|