@yume-chan/stream-extra 0.0.17 → 0.0.18
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/CHANGELOG.json +12 -0
- package/CHANGELOG.md +8 -1
- package/LICENSE +1 -1
- package/README.md +34 -2
- package/esm/buffered-transform.d.ts +3 -3
- package/esm/buffered-transform.d.ts.map +1 -1
- package/esm/buffered-transform.js +17 -11
- package/esm/buffered-transform.js.map +1 -1
- package/esm/buffered.d.ts +2 -2
- package/esm/buffered.d.ts.map +1 -1
- package/esm/buffered.js +6 -13
- package/esm/buffered.js.map +1 -1
- package/esm/decode-utf8.d.ts.map +1 -1
- package/esm/decode-utf8.js +1 -1
- package/esm/decode-utf8.js.map +1 -1
- package/esm/duplex.d.ts +2 -2
- package/esm/duplex.d.ts.map +1 -1
- package/esm/duplex.js +17 -13
- package/esm/duplex.js.map +1 -1
- package/esm/pipe-from.d.ts +4 -5
- package/esm/pipe-from.d.ts.map +1 -1
- package/esm/pipe-from.js +3 -4
- package/esm/pipe-from.js.map +1 -1
- package/esm/push-readable.d.ts +10 -3
- package/esm/push-readable.d.ts.map +1 -1
- package/esm/push-readable.js +20 -5
- package/esm/push-readable.js.map +1 -1
- package/esm/stream.d.ts +11 -4
- package/esm/stream.d.ts.map +1 -1
- package/esm/stream.js +26 -3
- package/esm/stream.js.map +1 -1
- package/esm/struct-deserialize.d.ts +2 -2
- package/esm/struct-deserialize.d.ts.map +1 -1
- package/esm/struct-deserialize.js +1 -1
- package/esm/struct-deserialize.js.map +1 -1
- package/esm/struct-serialize.d.ts +1 -1
- package/esm/struct-serialize.d.ts.map +1 -1
- package/esm/struct-serialize.js.map +1 -1
- package/esm/trace.d.ts +16 -0
- package/esm/trace.d.ts.map +1 -0
- package/esm/trace.js +131 -0
- package/esm/trace.js.map +1 -0
- package/esm/wrap-readable.d.ts +4 -4
- package/esm/wrap-readable.d.ts.map +1 -1
- package/esm/wrap-readable.js +6 -6
- package/esm/wrap-readable.js.map +1 -1
- package/esm/wrap-writable.d.ts +3 -3
- package/esm/wrap-writable.d.ts.map +1 -1
- package/esm/wrap-writable.js +4 -4
- package/esm/wrap-writable.js.map +1 -1
- package/package.json +12 -9
- package/src/buffered-transform.ts +37 -17
- package/src/buffered.ts +12 -15
- package/src/decode-utf8.ts +3 -2
- package/src/duplex.ts +27 -9
- package/src/pipe-from.ts +3 -4
- package/src/push-readable.ts +79 -44
- package/src/stream.ts +49 -7
- package/src/struct-deserialize.ts +7 -5
- package/src/struct-serialize.ts +4 -2
- package/src/wrap-readable.ts +31 -13
- package/src/wrap-writable.ts +21 -10
- package/tsconfig.build.json +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/esm/native.d.ts +0 -240
- package/esm/native.d.ts.map +0 -1
- package/esm/native.js +0 -60
- package/esm/native.js.map +0 -1
- package/src/native.ts +0 -362
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type Struct from "@yume-chan/struct";
|
|
2
2
|
import { TransformStream } from "./stream.js";
|
|
3
|
-
export declare class StructSerializeStream<T extends Struct<any, any, any, any>> extends TransformStream<T[
|
|
3
|
+
export declare class StructSerializeStream<T extends Struct<any, any, any, any>> extends TransformStream<T["TInit"], Uint8Array> {
|
|
4
4
|
constructor(struct: T);
|
|
5
5
|
}
|
|
6
6
|
//# sourceMappingURL=struct-serialize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"struct-serialize.d.ts","sourceRoot":"","sources":["../src/struct-serialize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"struct-serialize.d.ts","sourceRoot":"","sources":["../src/struct-serialize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,qBAAa,qBAAqB,CAC9B,CAAC,SAAS,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CACtC,SAAQ,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC;gBACjC,MAAM,EAAE,CAAC;CAOxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"struct-serialize.js","sourceRoot":"","sources":["../src/struct-serialize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"struct-serialize.js","sourceRoot":"","sources":["../src/struct-serialize.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,OAAO,qBAEX,SAAQ,eAAuC;IAC7C,YAAY,MAAS;QACjB,KAAK,CAAC;YACF,SAAS,CAAC,KAAK,EAAE,UAAU;gBACvB,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YAChD,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;CACJ"}
|
package/esm/trace.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ReadableStream, WritableStream, type ReadableWritablePair } from "./stream.js";
|
|
2
|
+
export declare const PRESSURE_WARNINGS: Map<string, number[]>;
|
|
3
|
+
export declare class PressureSensor<R> implements ReadableWritablePair<R, R> {
|
|
4
|
+
private _readable;
|
|
5
|
+
get readable(): ReadableStream<R>;
|
|
6
|
+
private _writable;
|
|
7
|
+
get writable(): WritableStream<R>;
|
|
8
|
+
private _name;
|
|
9
|
+
private _ended;
|
|
10
|
+
private _cancelReason;
|
|
11
|
+
private _readAhead;
|
|
12
|
+
private _writeAhead;
|
|
13
|
+
private _writeLock;
|
|
14
|
+
constructor(name: string, size: number);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=trace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../src/trace.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,cAAc,EACd,cAAc,EACd,KAAK,oBAAoB,EAC5B,MAAM,aAAa,CAAC;AAiDrB,eAAO,MAAM,iBAAiB,uBAA8B,CAAC;AAE7D,qBAAa,cAAc,CAAC,CAAC,CAAE,YAAW,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC;IAChE,OAAO,CAAC,SAAS,CAAoB;IACrC,IAAW,QAAQ,sBAElB;IACD,OAAO,CAAC,SAAS,CAAoB;IACrC,IAAW,QAAQ,sBAElB;IAED,OAAO,CAAC,KAAK,CAAS;IAEtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,UAAU,CAA6C;IAC/D,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,UAAU,CAAoC;gBAEnC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CA+EhD"}
|
package/esm/trace.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { PromiseResolver } from "@yume-chan/async";
|
|
2
|
+
import { ReadableStream, WritableStream, } from "./stream.js";
|
|
3
|
+
class RingBuffer {
|
|
4
|
+
_capacity;
|
|
5
|
+
get capacity() {
|
|
6
|
+
return this._capacity;
|
|
7
|
+
}
|
|
8
|
+
_size;
|
|
9
|
+
get size() {
|
|
10
|
+
return this._size;
|
|
11
|
+
}
|
|
12
|
+
_buffer;
|
|
13
|
+
_head;
|
|
14
|
+
_tail;
|
|
15
|
+
constructor(capacity) {
|
|
16
|
+
this._capacity = capacity;
|
|
17
|
+
this._size = 0;
|
|
18
|
+
this._head = 0;
|
|
19
|
+
this._tail = 0;
|
|
20
|
+
this._buffer = new Array(capacity);
|
|
21
|
+
}
|
|
22
|
+
push(value) {
|
|
23
|
+
this._buffer[this._head] = value;
|
|
24
|
+
this._size += 1;
|
|
25
|
+
this._head = (this._head + 1) % this._capacity;
|
|
26
|
+
if (this._head === this._tail) {
|
|
27
|
+
this._tail = (this._tail + 1) % this._capacity;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
shift() {
|
|
31
|
+
if (this._head === this._tail) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
this._size -= 1;
|
|
35
|
+
const value = this._buffer[this._tail];
|
|
36
|
+
this._tail = (this._tail + 1) % this._capacity;
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
peekFirst() {
|
|
40
|
+
return this._buffer[this._tail];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export const PRESSURE_WARNINGS = new Map();
|
|
44
|
+
export class PressureSensor {
|
|
45
|
+
_readable;
|
|
46
|
+
get readable() {
|
|
47
|
+
return this._readable;
|
|
48
|
+
}
|
|
49
|
+
_writable;
|
|
50
|
+
get writable() {
|
|
51
|
+
return this._writable;
|
|
52
|
+
}
|
|
53
|
+
_name;
|
|
54
|
+
_ended = false;
|
|
55
|
+
_cancelReason = undefined;
|
|
56
|
+
_readAhead;
|
|
57
|
+
_writeAhead;
|
|
58
|
+
_writeLock;
|
|
59
|
+
constructor(name, size) {
|
|
60
|
+
this._name = name;
|
|
61
|
+
this._readAhead = new RingBuffer(size);
|
|
62
|
+
this._writeAhead = new RingBuffer(size);
|
|
63
|
+
this._readable = new ReadableStream({
|
|
64
|
+
pull: async (controller) => {
|
|
65
|
+
if (this._writeAhead.size !== 0) {
|
|
66
|
+
controller.enqueue(this._writeAhead.shift());
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (this._ended) {
|
|
70
|
+
controller.close();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const resolver = new PromiseResolver();
|
|
74
|
+
this._readAhead.push(resolver);
|
|
75
|
+
const chunk = await resolver.promise;
|
|
76
|
+
if (chunk === undefined) {
|
|
77
|
+
controller.close();
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
controller.enqueue(chunk);
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
cancel: (reason) => {
|
|
84
|
+
this._cancelReason = reason;
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
this._writable = new WritableStream({
|
|
88
|
+
write: (chunk) => {
|
|
89
|
+
if (this._cancelReason !== undefined) {
|
|
90
|
+
throw this._cancelReason;
|
|
91
|
+
}
|
|
92
|
+
if (this._readAhead.size !== 0) {
|
|
93
|
+
this._readAhead.shift().resolve(chunk);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (this._writeAhead.size === this._writeAhead.capacity) {
|
|
97
|
+
if (this._writeLock) {
|
|
98
|
+
throw new Error(`PressureSensor ${this._name}: the producer keeps writing without monitoring the pressure.`);
|
|
99
|
+
}
|
|
100
|
+
const warnings = PRESSURE_WARNINGS.get(this._name);
|
|
101
|
+
if (warnings) {
|
|
102
|
+
warnings.push(Date.now());
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
PRESSURE_WARNINGS.set(this._name, [Date.now()]);
|
|
106
|
+
}
|
|
107
|
+
this._writeLock = new PromiseResolver();
|
|
108
|
+
return this._writeLock.promise.then(() => {
|
|
109
|
+
this._writeLock = undefined;
|
|
110
|
+
this._writeAhead.push(chunk);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
this._writeAhead.push(chunk);
|
|
114
|
+
return undefined;
|
|
115
|
+
},
|
|
116
|
+
close: () => {
|
|
117
|
+
this._ended = true;
|
|
118
|
+
while (this._readAhead.size !== 0) {
|
|
119
|
+
this._readAhead.shift().resolve(undefined);
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
abort: (reason) => {
|
|
123
|
+
this._ended = true;
|
|
124
|
+
while (this._readAhead.size !== 0) {
|
|
125
|
+
this._readAhead.shift().reject(reason);
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=trace.js.map
|
package/esm/trace.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../src/trace.ts"],"names":[],"mappings":"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"}
|
package/esm/wrap-readable.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { ReadableStream, ReadableStreamDefaultController } from "./stream.js";
|
|
3
|
-
export
|
|
1
|
+
import { type ValueOrPromise } from "@yume-chan/struct";
|
|
2
|
+
import { ReadableStream, type ReadableStreamDefaultController } from "./stream.js";
|
|
3
|
+
export type WrapReadableStreamStart<T> = (controller: ReadableStreamDefaultController<T>) => ValueOrPromise<ReadableStream<T>>;
|
|
4
4
|
export interface ReadableStreamWrapper<T> {
|
|
5
5
|
start: WrapReadableStreamStart<T>;
|
|
6
|
-
cancel?(reason?:
|
|
6
|
+
cancel?(reason?: unknown): ValueOrPromise<void>;
|
|
7
7
|
close?(): ValueOrPromise<void>;
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap-readable.d.ts","sourceRoot":"","sources":["../src/wrap-readable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"wrap-readable.d.ts","sourceRoot":"","sources":["../src/wrap-readable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EACH,cAAc,EACd,KAAK,+BAA+B,EAEvC,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,CACrC,UAAU,EAAE,+BAA+B,CAAC,CAAC,CAAC,KAC7C,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvC,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACpC,KAAK,EAAE,uBAAuB,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC;CAClC;AAoBD;;;;;;GAMG;AACH,qBAAa,kBAAkB,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;IACjD,QAAQ,EAAG,cAAc,CAAC,CAAC,CAAC,CAAC;IAEpC,OAAO,CAAC,MAAM,CAAkC;gBAG5C,OAAO,EACD,cAAc,CAAC,CAAC,CAAC,GACjB,uBAAuB,CAAC,CAAC,CAAC,GAC1B,qBAAqB,CAAC,CAAC,CAAC;CAmCrC"}
|
package/esm/wrap-readable.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { ReadableStream } from "./stream.js";
|
|
1
|
+
import { ReadableStream, } from "./stream.js";
|
|
2
2
|
function getWrappedReadableStream(wrapper, controller) {
|
|
3
|
-
if (
|
|
3
|
+
if ("start" in wrapper) {
|
|
4
4
|
return wrapper.start(controller);
|
|
5
5
|
}
|
|
6
|
-
else if (typeof wrapper ===
|
|
6
|
+
else if (typeof wrapper === "function") {
|
|
7
7
|
return wrapper(controller);
|
|
8
8
|
}
|
|
9
9
|
else {
|
|
@@ -35,7 +35,7 @@ export class WrapReadableStream extends ReadableStream {
|
|
|
35
35
|
},
|
|
36
36
|
cancel: async (reason) => {
|
|
37
37
|
await this.reader.cancel(reason);
|
|
38
|
-
if (
|
|
38
|
+
if ("cancel" in wrapper) {
|
|
39
39
|
await wrapper.cancel?.(reason);
|
|
40
40
|
}
|
|
41
41
|
},
|
|
@@ -43,14 +43,14 @@ export class WrapReadableStream extends ReadableStream {
|
|
|
43
43
|
const result = await this.reader.read();
|
|
44
44
|
if (result.done) {
|
|
45
45
|
controller.close();
|
|
46
|
-
if (
|
|
46
|
+
if ("close" in wrapper) {
|
|
47
47
|
await wrapper.close?.();
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
else {
|
|
51
51
|
controller.enqueue(result.value);
|
|
52
52
|
}
|
|
53
|
-
}
|
|
53
|
+
},
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
56
|
}
|
package/esm/wrap-readable.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap-readable.js","sourceRoot":"","sources":["../src/wrap-readable.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wrap-readable.js","sourceRoot":"","sources":["../src/wrap-readable.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,cAAc,GAGjB,MAAM,aAAa,CAAC;AAYrB,SAAS,wBAAwB,CAC7B,OAG8B,EAC9B,UAA8C;IAE9C,IAAI,OAAO,IAAI,OAAO,EAAE;QACpB,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;KACpC;SAAM,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE;QACtC,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC;KAC9B;SAAM;QACH,gDAAgD;QAChD,wEAAwE;QACxE,OAAO,OAAO,CAAC;KAClB;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,kBAAsB,SAAQ,cAAiB;IACjD,QAAQ,CAAqB;IAE5B,MAAM,CAAkC;IAEhD,YACI,OAG8B;QAE9B,KAAK,CAAC;YACF,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;gBACxB,mEAAmE;gBACnE,uCAAuC;gBACvC,gHAAgH;gBAChH,mCAAmC;gBACnC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;gBAExB,IAAI,CAAC,QAAQ,GAAG,MAAM,wBAAwB,CAC1C,OAAO,EACP,UAAU,CACb,CAAC;gBACF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;YAC5C,CAAC;YACD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBACrB,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,QAAQ,IAAI,OAAO,EAAE;oBACrB,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;iBAClC;YACL,CAAC;YACD,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;gBACvB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBACxC,IAAI,MAAM,CAAC,IAAI,EAAE;oBACb,UAAU,CAAC,KAAK,EAAE,CAAC;oBACnB,IAAI,OAAO,IAAI,OAAO,EAAE;wBACpB,MAAM,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;qBAC3B;iBACJ;qBAAM;oBACH,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;iBACpC;YACL,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;CACJ"}
|
package/esm/wrap-writable.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ValueOrPromise } from "@yume-chan/struct";
|
|
2
2
|
import { WritableStream } from "./stream.js";
|
|
3
|
-
export
|
|
3
|
+
export type WrapWritableStreamStart<T> = () => ValueOrPromise<WritableStream<T>>;
|
|
4
4
|
export interface WritableStreamWrapper<T> {
|
|
5
5
|
start: WrapWritableStreamStart<T>;
|
|
6
|
-
close?(): Promise<void>;
|
|
6
|
+
close?(): void | Promise<void>;
|
|
7
7
|
}
|
|
8
8
|
export declare class WrapWritableStream<T> extends WritableStream<T> {
|
|
9
9
|
writable: WritableStream<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap-writable.d.ts","sourceRoot":"","sources":["../src/wrap-writable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"wrap-writable.d.ts","sourceRoot":"","sources":["../src/wrap-writable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EAAE,cAAc,EAAoC,MAAM,aAAa,CAAC;AAE/E,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,MAAM,cAAc,CACzD,cAAc,CAAC,CAAC,CAAC,CACpB,CAAC;AAEF,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACpC,KAAK,EAAE,uBAAuB,CAAC,CAAC,CAAC,CAAC;IAClC,KAAK,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;AAmBD,qBAAa,kBAAkB,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;IACjD,QAAQ,EAAG,cAAc,CAAC,CAAC,CAAC,CAAC;IAEpC,OAAO,CAAC,MAAM,CAAkC;gBAG5C,OAAO,EACD,cAAc,CAAC,CAAC,CAAC,GACjB,uBAAuB,CAAC,CAAC,CAAC,GAC1B,qBAAqB,CAAC,CAAC,CAAC;CAoCrC"}
|
package/esm/wrap-writable.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { WritableStream } from "./stream.js";
|
|
2
2
|
async function getWrappedWritableStream(wrapper) {
|
|
3
|
-
if (
|
|
3
|
+
if ("start" in wrapper) {
|
|
4
4
|
return await wrapper.start();
|
|
5
5
|
}
|
|
6
|
-
else if (typeof wrapper ===
|
|
6
|
+
else if (typeof wrapper === "function") {
|
|
7
7
|
return await wrapper();
|
|
8
8
|
}
|
|
9
9
|
else {
|
|
@@ -33,7 +33,7 @@ export class WrapWritableStream extends WritableStream {
|
|
|
33
33
|
},
|
|
34
34
|
abort: async (reason) => {
|
|
35
35
|
await this.writer.abort(reason);
|
|
36
|
-
if (
|
|
36
|
+
if ("close" in wrapper) {
|
|
37
37
|
await wrapper.close?.();
|
|
38
38
|
}
|
|
39
39
|
},
|
|
@@ -43,7 +43,7 @@ export class WrapWritableStream extends WritableStream {
|
|
|
43
43
|
// closing the outer stream first will make the inner stream incapable of
|
|
44
44
|
// sending data in its `close` handler.
|
|
45
45
|
await this.writer.close();
|
|
46
|
-
if (
|
|
46
|
+
if ("close" in wrapper) {
|
|
47
47
|
await wrapper.close?.();
|
|
48
48
|
}
|
|
49
49
|
},
|
package/esm/wrap-writable.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap-writable.js","sourceRoot":"","sources":["../src/wrap-writable.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wrap-writable.js","sourceRoot":"","sources":["../src/wrap-writable.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAoC,MAAM,aAAa,CAAC;AAW/E,KAAK,UAAU,wBAAwB,CACnC,OAG8B;IAE9B,IAAI,OAAO,IAAI,OAAO,EAAE;QACpB,OAAO,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;KAChC;SAAM,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE;QACtC,OAAO,MAAM,OAAO,EAAE,CAAC;KAC1B;SAAM;QACH,gDAAgD;QAChD,wEAAwE;QACxE,OAAO,OAAO,CAAC;KAClB;AACL,CAAC;AAED,MAAM,OAAO,kBAAsB,SAAQ,cAAiB;IACjD,QAAQ,CAAqB;IAE5B,MAAM,CAAkC;IAEhD,YACI,OAG8B;QAE9B,KAAK,CAAC;YACF,KAAK,EAAE,KAAK,IAAI,EAAE;gBACd,mEAAmE;gBACnE,uCAAuC;gBACvC,gHAAgH;gBAChH,mCAAmC;gBACnC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;gBAExB,IAAI,CAAC,QAAQ,GAAG,MAAM,wBAAwB,CAAC,OAAO,CAAC,CAAC;gBACxD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;YAC5C,CAAC;YACD,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACnB,yBAAyB;gBACzB,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;gBACxB,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC;YACD,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBACpB,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAChC,IAAI,OAAO,IAAI,OAAO,EAAE;oBACpB,MAAM,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;iBAC3B;YACL,CAAC;YACD,KAAK,EAAE,KAAK,IAAI,EAAE;gBACd,gCAAgC;gBAChC,0EAA0E;gBAC1E,yEAAyE;gBACzE,uCAAuC;gBACvC,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC1B,IAAI,OAAO,IAAI,OAAO,EAAE;oBACpB,MAAM,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;iBAC3B;YACL,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;CACJ"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yume-chan/stream-extra",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"description": "Extensions to Web Streams API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"stream",
|
|
@@ -26,21 +26,24 @@
|
|
|
26
26
|
"types": "esm/index.d.ts",
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@yume-chan/async": "^2.2.0",
|
|
29
|
-
"@yume-chan/struct": "^0.0.
|
|
30
|
-
"tslib": "^2.4.
|
|
29
|
+
"@yume-chan/struct": "^0.0.18",
|
|
30
|
+
"tslib": "^2.4.1",
|
|
31
31
|
"web-streams-polyfill": "^4.0.0-beta.3"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@jest/globals": "^
|
|
35
|
-
"@yume-chan/
|
|
34
|
+
"@jest/globals": "^29.3.1",
|
|
35
|
+
"@yume-chan/eslint-config": "^1.0.0",
|
|
36
|
+
"@yume-chan/tsconfig": "^1.0.0",
|
|
36
37
|
"cross-env": "^7.0.3",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
38
|
+
"eslint": "^8.31.0",
|
|
39
|
+
"jest": "^29.3.1",
|
|
40
|
+
"ts-jest": "^29.0.4",
|
|
41
|
+
"typescript": "^4.9.4"
|
|
40
42
|
},
|
|
41
43
|
"scripts": {
|
|
42
44
|
"build": "tsc -b tsconfig.build.json",
|
|
43
45
|
"build:watch": "tsc -b tsconfig.build.json",
|
|
44
|
-
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --coverage"
|
|
46
|
+
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --coverage",
|
|
47
|
+
"lint": "eslint src/**/*.ts --fix"
|
|
45
48
|
}
|
|
46
49
|
}
|
|
@@ -1,24 +1,44 @@
|
|
|
1
|
-
import type
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { type ValueOrPromise } from "@yume-chan/struct";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
BufferedReadableStream,
|
|
5
|
+
BufferedReadableStreamEndedError,
|
|
6
|
+
} from "./buffered.js";
|
|
7
|
+
import {
|
|
8
|
+
PushReadableStream,
|
|
9
|
+
type PushReadableStreamController,
|
|
10
|
+
} from "./push-readable.js";
|
|
11
|
+
import {
|
|
12
|
+
ReadableStream,
|
|
13
|
+
WritableStream,
|
|
14
|
+
type ReadableWritablePair,
|
|
15
|
+
} from "./stream.js";
|
|
5
16
|
|
|
6
17
|
// TODO: BufferedTransformStream: find better implementation
|
|
7
|
-
export class BufferedTransformStream<T>
|
|
18
|
+
export class BufferedTransformStream<T>
|
|
19
|
+
implements ReadableWritablePair<T, Uint8Array>
|
|
20
|
+
{
|
|
8
21
|
private _readable: ReadableStream<T>;
|
|
9
|
-
public get readable() {
|
|
22
|
+
public get readable() {
|
|
23
|
+
return this._readable;
|
|
24
|
+
}
|
|
10
25
|
|
|
11
26
|
private _writable: WritableStream<Uint8Array>;
|
|
12
|
-
public get writable() {
|
|
27
|
+
public get writable() {
|
|
28
|
+
return this._writable;
|
|
29
|
+
}
|
|
13
30
|
|
|
14
|
-
constructor(
|
|
31
|
+
constructor(
|
|
32
|
+
transform: (stream: BufferedReadableStream) => ValueOrPromise<T>
|
|
33
|
+
) {
|
|
15
34
|
// Convert incoming chunks to a `BufferedReadableStream`
|
|
16
35
|
let sourceStreamController!: PushReadableStreamController<Uint8Array>;
|
|
17
36
|
|
|
18
|
-
const buffered = new BufferedReadableStream(
|
|
19
|
-
controller =>
|
|
20
|
-
sourceStreamController = controller
|
|
21
|
-
|
|
37
|
+
const buffered = new BufferedReadableStream(
|
|
38
|
+
new PushReadableStream<Uint8Array>((controller) => {
|
|
39
|
+
sourceStreamController = controller;
|
|
40
|
+
})
|
|
41
|
+
);
|
|
22
42
|
|
|
23
43
|
this._readable = new ReadableStream<T>({
|
|
24
44
|
async pull(controller) {
|
|
@@ -26,9 +46,9 @@ export class BufferedTransformStream<T> implements ReadableWritablePair<T, Uint8
|
|
|
26
46
|
const value = await transform(buffered);
|
|
27
47
|
controller.enqueue(value);
|
|
28
48
|
} catch (e) {
|
|
29
|
-
//
|
|
30
|
-
// If the `transform`
|
|
31
|
-
//
|
|
49
|
+
// Treat `BufferedReadableStreamEndedError` as a normal end.
|
|
50
|
+
// If the `transform` method doesn't have enough data to return a value,
|
|
51
|
+
// it should throw another error to indicate that.
|
|
32
52
|
if (e instanceof BufferedReadableStreamEndedError) {
|
|
33
53
|
controller.close();
|
|
34
54
|
return;
|
|
@@ -39,8 +59,8 @@ export class BufferedTransformStream<T> implements ReadableWritablePair<T, Uint8
|
|
|
39
59
|
cancel: (reason) => {
|
|
40
60
|
// Propagate cancel to the source stream
|
|
41
61
|
// So future writes will be rejected
|
|
42
|
-
buffered.cancel(reason);
|
|
43
|
-
}
|
|
62
|
+
return buffered.cancel(reason);
|
|
63
|
+
},
|
|
44
64
|
});
|
|
45
65
|
|
|
46
66
|
this._writable = new WritableStream({
|
package/src/buffered.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { PushReadableStream } from "./push-readable.js";
|
|
2
|
-
import
|
|
2
|
+
import {
|
|
3
|
+
type ReadableStream,
|
|
4
|
+
type ReadableStreamDefaultReader,
|
|
5
|
+
} from "./stream.js";
|
|
3
6
|
|
|
4
7
|
export class BufferedReadableStreamEndedError extends Error {
|
|
5
8
|
public constructor() {
|
|
6
|
-
super(
|
|
9
|
+
super("Stream ended");
|
|
7
10
|
|
|
8
11
|
// Fix Error's prototype chain when compiling to ES5
|
|
9
12
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
@@ -115,23 +118,17 @@ export class BufferedReadableStream {
|
|
|
115
118
|
*/
|
|
116
119
|
public release(): ReadableStream<Uint8Array> {
|
|
117
120
|
if (this.buffered) {
|
|
118
|
-
return new PushReadableStream<Uint8Array>(async controller => {
|
|
121
|
+
return new PushReadableStream<Uint8Array>(async (controller) => {
|
|
119
122
|
// Put the remaining data back to the stream
|
|
120
123
|
await controller.enqueue(this.buffered!);
|
|
121
124
|
|
|
122
125
|
// Manually pipe the stream
|
|
123
126
|
while (true) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
} else {
|
|
130
|
-
await controller.enqueue(value);
|
|
131
|
-
}
|
|
132
|
-
} catch (e) {
|
|
133
|
-
controller.error(e);
|
|
134
|
-
break;
|
|
127
|
+
const { done, value } = await this.reader.read();
|
|
128
|
+
if (done) {
|
|
129
|
+
return;
|
|
130
|
+
} else {
|
|
131
|
+
await controller.enqueue(value);
|
|
135
132
|
}
|
|
136
133
|
}
|
|
137
134
|
});
|
|
@@ -142,7 +139,7 @@ export class BufferedReadableStream {
|
|
|
142
139
|
}
|
|
143
140
|
}
|
|
144
141
|
|
|
145
|
-
public cancel(reason?:
|
|
142
|
+
public cancel(reason?: unknown) {
|
|
146
143
|
return this.reader.cancel(reason);
|
|
147
144
|
}
|
|
148
145
|
}
|
package/src/decode-utf8.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { decodeUtf8 } from
|
|
1
|
+
import { decodeUtf8 } from "@yume-chan/struct";
|
|
2
|
+
|
|
2
3
|
import { TransformStream } from "./stream.js";
|
|
3
4
|
|
|
4
|
-
export class DecodeUtf8Stream extends TransformStream<Uint8Array, string>{
|
|
5
|
+
export class DecodeUtf8Stream extends TransformStream<Uint8Array, string> {
|
|
5
6
|
public constructor() {
|
|
6
7
|
super({
|
|
7
8
|
transform(chunk, controller) {
|
package/src/duplex.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { PromiseResolver } from "@yume-chan/async";
|
|
2
|
-
import type
|
|
3
|
-
|
|
2
|
+
import { type ValueOrPromise } from "@yume-chan/struct";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
WritableStream,
|
|
6
|
+
type ReadableStream,
|
|
7
|
+
type ReadableStreamDefaultController,
|
|
8
|
+
type WritableStreamDefaultWriter,
|
|
9
|
+
} from "./stream.js";
|
|
4
10
|
import { WrapReadableStream } from "./wrap-readable.js";
|
|
5
11
|
|
|
6
12
|
export interface DuplexStreamFactoryOptions {
|
|
@@ -9,7 +15,7 @@ export interface DuplexStreamFactoryOptions {
|
|
|
9
15
|
* or `WritableStream` is ended (the user won't produce any more data),
|
|
10
16
|
* or `DuplexStreamFactory#close` is called.
|
|
11
17
|
*
|
|
12
|
-
* Usually you want to let the other peer know that the duplex stream should be
|
|
18
|
+
* Usually you want to let the other peer know that the duplex stream should be closed.
|
|
13
19
|
*
|
|
14
20
|
* `dispose` will automatically be called after `close` completes,
|
|
15
21
|
* but if you want to wait another peer for a close confirmation and call
|
|
@@ -40,10 +46,14 @@ export class DuplexStreamFactory<R, W> {
|
|
|
40
46
|
private writers: WritableStreamDefaultWriter<W>[] = [];
|
|
41
47
|
|
|
42
48
|
private _writableClosed = false;
|
|
43
|
-
public get writableClosed() {
|
|
49
|
+
public get writableClosed() {
|
|
50
|
+
return this._writableClosed;
|
|
51
|
+
}
|
|
44
52
|
|
|
45
53
|
private _closed = new PromiseResolver<void>();
|
|
46
|
-
public get closed() {
|
|
54
|
+
public get closed() {
|
|
55
|
+
return this._closed.promise;
|
|
56
|
+
}
|
|
47
57
|
|
|
48
58
|
private options: DuplexStreamFactoryOptions;
|
|
49
59
|
|
|
@@ -84,7 +94,9 @@ export class DuplexStreamFactory<R, W> {
|
|
|
84
94
|
await this.close();
|
|
85
95
|
},
|
|
86
96
|
close: async () => {
|
|
87
|
-
|
|
97
|
+
await writer.close().catch((e) => {
|
|
98
|
+
void e;
|
|
99
|
+
});
|
|
88
100
|
await this.close();
|
|
89
101
|
},
|
|
90
102
|
});
|
|
@@ -97,13 +109,15 @@ export class DuplexStreamFactory<R, W> {
|
|
|
97
109
|
this._writableClosed = true;
|
|
98
110
|
|
|
99
111
|
// Call `close` first, so it can still write data to `WritableStream`s.
|
|
100
|
-
if (await this.options.close?.() !== false) {
|
|
112
|
+
if ((await this.options.close?.()) !== false) {
|
|
101
113
|
// `close` can return `false` to disable automatic `dispose`.
|
|
102
114
|
await this.dispose();
|
|
103
115
|
}
|
|
104
116
|
|
|
105
117
|
for (const writer of this.writers) {
|
|
106
|
-
|
|
118
|
+
await writer.close().catch((e) => {
|
|
119
|
+
void e;
|
|
120
|
+
});
|
|
107
121
|
}
|
|
108
122
|
}
|
|
109
123
|
|
|
@@ -112,7 +126,11 @@ export class DuplexStreamFactory<R, W> {
|
|
|
112
126
|
this._closed.resolve();
|
|
113
127
|
|
|
114
128
|
for (const controller of this.readableControllers) {
|
|
115
|
-
try {
|
|
129
|
+
try {
|
|
130
|
+
controller.close();
|
|
131
|
+
} catch (e) {
|
|
132
|
+
void e;
|
|
133
|
+
}
|
|
116
134
|
}
|
|
117
135
|
|
|
118
136
|
await this.options.dispose?.();
|
package/src/pipe-from.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { WritableStream, type ReadableWritablePair } from "./stream.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* `pair.writable`, when pipe `pair.readable` to `writable`.
|
|
4
|
+
* Pipe `pair.readable` to `writable`, then returns `pair.writable`.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
6
|
+
* This is the opposite of `ReadableStream#pipeThrough()`.
|
|
8
7
|
*
|
|
9
8
|
* @param writable The `WritableStream` to write to.
|
|
10
9
|
* @param pair A `TransformStream` that converts chunks.
|
|
11
|
-
* @returns
|
|
10
|
+
* @returns `pair`'s `writable` stream.
|
|
12
11
|
*/
|
|
13
12
|
export function pipeFrom<W, T>(writable: WritableStream<W>, pair: ReadableWritablePair<W, T>) {
|
|
14
13
|
const writer = pair.writable.getWriter();
|