@yume-chan/stream-extra 2.1.0 → 2.6.1

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.
@@ -2,7 +2,24 @@ import type { AbortSignal, QueuingStrategy } from "./stream.js";
2
2
  import { ReadableStream } from "./stream.js";
3
3
  export interface PushReadableStreamController<T> {
4
4
  abortSignal: AbortSignal;
5
- enqueue(chunk: T): Promise<void>;
5
+ /**
6
+ * Enqueue `chunk` into the stream.
7
+ *
8
+ * - If the stream is already cancelled by consumer before calling `enqueue`,
9
+ * the call will return `false`.
10
+ * - If the stream is already closed or errored by producer before calling `enqueue`,
11
+ * the call will throw an error.
12
+ * - If the stream has enough buffer space, the call will return `true`.
13
+ *
14
+ * Otherwise it returns a `Promise`:
15
+ *
16
+ * - If the stream is cancelled by consumer, or closed or errored by producer,
17
+ * while the `Promise` is pending, the `Promise` will be resolved to `false`.
18
+ * - When the stream has enough buffer space, the `Promise` will be resolved to `true`.
19
+ *
20
+ * @param chunk The value to be enqueued
21
+ */
22
+ enqueue(chunk: T): Promise<boolean>;
6
23
  close(): void;
7
24
  error(e?: unknown): void;
8
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"push-readable.d.ts","sourceRoot":"","sources":["../src/push-readable.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAmB,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9D,MAAM,WAAW,4BAA4B,CAAC,CAAC;IAC3C,WAAW,EAAE,WAAW,CAAC;IAEzB,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjC,KAAK,IAAI,IAAI,CAAC;IAEd,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,MAAM,wBAAwB,CAAC,CAAC,IAAI,CACtC,UAAU,EAAE,4BAA4B,CAAC,CAAC,CAAC,KAC1C,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,CAChC,KAAK,EACC;IACI,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;CACvD,GACD;IACI,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,UAAU,CAAC;CAC3C,GACD;IACI,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC7B,KAAK,EAAE,OAAO,GAAG,UAAU,CAAC;CAC/B,KACN,IAAI,CAAC;AAEV,qBAAa,kBAAkB,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;IACxD;;;;;;OAMG;gBAEC,MAAM,EAAE,wBAAwB,CAAC,CAAC,CAAC,EACnC,QAAQ,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,EAC7B,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC;CA+PrC"}
1
+ {"version":3,"file":"push-readable.d.ts","sourceRoot":"","sources":["../src/push-readable.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACR,WAAW,EACX,eAAe,EAElB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAmB,cAAc,EAAE,MAAM,aAAa,CAAC;AAG9D,MAAM,WAAW,4BAA4B,CAAC,CAAC;IAC3C,WAAW,EAAE,WAAW,CAAC;IAEzB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpC,KAAK,IAAI,IAAI,CAAC;IAEd,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,MAAM,wBAAwB,CAAC,CAAC,IAAI,CACtC,UAAU,EAAE,4BAA4B,CAAC,CAAC,CAAC,KAC1C,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,CAChC,KAAK,EACC;IACI,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;CACvD,GACD;IACI,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,UAAU,CAAC;CAC3C,GACD;IACI,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC7B,KAAK,EAAE,OAAO,GAAG,UAAU,CAAC;CAC/B,KACN,IAAI,CAAC;AAEV,qBAAa,kBAAkB,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;IACxD;;;;;;OAMG;gBAEC,MAAM,EAAE,wBAAwB,CAAC,CAAC,CAAC,EACnC,QAAQ,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,EAC7B,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC;CAoQrC"}
@@ -1,5 +1,6 @@
1
- import { PromiseResolver } from "@yume-chan/async";
1
+ import { isPromiseLike, PromiseResolver } from "@yume-chan/async";
2
2
  import { AbortController, ReadableStream } from "./stream.js";
3
+ import { TaskQueue } from "./task-queue.js";
3
4
  export class PushReadableStream extends ReadableStream {
4
5
  /**
5
6
  * Create a new `PushReadableStream` from a source.
@@ -9,196 +10,194 @@ export class PushReadableStream extends ReadableStream {
9
10
  * @param strategy
10
11
  */
11
12
  constructor(source, strategy, logger) {
12
- let waterMarkLow;
13
+ let controller;
14
+ const tasks = new TaskQueue();
13
15
  let zeroHighWaterMarkAllowEnqueue = false;
16
+ // Resolves when consumer calls `reader.read`.
17
+ // Rejects when producer calls `controller.close` or `controller.error`,
18
+ // or consumer calls `reader.cancel`.
19
+ let waterMarkLow;
14
20
  const abortController = new AbortController();
21
+ // Whether either the consumer has called `stream.cancel()`,
22
+ // or the producer has called `controller.close` or `controller.error`.
23
+ let stopped = false;
24
+ const enqueue = (chunk) => {
25
+ logger?.({
26
+ source: "producer",
27
+ operation: "enqueue",
28
+ value: chunk,
29
+ phase: "start",
30
+ });
31
+ if (abortController.signal.aborted) {
32
+ // In original `ReadableStream`, calling `enqueue` or `close`
33
+ // on an cancelled stream will throw an error,
34
+ //
35
+ // But in `PushReadableStream`, `enqueue` is an async function,
36
+ // the producer can't just check `abortSignal.aborted`
37
+ // before calling `enqueue`, as it might change when waiting
38
+ // for the backpressure to be reduced.
39
+ //
40
+ // So IMO it's better to handle this for the producer
41
+ // by simply ignoring the `enqueue` call.
42
+ //
43
+ // Note that we check `abortSignal.aborted` instead of `stopped`,
44
+ // as it's not allowed for the producer to call `enqueue` after
45
+ // they called `close` or `error`.
46
+ //
47
+ // Obviously, the producer should listen to the `abortSignal` and
48
+ // stop producing, but most pushing data sources don't support that.
49
+ logger?.({
50
+ source: "producer",
51
+ operation: "enqueue",
52
+ value: chunk,
53
+ phase: "ignored",
54
+ });
55
+ return false;
56
+ }
57
+ if (controller.desiredSize === null) {
58
+ // `desiredSize` being `null` means the stream is in error state,
59
+ // `controller.enqueue` will throw an error for us.
60
+ controller.enqueue(chunk);
61
+ // istanbul ignore next
62
+ throw new Error("unreachable");
63
+ }
64
+ if (zeroHighWaterMarkAllowEnqueue) {
65
+ // When `highWaterMark` is set to `0`,
66
+ // `controller.desiredSize` will always be `0`,
67
+ // even if the consumer has called `reader.read()`.
68
+ // (in this case, each `reader.read()`/`pull`
69
+ // should allow one `enqueue` of any size)
70
+ //
71
+ // If the consumer has already called `reader.read()`,
72
+ // before the producer tries to `enqueue`,
73
+ // `controller.desiredSize` is `0` and normal `waterMarkLow` signal
74
+ // will never trigger,
75
+ // (because `ReadableStream` prevents reentrance of `pull`)
76
+ // The stream will stuck.
77
+ //
78
+ // So we need a special signal for this case.
79
+ zeroHighWaterMarkAllowEnqueue = false;
80
+ controller.enqueue(chunk);
81
+ logger?.({
82
+ source: "producer",
83
+ operation: "enqueue",
84
+ value: chunk,
85
+ phase: "complete",
86
+ });
87
+ return true;
88
+ }
89
+ if (controller.desiredSize <= 0) {
90
+ logger?.({
91
+ source: "producer",
92
+ operation: "enqueue",
93
+ value: chunk,
94
+ phase: "waiting",
95
+ });
96
+ waterMarkLow = new PromiseResolver();
97
+ return waterMarkLow.promise.then(() => {
98
+ controller.enqueue(chunk);
99
+ logger?.({
100
+ source: "producer",
101
+ operation: "enqueue",
102
+ value: chunk,
103
+ phase: "complete",
104
+ });
105
+ return true;
106
+ }, () => {
107
+ // Only ignore this in-flight `enqueue` call
108
+ // future calls will trigger `desiredSize === null` and throw
109
+ logger?.({
110
+ source: "producer",
111
+ operation: "enqueue",
112
+ value: chunk,
113
+ phase: "ignored",
114
+ });
115
+ return false;
116
+ });
117
+ }
118
+ controller.enqueue(chunk);
119
+ logger?.({
120
+ source: "producer",
121
+ operation: "enqueue",
122
+ value: chunk,
123
+ phase: "complete",
124
+ });
125
+ return true;
126
+ };
127
+ const close = (explicit) => {
128
+ logger?.({
129
+ source: "producer",
130
+ operation: "close",
131
+ explicit,
132
+ phase: "start",
133
+ });
134
+ // Allow calling `controller.close` on cancelled stream as `enqueue` does
135
+ // Ignore implicit close on any stopped state
136
+ // But don't allow calling `controller.close` multiple times
137
+ if (abortController.signal.aborted || (stopped && !explicit)) {
138
+ logger?.({
139
+ source: "producer",
140
+ operation: "close",
141
+ explicit,
142
+ phase: "ignored",
143
+ });
144
+ return;
145
+ }
146
+ // This will throw for us if the stream is not in `readable` state
147
+ controller.close();
148
+ stopped = true;
149
+ // Wake up pending `enqueue`
150
+ waterMarkLow?.reject();
151
+ logger?.({
152
+ source: "producer",
153
+ operation: "close",
154
+ explicit,
155
+ phase: "complete",
156
+ });
157
+ };
158
+ const error = (error, explicit) => {
159
+ logger?.({
160
+ source: "producer",
161
+ operation: "error",
162
+ explicit,
163
+ phase: "start",
164
+ });
165
+ stopped = true;
166
+ // `controller.error` won't throw on closed/errored/cancelled stream
167
+ // so don't need any checks
168
+ controller.error(error);
169
+ // Wake up pending `enqueue`
170
+ waterMarkLow?.reject();
171
+ logger?.({
172
+ source: "producer",
173
+ operation: "error",
174
+ explicit,
175
+ phase: "complete",
176
+ });
177
+ };
15
178
  super({
16
- start: (controller) => {
179
+ start: (controller_) => {
180
+ controller = controller_;
17
181
  const result = source({
18
182
  abortSignal: abortController.signal,
19
- enqueue: async (chunk) => {
20
- logger?.({
21
- source: "producer",
22
- operation: "enqueue",
23
- value: chunk,
24
- phase: "start",
25
- });
26
- if (abortController.signal.aborted) {
27
- // In original `ReadableStream`, calling `enqueue` or `close`
28
- // on an cancelled stream will throw an error,
29
- //
30
- // But in `PushReadableStream`, `enqueue` is an async function,
31
- // the producer can't just check `abortSignal.aborted`
32
- // before calling `enqueue`, as it might change when waiting
33
- // for the backpressure to be reduced.
34
- //
35
- // So IMO it's better to handle this for the producer
36
- // by simply ignoring the `enqueue` call.
37
- //
38
- // Note that we check `abortSignal.aborted` instead of `stopped`,
39
- // as it's not allowed for the producer to call `enqueue` after
40
- // they called `close` or `error`.
41
- //
42
- // Obviously, the producer should listen to the `abortSignal` and
43
- // stop producing, but most pushing data sources don't support that.
44
- logger?.({
45
- source: "producer",
46
- operation: "enqueue",
47
- value: chunk,
48
- phase: "ignored",
49
- });
50
- return;
51
- }
52
- if (controller.desiredSize === null) {
53
- // `desiredSize` being `null` means the stream is in error state,
54
- // `controller.enqueue` will throw an error for us.
55
- controller.enqueue(chunk);
56
- // istanbul ignore next
57
- return;
58
- }
59
- if (zeroHighWaterMarkAllowEnqueue) {
60
- // When `highWaterMark` is set to `0`,
61
- // `controller.desiredSize` will always be `0`,
62
- // even if the consumer has called `reader.read()`.
63
- // (in this case, each `reader.read()`/`pull`
64
- // should allow one `enqueue` of any size)
65
- //
66
- // If the consumer has already called `reader.read()`,
67
- // before the producer tries to `enqueue`,
68
- // `controller.desiredSize` is `0` and normal `waterMarkLow` signal
69
- // will never trigger,
70
- // (because `ReadableStream` prevents reentrance of `pull`)
71
- // The stream will stuck.
72
- //
73
- // So we need a special signal for this case.
74
- zeroHighWaterMarkAllowEnqueue = false;
75
- controller.enqueue(chunk);
76
- logger?.({
77
- source: "producer",
78
- operation: "enqueue",
79
- value: chunk,
80
- phase: "complete",
81
- });
82
- return;
83
- }
84
- if (controller.desiredSize <= 0) {
85
- logger?.({
86
- source: "producer",
87
- operation: "enqueue",
88
- value: chunk,
89
- phase: "waiting",
90
- });
91
- waterMarkLow = new PromiseResolver();
92
- await waterMarkLow.promise;
93
- // Recheck consumer cancellation after async operations.
94
- if (abortController.signal.aborted) {
95
- logger?.({
96
- source: "producer",
97
- operation: "enqueue",
98
- value: chunk,
99
- phase: "ignored",
100
- });
101
- return;
102
- }
103
- }
104
- controller.enqueue(chunk);
105
- logger?.({
106
- source: "producer",
107
- operation: "enqueue",
108
- value: chunk,
109
- phase: "complete",
110
- });
111
- },
183
+ enqueue: async (chunk) =>
184
+ // Run `enqueue`s in serial
185
+ // Use `async/await` to always return a `Promise`
186
+ await tasks.enqueue(() => enqueue(chunk)),
112
187
  close() {
113
- logger?.({
114
- source: "producer",
115
- operation: "close",
116
- explicit: true,
117
- phase: "start",
118
- });
119
- // Since `enqueue` on an cancelled stream won't throw an error,
120
- // so does `close`.
121
- if (abortController.signal.aborted) {
122
- logger?.({
123
- source: "producer",
124
- operation: "close",
125
- explicit: true,
126
- phase: "ignored",
127
- });
128
- return;
129
- }
130
- controller.close();
131
- logger?.({
132
- source: "producer",
133
- operation: "close",
134
- explicit: true,
135
- phase: "complete",
136
- });
188
+ close(true);
137
189
  },
138
190
  error(e) {
139
- logger?.({
140
- source: "producer",
141
- operation: "error",
142
- explicit: true,
143
- phase: "start",
144
- });
145
- // Calling `error` on an already closed or errored stream is a no-op.
146
- controller.error(e);
147
- logger?.({
148
- source: "producer",
149
- operation: "error",
150
- explicit: true,
151
- phase: "complete",
152
- });
191
+ error(e, true);
153
192
  },
154
193
  });
155
- if (result && "then" in result) {
194
+ if (!stopped && isPromiseLike(result)) {
156
195
  // If `source` returns a `Promise`,
157
196
  // close the stream when the `Promise` is resolved,
158
197
  // and error the stream when the `Promise` is rejected.
159
198
  // The producer can return a never-settling `Promise`
160
199
  // to disable this behavior.
161
- result.then(() => {
162
- logger?.({
163
- source: "producer",
164
- operation: "close",
165
- explicit: false,
166
- phase: "start",
167
- });
168
- try {
169
- controller.close();
170
- logger?.({
171
- source: "producer",
172
- operation: "close",
173
- explicit: false,
174
- phase: "complete",
175
- });
176
- }
177
- catch {
178
- logger?.({
179
- source: "producer",
180
- operation: "close",
181
- explicit: false,
182
- phase: "ignored",
183
- });
184
- // The stream is already closed by the producer,
185
- // Or cancelled by the consumer.
186
- }
187
- }, (e) => {
188
- logger?.({
189
- source: "producer",
190
- operation: "error",
191
- explicit: false,
192
- phase: "start",
193
- });
194
- controller.error(e);
195
- logger?.({
196
- source: "producer",
197
- operation: "error",
198
- explicit: false,
199
- phase: "complete",
200
- });
201
- });
200
+ result.then(() => close(false), (e) => error(e, false));
202
201
  }
203
202
  },
204
203
  pull: () => {
@@ -208,7 +207,8 @@ export class PushReadableStream extends ReadableStream {
208
207
  phase: "start",
209
208
  });
210
209
  if (waterMarkLow) {
211
- waterMarkLow.resolve();
210
+ waterMarkLow.resolve(undefined);
211
+ waterMarkLow = undefined;
212
212
  }
213
213
  else if (strategy?.highWaterMark === 0) {
214
214
  zeroHighWaterMarkAllowEnqueue = true;
@@ -225,9 +225,9 @@ export class PushReadableStream extends ReadableStream {
225
225
  operation: "cancel",
226
226
  phase: "start",
227
227
  });
228
+ stopped = true;
228
229
  abortController.abort(reason);
229
- // Resolve it on cancellation. `pull` will check `abortSignal.aborted` again.
230
- waterMarkLow?.resolve();
230
+ waterMarkLow?.reject();
231
231
  logger?.({
232
232
  source: "consumer",
233
233
  operation: "cancel",
@@ -1 +1 @@
1
- {"version":3,"file":"push-readable.js","sourceRoot":"","sources":["../src/push-readable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGnD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAqC9D,MAAM,OAAO,kBAAsB,SAAQ,cAAiB;IACxD;;;;;;OAMG;IACH,YACI,MAAmC,EACnC,QAA6B,EAC7B,MAA8B;QAE9B,IAAI,YAA+C,CAAC;QACpD,IAAI,6BAA6B,GAAG,KAAK,CAAC;QAC1C,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;QAE9C,KAAK,CACD;YACI,KAAK,EAAE,CAAC,UAAU,EAAE,EAAE;gBAClB,MAAM,MAAM,GAAG,MAAM,CAAC;oBAClB,WAAW,EAAE,eAAe,CAAC,MAAM;oBACnC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;wBACrB,MAAM,EAAE,CAAC;4BACL,MAAM,EAAE,UAAU;4BAClB,SAAS,EAAE,SAAS;4BACpB,KAAK,EAAE,KAAK;4BACZ,KAAK,EAAE,OAAO;yBACjB,CAAC,CAAC;wBAEH,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;4BACjC,6DAA6D;4BAC7D,8CAA8C;4BAC9C,EAAE;4BACF,+DAA+D;4BAC/D,sDAAsD;4BACtD,4DAA4D;4BAC5D,sCAAsC;4BACtC,EAAE;4BACF,qDAAqD;4BACrD,yCAAyC;4BACzC,EAAE;4BACF,iEAAiE;4BACjE,+DAA+D;4BAC/D,kCAAkC;4BAClC,EAAE;4BACF,iEAAiE;4BACjE,oEAAoE;4BACpE,MAAM,EAAE,CAAC;gCACL,MAAM,EAAE,UAAU;gCAClB,SAAS,EAAE,SAAS;gCACpB,KAAK,EAAE,KAAK;gCACZ,KAAK,EAAE,SAAS;6BACnB,CAAC,CAAC;4BACH,OAAO;wBACX,CAAC;wBAED,IAAI,UAAU,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;4BAClC,iEAAiE;4BACjE,mDAAmD;4BACnD,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;4BAC1B,uBAAuB;4BACvB,OAAO;wBACX,CAAC;wBAED,IAAI,6BAA6B,EAAE,CAAC;4BAChC,sCAAsC;4BACtC,+CAA+C;4BAC/C,mDAAmD;4BACnD,6CAA6C;4BAC7C,0CAA0C;4BAC1C,EAAE;4BACF,sDAAsD;4BACtD,0CAA0C;4BAC1C,mEAAmE;4BACnE,sBAAsB;4BACtB,2DAA2D;4BAC3D,yBAAyB;4BACzB,EAAE;4BACF,6CAA6C;4BAC7C,6BAA6B,GAAG,KAAK,CAAC;4BACtC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;4BAC1B,MAAM,EAAE,CAAC;gCACL,MAAM,EAAE,UAAU;gCAClB,SAAS,EAAE,SAAS;gCACpB,KAAK,EAAE,KAAK;gCACZ,KAAK,EAAE,UAAU;6BACpB,CAAC,CAAC;4BACH,OAAO;wBACX,CAAC;wBAED,IAAI,UAAU,CAAC,WAAW,IAAI,CAAC,EAAE,CAAC;4BAC9B,MAAM,EAAE,CAAC;gCACL,MAAM,EAAE,UAAU;gCAClB,SAAS,EAAE,SAAS;gCACpB,KAAK,EAAE,KAAK;gCACZ,KAAK,EAAE,SAAS;6BACnB,CAAC,CAAC;4BAEH,YAAY,GAAG,IAAI,eAAe,EAAQ,CAAC;4BAC3C,MAAM,YAAY,CAAC,OAAO,CAAC;4BAE3B,wDAAwD;4BACxD,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gCACjC,MAAM,EAAE,CAAC;oCACL,MAAM,EAAE,UAAU;oCAClB,SAAS,EAAE,SAAS;oCACpB,KAAK,EAAE,KAAK;oCACZ,KAAK,EAAE,SAAS;iCACnB,CAAC,CAAC;gCACH,OAAO;4BACX,CAAC;wBACL,CAAC;wBAED,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBAC1B,MAAM,EAAE,CAAC;4BACL,MAAM,EAAE,UAAU;4BAClB,SAAS,EAAE,SAAS;4BACpB,KAAK,EAAE,KAAK;4BACZ,KAAK,EAAE,UAAU;yBACpB,CAAC,CAAC;oBACP,CAAC;oBACD,KAAK;wBACD,MAAM,EAAE,CAAC;4BACL,MAAM,EAAE,UAAU;4BAClB,SAAS,EAAE,OAAO;4BAClB,QAAQ,EAAE,IAAI;4BACd,KAAK,EAAE,OAAO;yBACjB,CAAC,CAAC;wBAEH,+DAA+D;wBAC/D,mBAAmB;wBACnB,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;4BACjC,MAAM,EAAE,CAAC;gCACL,MAAM,EAAE,UAAU;gCAClB,SAAS,EAAE,OAAO;gCAClB,QAAQ,EAAE,IAAI;gCACd,KAAK,EAAE,SAAS;6BACnB,CAAC,CAAC;4BACH,OAAO;wBACX,CAAC;wBAED,UAAU,CAAC,KAAK,EAAE,CAAC;wBACnB,MAAM,EAAE,CAAC;4BACL,MAAM,EAAE,UAAU;4BAClB,SAAS,EAAE,OAAO;4BAClB,QAAQ,EAAE,IAAI;4BACd,KAAK,EAAE,UAAU;yBACpB,CAAC,CAAC;oBACP,CAAC;oBACD,KAAK,CAAC,CAAC;wBACH,MAAM,EAAE,CAAC;4BACL,MAAM,EAAE,UAAU;4BAClB,SAAS,EAAE,OAAO;4BAClB,QAAQ,EAAE,IAAI;4BACd,KAAK,EAAE,OAAO;yBACjB,CAAC,CAAC;wBAEH,qEAAqE;wBACrE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;wBAEpB,MAAM,EAAE,CAAC;4BACL,MAAM,EAAE,UAAU;4BAClB,SAAS,EAAE,OAAO;4BAClB,QAAQ,EAAE,IAAI;4BACd,KAAK,EAAE,UAAU;yBACpB,CAAC,CAAC;oBACP,CAAC;iBACJ,CAAC,CAAC;gBAEH,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;oBAC7B,mCAAmC;oBACnC,mDAAmD;oBACnD,uDAAuD;oBACvD,qDAAqD;oBACrD,4BAA4B;oBAC5B,MAAM,CAAC,IAAI,CACP,GAAG,EAAE;wBACD,MAAM,EAAE,CAAC;4BACL,MAAM,EAAE,UAAU;4BAClB,SAAS,EAAE,OAAO;4BAClB,QAAQ,EAAE,KAAK;4BACf,KAAK,EAAE,OAAO;yBACjB,CAAC,CAAC;wBAEH,IAAI,CAAC;4BACD,UAAU,CAAC,KAAK,EAAE,CAAC;4BAEnB,MAAM,EAAE,CAAC;gCACL,MAAM,EAAE,UAAU;gCAClB,SAAS,EAAE,OAAO;gCAClB,QAAQ,EAAE,KAAK;gCACf,KAAK,EAAE,UAAU;6BACpB,CAAC,CAAC;wBACP,CAAC;wBAAC,MAAM,CAAC;4BACL,MAAM,EAAE,CAAC;gCACL,MAAM,EAAE,UAAU;gCAClB,SAAS,EAAE,OAAO;gCAClB,QAAQ,EAAE,KAAK;gCACf,KAAK,EAAE,SAAS;6BACnB,CAAC,CAAC;4BAEH,gDAAgD;4BAChD,gCAAgC;wBACpC,CAAC;oBACL,CAAC,EACD,CAAC,CAAC,EAAE,EAAE;wBACF,MAAM,EAAE,CAAC;4BACL,MAAM,EAAE,UAAU;4BAClB,SAAS,EAAE,OAAO;4BAClB,QAAQ,EAAE,KAAK;4BACf,KAAK,EAAE,OAAO;yBACjB,CAAC,CAAC;wBAEH,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;wBAEpB,MAAM,EAAE,CAAC;4BACL,MAAM,EAAE,UAAU;4BAClB,SAAS,EAAE,OAAO;4BAClB,QAAQ,EAAE,KAAK;4BACf,KAAK,EAAE,UAAU;yBACpB,CAAC,CAAC;oBACP,CAAC,CACJ,CAAC;gBACN,CAAC;YACL,CAAC;YACD,IAAI,EAAE,GAAG,EAAE;gBACP,MAAM,EAAE,CAAC;oBACL,MAAM,EAAE,UAAU;oBAClB,SAAS,EAAE,MAAM;oBACjB,KAAK,EAAE,OAAO;iBACjB,CAAC,CAAC;gBAEH,IAAI,YAAY,EAAE,CAAC;oBACf,YAAY,CAAC,OAAO,EAAE,CAAC;gBAC3B,CAAC;qBAAM,IAAI,QAAQ,EAAE,aAAa,KAAK,CAAC,EAAE,CAAC;oBACvC,6BAA6B,GAAG,IAAI,CAAC;gBACzC,CAAC;gBAED,MAAM,EAAE,CAAC;oBACL,MAAM,EAAE,UAAU;oBAClB,SAAS,EAAE,MAAM;oBACjB,KAAK,EAAE,UAAU;iBACpB,CAAC,CAAC;YACP,CAAC;YACD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;gBACf,MAAM,EAAE,CAAC;oBACL,MAAM,EAAE,UAAU;oBAClB,SAAS,EAAE,QAAQ;oBACnB,KAAK,EAAE,OAAO;iBACjB,CAAC,CAAC;gBAEH,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC9B,6EAA6E;gBAC7E,YAAY,EAAE,OAAO,EAAE,CAAC;gBAExB,MAAM,EAAE,CAAC;oBACL,MAAM,EAAE,UAAU;oBAClB,SAAS,EAAE,QAAQ;oBACnB,KAAK,EAAE,UAAU;iBACpB,CAAC,CAAC;YACP,CAAC;SACJ,EACD,QAAQ,CACX,CAAC;IACN,CAAC;CACJ"}
1
+ {"version":3,"file":"push-readable.js","sourceRoot":"","sources":["../src/push-readable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { MaybePromise, MaybePromiseLike } from "@yume-chan/async";
2
+ export declare class TaskQueue {
3
+ #private;
4
+ enqueue<T extends MaybePromiseLike<unknown>>(task: () => T, bail?: boolean): T;
5
+ enqueue<T>(task: () => T, bail?: boolean): MaybePromise<T>;
6
+ dispose(): void;
7
+ }
8
+ //# sourceMappingURL=task-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-queue.d.ts","sourceRoot":"","sources":["../src/task-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGvE,qBAAa,SAAS;;IAIlB,OAAO,CAAC,CAAC,SAAS,gBAAgB,CAAC,OAAO,CAAC,EACvC,IAAI,EAAE,MAAM,CAAC,EACb,IAAI,CAAC,EAAE,OAAO,GACf,CAAC;IACJ,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC;IAsD1D,OAAO;CAGV"}
@@ -0,0 +1,50 @@
1
+ import { isPromiseLike } from "@yume-chan/async";
2
+ export class TaskQueue {
3
+ #ready;
4
+ #disposed = false;
5
+ enqueue(task, bail = false) {
6
+ if (this.#disposed) {
7
+ throw new Error("TaskQueue is disposed");
8
+ }
9
+ if (!this.#ready) {
10
+ // Init state or all previous tasks are synchronous
11
+ try {
12
+ const result = task();
13
+ if (isPromiseLike(result)) {
14
+ this.#ready = result.then(() => { }, (e) => {
15
+ if (bail) {
16
+ throw e;
17
+ }
18
+ });
19
+ }
20
+ return result;
21
+ }
22
+ catch (e) {
23
+ if (bail) {
24
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
25
+ const promise = Promise.reject(e);
26
+ // Suppress unhandled-rejection without resolving `#ready`
27
+ void promise.catch(() => { });
28
+ this.#ready = promise;
29
+ }
30
+ throw e;
31
+ }
32
+ }
33
+ const result = this.#ready.then(() => {
34
+ if (this.#disposed) {
35
+ throw new Error("TaskQueue is disposed");
36
+ }
37
+ return task();
38
+ });
39
+ this.#ready = result.then(() => { }, (e) => {
40
+ if (bail || this.#disposed) {
41
+ throw e;
42
+ }
43
+ });
44
+ return result;
45
+ }
46
+ dispose() {
47
+ this.#disposed = true;
48
+ }
49
+ }
50
+ //# sourceMappingURL=task-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-queue.js","sourceRoot":"","sources":["../src/task-queue.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,OAAO,SAAS;IAClB,MAAM,CAAmC;IACzC,SAAS,GAAG,KAAK,CAAC;IAOlB,OAAO,CACH,IAA+B,EAC/B,IAAI,GAAG,KAAK;QAEZ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACf,mDAAmD;YACnD,IAAI,CAAC;gBACD,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC;gBACtB,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;oBACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CACrB,GAAG,EAAE,GAAE,CAAC,EACR,CAAC,CAAC,EAAE,EAAE;wBACF,IAAI,IAAI,EAAE,CAAC;4BACP,MAAM,CAAC,CAAC;wBACZ,CAAC;oBACL,CAAC,CACJ,CAAC;gBACN,CAAC;gBACD,OAAO,MAAM,CAAC;YAClB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,IAAI,IAAI,EAAE,CAAC;oBACP,2EAA2E;oBAC3E,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;oBAClC,0DAA0D;oBAC1D,KAAK,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;oBAC7B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;gBAC1B,CAAC;gBACD,MAAM,CAAC,CAAC;YACZ,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;YACjC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YAC7C,CAAC;YAED,OAAO,IAAI,EAAE,CAAC;QAClB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CACrB,GAAG,EAAE,GAAE,CAAC,EACR,CAAC,CAAC,EAAE,EAAE;YACF,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACzB,MAAM,CAAC,CAAC;YACZ,CAAC;QACL,CAAC,CACJ,CAAC;QACF,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,OAAO;QACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IAC1B,CAAC;CACJ"}
@@ -1,9 +1,11 @@
1
1
  import type { BufferedReadableStream } from "./buffered.js";
2
- import type { PushReadableStreamController } from "./push-readable.js";
3
- import type { ReadableStream, ReadableStreamDefaultController, ReadableStreamDefaultReader, WritableStreamDefaultWriter } from "./stream.js";
4
- export declare function tryClose(controller: PushReadableStreamController<unknown>): boolean;
5
- export declare function tryClose(controller: ReadableStreamDefaultController<unknown>): boolean;
6
- export declare function tryClose(writer: WritableStreamDefaultWriter<never>): boolean;
2
+ import type { ReadableStream, ReadableStreamDefaultReader } from "./stream.js";
3
+ export declare function tryClose(value: {
4
+ close(): PromiseLike<void>;
5
+ }): Promise<boolean>;
6
+ export declare function tryClose(value: {
7
+ close(): void;
8
+ }): boolean;
7
9
  export declare function tryCancel(stream: ReadableStream<unknown>): Promise<boolean>;
8
10
  export declare function tryCancel(stream: BufferedReadableStream): Promise<boolean>;
9
11
  export declare function tryCancel(reader: ReadableStreamDefaultReader<unknown>): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"try-close.d.ts","sourceRoot":"","sources":["../src/try-close.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,KAAK,EACR,cAAc,EACd,+BAA+B,EAC/B,2BAA2B,EAC3B,2BAA2B,EAC9B,MAAM,aAAa,CAAC;AAErB,wBAAgB,QAAQ,CACpB,UAAU,EAAE,4BAA4B,CAAC,OAAO,CAAC,GAClD,OAAO,CAAC;AACX,wBAAgB,QAAQ,CACpB,UAAU,EAAE,+BAA+B,CAAC,OAAO,CAAC,GACrD,OAAO,CAAC;AACX,wBAAgB,QAAQ,CAAC,MAAM,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;AAU9E,wBAAsB,SAAS,CAC3B,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,GAChC,OAAO,CAAC,OAAO,CAAC,CAAC;AACpB,wBAAsB,SAAS,CAC3B,MAAM,EAAE,sBAAsB,GAC/B,OAAO,CAAC,OAAO,CAAC,CAAC;AACpB,wBAAsB,SAAS,CAC3B,MAAM,EAAE,2BAA2B,CAAC,OAAO,CAAC,GAC7C,OAAO,CAAC,OAAO,CAAC,CAAC"}
1
+ {"version":3,"file":"try-close.d.ts","sourceRoot":"","sources":["../src/try-close.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAE/E,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAC5B,KAAK,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;CAC9B,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AACrB,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAAE,KAAK,IAAI,IAAI,CAAA;CAAE,GAAG,OAAO,CAAC;AAgB5D,wBAAsB,SAAS,CAC3B,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,GAChC,OAAO,CAAC,OAAO,CAAC,CAAC;AACpB,wBAAsB,SAAS,CAC3B,MAAM,EAAE,sBAAsB,GAC/B,OAAO,CAAC,OAAO,CAAC,CAAC;AACpB,wBAAsB,SAAS,CAC3B,MAAM,EAAE,2BAA2B,CAAC,OAAO,CAAC,GAC7C,OAAO,CAAC,OAAO,CAAC,CAAC"}
package/esm/try-close.js CHANGED
@@ -1,6 +1,10 @@
1
- export function tryClose(controller) {
1
+ import { isPromiseLike } from "@yume-chan/async";
2
+ export function tryClose(value) {
2
3
  try {
3
- controller.close();
4
+ const result = value.close();
5
+ if (isPromiseLike(result)) {
6
+ return result.then(() => true, () => false);
7
+ }
4
8
  return true;
5
9
  }
6
10
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"try-close.js","sourceRoot":"","sources":["../src/try-close.ts"],"names":[],"mappings":"AAgBA,MAAM,UAAU,QAAQ,CAAC,UAA6B;IAClD,IAAI,CAAC;QACD,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC;AAWD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAE/B;IACG,IAAI,CAAC;QACD,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"try-close.js","sourceRoot":"","sources":["../src/try-close.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AASjD,MAAM,UAAU,QAAQ,CAAC,KAA0C;IAC/D,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,OAAO,MAAM,CAAC,IAAI,CACd,GAAG,EAAE,CAAC,IAAI,EACV,GAAG,EAAE,CAAC,KAAK,CACd,CAAC;QACN,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC;AAWD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAE/B;IACG,IAAI,CAAC;QACD,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yume-chan/stream-extra",
3
- "version": "2.1.0",
3
+ "version": "2.6.1",
4
4
  "description": "Extensions to Web Streams API",
5
5
  "keywords": [
6
6
  "stream",
@@ -27,15 +27,15 @@
27
27
  "sideEffects": false,
28
28
  "dependencies": {
29
29
  "@yume-chan/async": "^4.1.3",
30
- "@yume-chan/struct": "^2.0.1"
30
+ "@yume-chan/struct": "^2.3.2"
31
31
  },
32
32
  "devDependencies": {
33
- "@types/node": "^24.0.1",
34
- "prettier": "^3.5.3",
35
- "typescript": "^5.8.3",
33
+ "@types/node": "^24.3.1",
34
+ "prettier": "^3.6.2",
35
+ "typescript": "^5.9.2",
36
36
  "@yume-chan/eslint-config": "^1.0.0",
37
- "@yume-chan/test-runner": "^1.0.0",
38
- "@yume-chan/tsconfig": "^1.0.0"
37
+ "@yume-chan/tsconfig": "^1.0.0",
38
+ "@yume-chan/test-runner": "^1.0.0"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsc -b tsconfig.build.json",