@yume-chan/stream-extra 2.5.3 → 3.0.0-beta.0

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.
Files changed (167) hide show
  1. package/LICENSE +1 -1
  2. package/esm/buffered-transform.d.ts +2 -2
  3. package/esm/buffered-transform.d.ts.map +1 -1
  4. package/esm/buffered-transform.js +1 -1
  5. package/esm/buffered-transform.js.map +1 -1
  6. package/esm/buffered.d.ts +1 -1
  7. package/esm/buffered.d.ts.map +1 -1
  8. package/esm/buffered.js.map +1 -1
  9. package/esm/concat.d.ts +25 -16
  10. package/esm/concat.d.ts.map +1 -1
  11. package/esm/concat.js +124 -93
  12. package/esm/concat.js.map +1 -1
  13. package/esm/consumable/readable.d.ts +2 -2
  14. package/esm/consumable/readable.d.ts.map +1 -1
  15. package/esm/consumable/readable.js +1 -1
  16. package/esm/consumable/readable.js.map +1 -1
  17. package/esm/consumable/wrap-byte-readable.d.ts +5 -2
  18. package/esm/consumable/wrap-byte-readable.d.ts.map +1 -1
  19. package/esm/consumable/wrap-byte-readable.js +12 -6
  20. package/esm/consumable/wrap-byte-readable.js.map +1 -1
  21. package/esm/consumable/wrap-writable.d.ts +1 -1
  22. package/esm/consumable/wrap-writable.d.ts.map +1 -1
  23. package/esm/consumable/wrap-writable.js +1 -1
  24. package/esm/consumable/wrap-writable.js.map +1 -1
  25. package/esm/consumable/writable.d.ts +2 -2
  26. package/esm/consumable/writable.d.ts.map +1 -1
  27. package/esm/consumable/writable.js +1 -1
  28. package/esm/consumable/writable.js.map +1 -1
  29. package/esm/consumable.d.ts +4 -0
  30. package/esm/consumable.d.ts.map +1 -1
  31. package/esm/consumable.js +5 -0
  32. package/esm/consumable.js.map +1 -1
  33. package/esm/distribution.d.ts +1 -1
  34. package/esm/distribution.d.ts.map +1 -1
  35. package/esm/distribution.js +1 -1
  36. package/esm/distribution.js.map +1 -1
  37. package/esm/duplex.d.ts +2 -2
  38. package/esm/duplex.d.ts.map +1 -1
  39. package/esm/duplex.js +1 -1
  40. package/esm/duplex.js.map +1 -1
  41. package/esm/global/abort-signal.d.ts +87 -0
  42. package/esm/global/abort-signal.d.ts.map +1 -0
  43. package/esm/global/abort-signal.js +4 -0
  44. package/esm/global/abort-signal.js.map +1 -0
  45. package/esm/global/compression.d.ts +15 -0
  46. package/esm/global/compression.d.ts.map +1 -0
  47. package/esm/global/compression.js +4 -0
  48. package/esm/global/compression.js.map +1 -0
  49. package/esm/global/encoding.d.ts +25 -0
  50. package/esm/global/encoding.d.ts.map +1 -0
  51. package/esm/global/encoding.js +4 -0
  52. package/esm/global/encoding.js.map +1 -0
  53. package/esm/global/event.d.ts +191 -0
  54. package/esm/global/event.d.ts.map +1 -0
  55. package/esm/global/event.js +4 -0
  56. package/esm/global/event.js.map +1 -0
  57. package/esm/global/index.d.ts +7 -0
  58. package/esm/global/index.d.ts.map +1 -0
  59. package/esm/global/index.js +7 -0
  60. package/esm/global/index.js.map +1 -0
  61. package/esm/{types.d.ts → global/streams.d.ts} +136 -222
  62. package/esm/global/streams.d.ts.map +1 -0
  63. package/esm/{stream.js → global/streams.js} +16 -8
  64. package/esm/global/streams.js.map +1 -0
  65. package/esm/global/timer.d.ts +13 -0
  66. package/esm/global/timer.d.ts.map +1 -0
  67. package/esm/global/timer.js +4 -0
  68. package/esm/global/timer.js.map +1 -0
  69. package/esm/global/utils.d.ts +9 -0
  70. package/esm/global/utils.d.ts.map +1 -0
  71. package/esm/global/utils.js +5 -0
  72. package/esm/global/utils.js.map +1 -0
  73. package/esm/index.d.ts +2 -2
  74. package/esm/index.d.ts.map +1 -1
  75. package/esm/index.js +2 -2
  76. package/esm/index.js.map +1 -1
  77. package/esm/inspect.d.ts +6 -2
  78. package/esm/inspect.d.ts.map +1 -1
  79. package/esm/inspect.js +10 -4
  80. package/esm/inspect.js.map +1 -1
  81. package/esm/maybe-consumable/wrap-writable.d.ts +1 -1
  82. package/esm/maybe-consumable/wrap-writable.d.ts.map +1 -1
  83. package/esm/maybe-consumable/wrap-writable.js +1 -1
  84. package/esm/maybe-consumable/wrap-writable.js.map +1 -1
  85. package/esm/maybe-consumable/writable.d.ts +2 -2
  86. package/esm/maybe-consumable/writable.d.ts.map +1 -1
  87. package/esm/maybe-consumable/writable.js +1 -1
  88. package/esm/maybe-consumable/writable.js.map +1 -1
  89. package/esm/pipe-from.d.ts +3 -3
  90. package/esm/pipe-from.d.ts.map +1 -1
  91. package/esm/pipe-from.js +1 -1
  92. package/esm/pipe-from.js.map +1 -1
  93. package/esm/push-readable.d.ts +20 -3
  94. package/esm/push-readable.d.ts.map +1 -1
  95. package/esm/push-readable.js +180 -180
  96. package/esm/push-readable.js.map +1 -1
  97. package/esm/split-string.d.ts +6 -2
  98. package/esm/split-string.d.ts.map +1 -1
  99. package/esm/split-string.js +28 -7
  100. package/esm/split-string.js.map +1 -1
  101. package/esm/struct-deserialize.js.map +1 -1
  102. package/esm/struct-serialize.d.ts +1 -1
  103. package/esm/struct-serialize.d.ts.map +1 -1
  104. package/esm/struct-serialize.js +1 -1
  105. package/esm/struct-serialize.js.map +1 -1
  106. package/esm/task-queue.d.ts +8 -0
  107. package/esm/task-queue.d.ts.map +1 -0
  108. package/esm/task-queue.js +50 -0
  109. package/esm/task-queue.js.map +1 -0
  110. package/esm/try-close.d.ts +3 -5
  111. package/esm/try-close.d.ts.map +1 -1
  112. package/esm/try-close.js.map +1 -1
  113. package/esm/wrap-readable.d.ts +2 -2
  114. package/esm/wrap-readable.d.ts.map +1 -1
  115. package/esm/wrap-readable.js +1 -1
  116. package/esm/wrap-readable.js.map +1 -1
  117. package/esm/wrap-writable.d.ts +2 -2
  118. package/esm/wrap-writable.d.ts.map +1 -1
  119. package/esm/wrap-writable.js +1 -1
  120. package/esm/wrap-writable.js.map +1 -1
  121. package/package.json +8 -8
  122. package/src/buffered-transform.ts +8 -7
  123. package/src/buffered.ts +4 -1
  124. package/src/concat.ts +161 -118
  125. package/src/consumable/readable.ts +2 -2
  126. package/src/consumable/wrap-byte-readable.ts +20 -7
  127. package/src/consumable/wrap-writable.ts +1 -1
  128. package/src/consumable/writable.ts +2 -2
  129. package/src/consumable.ts +8 -0
  130. package/src/distribution.ts +1 -1
  131. package/src/duplex.ts +2 -2
  132. package/src/global/abort-signal.ts +129 -0
  133. package/src/global/compression.ts +28 -0
  134. package/src/global/encoding.ts +36 -0
  135. package/src/global/event.ts +221 -0
  136. package/src/global/index.ts +6 -0
  137. package/src/{types.ts → global/streams.ts} +266 -244
  138. package/src/global/timer.ts +18 -0
  139. package/src/global/utils.ts +14 -0
  140. package/src/index.ts +2 -2
  141. package/src/inspect.ts +18 -4
  142. package/src/maybe-consumable/wrap-writable.ts +1 -1
  143. package/src/maybe-consumable/writable.ts +3 -3
  144. package/src/pipe-from.ts +2 -2
  145. package/src/push-readable.ts +226 -198
  146. package/src/split-string.ts +41 -7
  147. package/src/struct-deserialize.ts +1 -1
  148. package/src/struct-serialize.ts +1 -1
  149. package/src/task-queue.ts +69 -0
  150. package/src/try-close.ts +0 -12
  151. package/src/wrap-readable.ts +2 -2
  152. package/src/wrap-writable.ts +5 -2
  153. package/tsconfig.build.json +1 -6
  154. package/CHANGELOG.md +0 -102
  155. package/esm/encoding.d.ts +0 -21
  156. package/esm/encoding.d.ts.map +0 -1
  157. package/esm/encoding.js +0 -4
  158. package/esm/encoding.js.map +0 -1
  159. package/esm/stream.d.ts +0 -25
  160. package/esm/stream.d.ts.map +0 -1
  161. package/esm/stream.js.map +0 -1
  162. package/esm/types.d.ts.map +0 -1
  163. package/esm/types.js +0 -3
  164. package/esm/types.js.map +0 -1
  165. package/src/encoding.ts +0 -39
  166. package/src/stream.ts +0 -106
  167. package/tsconfig.build.tsbuildinfo +0 -1
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"try-close.js","sourceRoot":"","sources":["../src/try-close.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAMjD,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;AAED,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,6 +1,6 @@
1
1
  import type { MaybePromiseLike } from "@yume-chan/async";
2
- import type { QueuingStrategy, ReadableStreamDefaultController } from "./stream.js";
3
- import { ReadableStream } from "./stream.js";
2
+ import type { QueuingStrategy, ReadableStreamDefaultController } from "./global/index.js";
3
+ import { ReadableStream } from "./global/index.js";
4
4
  export type WrapReadableStreamStart<T> = (controller: ReadableStreamDefaultController<T>) => MaybePromiseLike<ReadableStream<T>>;
5
5
  export interface ReadableStreamWrapper<T> {
6
6
  start: WrapReadableStreamStart<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-readable.d.ts","sourceRoot":"","sources":["../src/wrap-readable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EACR,eAAe,EACf,+BAA+B,EAElC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,CACrC,UAAU,EAAE,+BAA+B,CAAC,CAAC,CAAC,KAC7C,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzC,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACpC,KAAK,EAAE,uBAAuB,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACtD,KAAK,CAAC,EAAE,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,gBAAgB,CAAC,IAAI,CAAC,CAAC;CACxD;AAoBD;;;;;;GAMG;AACH,qBAAa,kBAAkB,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;;IACxD,QAAQ,EAAG,cAAc,CAAC,CAAC,CAAC,CAAC;gBAKzB,OAAO,EACD,cAAc,CAAC,CAAC,CAAC,GACjB,uBAAuB,CAAC,CAAC,CAAC,GAC1B,qBAAqB,CAAC,CAAC,CAAC,EAC9B,QAAQ,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;CA2CpC"}
1
+ {"version":3,"file":"wrap-readable.d.ts","sourceRoot":"","sources":["../src/wrap-readable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EACR,eAAe,EACf,+BAA+B,EAElC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,CACrC,UAAU,EAAE,+BAA+B,CAAC,CAAC,CAAC,KAC7C,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzC,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACpC,KAAK,EAAE,uBAAuB,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACtD,KAAK,CAAC,EAAE,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,gBAAgB,CAAC,IAAI,CAAC,CAAC;CACxD;AAoBD;;;;;;GAMG;AACH,qBAAa,kBAAkB,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;;IACxD,QAAQ,EAAG,cAAc,CAAC,CAAC,CAAC,CAAC;gBAKzB,OAAO,EACD,cAAc,CAAC,CAAC,CAAC,GACjB,uBAAuB,CAAC,CAAC,CAAC,GAC1B,qBAAqB,CAAC,CAAC,CAAC,EAC9B,QAAQ,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;CA2CpC"}
@@ -1,4 +1,4 @@
1
- import { ReadableStream } from "./stream.js";
1
+ import { ReadableStream } from "./global/index.js";
2
2
  function getWrappedReadableStream(wrapper, controller) {
3
3
  if ("start" in wrapper) {
4
4
  return wrapper.start(controller);
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-readable.js","sourceRoot":"","sources":["../src/wrap-readable.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAa7C,SAAS,wBAAwB,CAC7B,OAG8B,EAC9B,UAA8C;IAE9C,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;QACrB,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC;SAAM,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;QACvC,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACJ,gDAAgD;QAChD,wEAAwE;QACxE,OAAO,OAAO,CAAC;IACnB,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,kBAAsB,SAAQ,cAAiB;IACxD,QAAQ,CAAqB;IAE7B,OAAO,CAAkC;IAEzC,YACI,OAG8B,EAC9B,QAA6B;QAE7B,KAAK,CACD;YACI,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;gBACxB,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAC3C,OAAO,EACP,UAAU,CACb,CAAC;gBACF,qEAAqE;gBACrE,wCAAwC;gBACxC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;gBACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;YAC7C,CAAC;YACD,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;gBACvB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO;qBACrC,IAAI,EAAE;qBACN,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;oBACT,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;wBACrB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBACrB,CAAC;oBACD,MAAM,CAAC,CAAC;gBACZ,CAAC,CAAC,CAAC;gBAEP,IAAI,IAAI,EAAE,CAAC;oBACP,UAAU,CAAC,KAAK,EAAE,CAAC;oBACnB,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;wBACrB,MAAM,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;oBAC5B,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC9B,CAAC;YACL,CAAC;YACD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBACrB,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAClC,IAAI,QAAQ,IAAI,OAAO,EAAE,CAAC;oBACtB,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;gBACnC,CAAC;YACL,CAAC;SACJ,EACD,QAAQ,CACX,CAAC;IACN,CAAC;CACJ"}
1
+ {"version":3,"file":"wrap-readable.js","sourceRoot":"","sources":["../src/wrap-readable.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAanD,SAAS,wBAAwB,CAC7B,OAG8B,EAC9B,UAA8C;IAE9C,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;QACrB,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC;SAAM,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;QACvC,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACJ,gDAAgD;QAChD,wEAAwE;QACxE,OAAO,OAAO,CAAC;IACnB,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,kBAAsB,SAAQ,cAAiB;IACxD,QAAQ,CAAqB;IAE7B,OAAO,CAAkC;IAEzC,YACI,OAG8B,EAC9B,QAA6B;QAE7B,KAAK,CACD;YACI,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;gBACxB,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAC3C,OAAO,EACP,UAAU,CACb,CAAC;gBACF,qEAAqE;gBACrE,wCAAwC;gBACxC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;gBACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;YAC7C,CAAC;YACD,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;gBACvB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO;qBACrC,IAAI,EAAE;qBACN,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;oBACT,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;wBACrB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBACrB,CAAC;oBACD,MAAM,CAAC,CAAC;gBACZ,CAAC,CAAC,CAAC;gBAEP,IAAI,IAAI,EAAE,CAAC;oBACP,UAAU,CAAC,KAAK,EAAE,CAAC;oBACnB,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;wBACrB,MAAM,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;oBAC5B,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC9B,CAAC;YACL,CAAC;YACD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBACrB,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAClC,IAAI,QAAQ,IAAI,OAAO,EAAE,CAAC;oBACtB,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;gBACnC,CAAC;YACL,CAAC;SACJ,EACD,QAAQ,CACX,CAAC;IACN,CAAC;CACJ"}
@@ -1,6 +1,6 @@
1
1
  import type { MaybePromiseLike } from "@yume-chan/async";
2
- import type { TransformStream } from "./stream.js";
3
- import { WritableStream } from "./stream.js";
2
+ import type { TransformStream } from "./global/index.js";
3
+ import { WritableStream } from "./global/index.js";
4
4
  export type WrapWritableStreamStart<T> = () => MaybePromiseLike<WritableStream<T>>;
5
5
  export interface WritableStreamWrapper<T> {
6
6
  start: WrapWritableStreamStart<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-writable.d.ts","sourceRoot":"","sources":["../src/wrap-writable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EAAE,eAAe,EAA+B,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,MAAM,gBAAgB,CAC3D,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;;IACxD,QAAQ,EAAG,cAAc,CAAC,CAAC,CAAC,CAAC;gBAKzB,KAAK,EACC,cAAc,CAAC,CAAC,CAAC,GACjB,uBAAuB,CAAC,CAAC,CAAC,GAC1B,qBAAqB,CAAC,CAAC,CAAC;IAgClC,kBAAkB,CAAC,CAAC,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC;CAY3D"}
1
+ {"version":3,"file":"wrap-writable.d.ts","sourceRoot":"","sources":["../src/wrap-writable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EACR,eAAe,EAElB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,MAAM,gBAAgB,CAC3D,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;;IACxD,QAAQ,EAAG,cAAc,CAAC,CAAC,CAAC,CAAC;gBAKzB,KAAK,EACC,cAAc,CAAC,CAAC,CAAC,GACjB,uBAAuB,CAAC,CAAC,CAAC,GAC1B,qBAAqB,CAAC,CAAC,CAAC;IAgClC,kBAAkB,CAAC,CAAC,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC;CAY3D"}
@@ -1,4 +1,4 @@
1
- import { WritableStream } from "./stream.js";
1
+ import { WritableStream } from "./global/index.js";
2
2
  async function getWrappedWritableStream(start) {
3
3
  if ("start" in start) {
4
4
  return await start.start();
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-writable.js","sourceRoot":"","sources":["../src/wrap-writable.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAW7C,KAAK,UAAU,wBAAwB,CACnC,KAG8B;IAE9B,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;QACnB,OAAO,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QACrC,OAAO,MAAM,KAAK,EAAE,CAAC;IACzB,CAAC;SAAM,CAAC;QACJ,gDAAgD;QAChD,wEAAwE;QACxE,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC;AAED,MAAM,OAAO,kBAAsB,SAAQ,cAAiB;IACxD,QAAQ,CAAqB;IAE7B,OAAO,CAAkC;IAEzC,YACI,KAG8B;QAE9B,KAAK,CAAC;YACF,KAAK,EAAE,KAAK,IAAI,EAAE;gBACd,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,KAAK,CAAC,CAAC;gBACvD,qEAAqE;gBACrE,wCAAwC;gBACxC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;gBACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;YAC7C,CAAC;YACD,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACnB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;YACD,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBACpB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,KAAK,KAAK,IAAI,CAAC,QAAQ,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;oBAC9C,MAAM,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;gBAC1B,CAAC;YACL,CAAC;YACD,KAAK,EAAE,KAAK,IAAI,EAAE;gBACd,gCAAgC;gBAChC,0EAA0E;gBAC1E,yEAAyE;gBACzE,uCAAuC;gBACvC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC3B,IAAI,KAAK,KAAK,IAAI,CAAC,QAAQ,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;oBAC9C,MAAM,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;gBAC1B,CAAC;YACL,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAED,kBAAkB,CAAI,WAAkC;QACpD,IAAI,OAAsB,CAAC;QAC3B,OAAO,IAAI,kBAAkB,CAAI;YAC7B,KAAK,EAAE,GAAG,EAAE;gBACR,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC5C,OAAO,WAAW,CAAC,QAAQ,CAAC;YAChC,CAAC;YACD,KAAK,CAAC,KAAK;gBACP,MAAM,OAAO,CAAC;YAClB,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;CACJ"}
1
+ {"version":3,"file":"wrap-writable.js","sourceRoot":"","sources":["../src/wrap-writable.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAWnD,KAAK,UAAU,wBAAwB,CACnC,KAG8B;IAE9B,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;QACnB,OAAO,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QACrC,OAAO,MAAM,KAAK,EAAE,CAAC;IACzB,CAAC;SAAM,CAAC;QACJ,gDAAgD;QAChD,wEAAwE;QACxE,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC;AAED,MAAM,OAAO,kBAAsB,SAAQ,cAAiB;IACxD,QAAQ,CAAqB;IAE7B,OAAO,CAAkC;IAEzC,YACI,KAG8B;QAE9B,KAAK,CAAC;YACF,KAAK,EAAE,KAAK,IAAI,EAAE;gBACd,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,KAAK,CAAC,CAAC;gBACvD,qEAAqE;gBACrE,wCAAwC;gBACxC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;gBACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;YAC7C,CAAC;YACD,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACnB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;YACD,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBACpB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,KAAK,KAAK,IAAI,CAAC,QAAQ,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;oBAC9C,MAAM,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;gBAC1B,CAAC;YACL,CAAC;YACD,KAAK,EAAE,KAAK,IAAI,EAAE;gBACd,gCAAgC;gBAChC,0EAA0E;gBAC1E,yEAAyE;gBACzE,uCAAuC;gBACvC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC3B,IAAI,KAAK,KAAK,IAAI,CAAC,QAAQ,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;oBAC9C,MAAM,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;gBAC1B,CAAC;YACL,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAED,kBAAkB,CAAI,WAAkC;QACpD,IAAI,OAAsB,CAAC;QAC3B,OAAO,IAAI,kBAAkB,CAAI;YAC7B,KAAK,EAAE,GAAG,EAAE;gBACR,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC5C,OAAO,WAAW,CAAC,QAAQ,CAAC;YAChC,CAAC;YACD,KAAK,CAAC,KAAK;gBACP,MAAM,OAAO,CAAC;YAClB,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": "2.5.3",
3
+ "version": "3.0.0-beta.0",
4
4
  "description": "Extensions to Web Streams API",
5
5
  "keywords": [
6
6
  "stream",
@@ -12,11 +12,11 @@
12
12
  "email": "cnsimonchan@live.com",
13
13
  "url": "https://chensi.moe/blog"
14
14
  },
15
- "homepage": "https://github.com/yume-chan/ya-webadb/tree/main/packages/stream-extra#readme",
15
+ "homepage": "https://github.com/yume-chan/ya-webadb/tree/main/libraries/stream-extra#readme",
16
16
  "repository": {
17
17
  "type": "git",
18
18
  "url": "git+https://github.com/yume-chan/ya-webadb.git",
19
- "directory": "packages/stream-extra"
19
+ "directory": "libraries/stream-extra"
20
20
  },
21
21
  "bugs": {
22
22
  "url": "https://github.com/yume-chan/ya-webadb/issues"
@@ -27,18 +27,18 @@
27
27
  "sideEffects": false,
28
28
  "dependencies": {
29
29
  "@yume-chan/async": "^4.1.3",
30
- "@yume-chan/struct": "^2.3.2"
30
+ "@yume-chan/struct": "3.0.0-beta.0"
31
31
  },
32
32
  "devDependencies": {
33
- "@types/node": "^24.3.1",
34
- "prettier": "^3.6.2",
35
- "typescript": "^5.9.2",
33
+ "@types/node": "^26.0.0",
34
+ "prettier": "^3.8.4",
35
+ "typescript": "^6.0.3",
36
36
  "@yume-chan/eslint-config": "^1.0.0",
37
37
  "@yume-chan/test-runner": "^1.0.0",
38
38
  "@yume-chan/tsconfig": "^1.0.0"
39
39
  },
40
40
  "scripts": {
41
- "build": "tsc -b tsconfig.build.json",
41
+ "build": "tsc -p tsconfig.build.json",
42
42
  "lint": "run-eslint && prettier src/**/*.ts --write --tab-width 4",
43
43
  "test": "run-test"
44
44
  }
@@ -2,18 +2,19 @@ import type { MaybePromiseLike } from "@yume-chan/async";
2
2
  import { StructEmptyError } from "@yume-chan/struct";
3
3
 
4
4
  import { BufferedReadableStream } from "./buffered.js";
5
- import type { PushReadableStreamController } from "./push-readable.js";
6
- import { PushReadableStream } from "./push-readable.js";
7
5
  import type {
8
6
  ReadableWritablePair,
9
7
  WritableStreamDefaultController,
10
- } from "./stream.js";
11
- import { ReadableStream, WritableStream } from "./stream.js";
8
+ } from "./global/index.js";
9
+ import { ReadableStream, WritableStream } from "./global/index.js";
10
+ import type { PushReadableStreamController } from "./push-readable.js";
11
+ import { PushReadableStream } from "./push-readable.js";
12
12
 
13
13
  // TODO: BufferedTransformStream: find better implementation
14
- export class BufferedTransformStream<T>
15
- implements ReadableWritablePair<T, Uint8Array>
16
- {
14
+ export class BufferedTransformStream<T> implements ReadableWritablePair<
15
+ T,
16
+ Uint8Array
17
+ > {
17
18
  #readable: ReadableStream<T>;
18
19
  get readable() {
19
20
  return this.#readable;
package/src/buffered.ts CHANGED
@@ -2,8 +2,11 @@ import type { MaybePromiseLike } from "@yume-chan/async";
2
2
  import type { AsyncExactReadable } from "@yume-chan/struct";
3
3
  import { bipedal, ExactReadableEndedError } from "@yume-chan/struct";
4
4
 
5
+ import type {
6
+ ReadableStream,
7
+ ReadableStreamDefaultReader,
8
+ } from "./global/index.js";
5
9
  import { PushReadableStream } from "./push-readable.js";
6
- import type { ReadableStream, ReadableStreamDefaultReader } from "./stream.js";
7
10
  import { tryCancel } from "./try-close.js";
8
11
 
9
12
  export class BufferedReadableStream implements AsyncExactReadable {
package/src/concat.ts CHANGED
@@ -1,162 +1,205 @@
1
1
  import { PromiseResolver } from "@yume-chan/async";
2
2
  import { EmptyUint8Array } from "@yume-chan/struct";
3
3
 
4
- import type { ReadableStreamDefaultController } from "./stream.js";
5
- import { ReadableStream, WritableStream } from "./stream.js";
6
-
7
- export interface ConcatStringReadableStream
8
- extends ReadableStream<string>,
9
- Promise<string> {}
4
+ import type { ReadableWritablePair } from "./global/index.js";
5
+ import { ReadableStream, WritableStream } from "./global/index.js";
10
6
 
11
7
  // `TransformStream` only calls its `source.flush` method when its `readable` is being read.
12
- // If the user want to use the `Promise` interface, the `flush` method will never be called,
8
+ // If the user wants to use the `Promise` interface, the `flush` method will never be called,
13
9
  // so the `PromiseResolver` will never be resolved.
14
10
  // Thus we need to implement our own `TransformStream` using a `WritableStream` and a `ReadableStream`.
11
+ export class AccumulateStream<
12
+ Input,
13
+ Output,
14
+ Accumulated = Output,
15
+ > implements ReadableWritablePair<Output, Input> {
16
+ #current: Accumulated;
15
17
 
16
- /**
17
- * A `TransformStream` that concatenates strings.
18
- *
19
- * Its `readable` is also a `Promise<string>`, so it's possible to `await` it to get the result.
20
- *
21
- * ```ts
22
- * const result: string = await readable.pipeThrough(new ConcatStringStream());
23
- * ```
24
- */
25
- export class ConcatStringStream {
26
- // PERF: rope (concat strings) is faster than `[].join('')`
27
- #result = "";
18
+ #write: (chunk: Input, current: Accumulated) => Accumulated;
19
+ #finalize: (current: Accumulated) => Output;
28
20
 
29
- #resolver = new PromiseResolver<string>();
21
+ #resolver = new PromiseResolver<Output>();
30
22
 
31
- #writable = new WritableStream<string>({
23
+ #writable = new WritableStream<Input>({
32
24
  write: (chunk) => {
33
- this.#result += chunk;
25
+ try {
26
+ this.#current = this.#write(chunk, this.#current);
27
+ } catch (e) {
28
+ this.#resolver.reject(e);
29
+ throw e;
30
+ }
34
31
  },
35
32
  close: () => {
36
- this.#resolver.resolve(this.#result);
37
- this.#readableController.enqueue(this.#result);
38
- this.#readableController.close();
33
+ try {
34
+ const output = this.#finalize(this.#current);
35
+ this.#resolver.resolve(output);
36
+ } catch (e) {
37
+ this.#resolver.reject(e);
38
+ throw e;
39
+ }
39
40
  },
40
41
  abort: (reason) => {
41
42
  this.#resolver.reject(reason);
42
- this.#readableController.error(reason);
43
43
  },
44
44
  });
45
- get writable(): WritableStream<string> {
45
+ get writable() {
46
46
  return this.#writable;
47
47
  }
48
48
 
49
- #readableController!: ReadableStreamDefaultController<string>;
50
- #readable = new ReadableStream<string>({
51
- start: (controller) => {
52
- this.#readableController = controller;
49
+ #readable = new ReadableStream<Output>(
50
+ {
51
+ pull: async (controller) => {
52
+ const output = await this.#resolver.promise;
53
+ controller.enqueue(output);
54
+ controller.close();
55
+ },
56
+ // Ignore `abort` event since the user might use the `Promise` interface.
53
57
  },
54
- }) as ConcatStringReadableStream;
55
- get readable(): ConcatStringReadableStream {
58
+ // `highWaterMark: 0` makes the `pull` method
59
+ // only be called when the `ReadableStream` is being read.
60
+ // If the user only uses the `Promise` interface,
61
+ // it's unnecessary to run the `pull` method.
62
+ { highWaterMark: 0 },
63
+ ) as ReadableStream<Output> &
64
+ Omit<Promise<Output>, typeof Symbol.toStringTag>;
65
+ get readable() {
56
66
  return this.#readable;
57
67
  }
58
68
 
59
- constructor() {
60
- void Object.defineProperties(this.#readable, {
61
- then: {
62
- get: () =>
63
- this.#resolver.promise.then.bind(this.#resolver.promise),
64
- },
65
- catch: {
66
- get: () =>
67
- this.#resolver.promise.catch.bind(this.#resolver.promise),
68
- },
69
- finally: {
70
- get: () =>
71
- this.#resolver.promise.finally.bind(this.#resolver.promise),
72
- },
73
- });
69
+ constructor(
70
+ initial: Accumulated,
71
+ write: (chunk: Input, current: Accumulated) => Accumulated,
72
+ finalize: (current: Accumulated) => Output,
73
+ ) {
74
+ this.#current = initial;
75
+ this.#write = write;
76
+ this.#finalize = finalize;
77
+
78
+ // biome-ignore lint/suspicious/noThenProperty: This object is intentionally thenable
79
+ this.#readable.then = (onfulfilled, onrejected) => {
80
+ return this.#resolver.promise.then(onfulfilled, onrejected);
81
+ };
82
+ // biome-ignore lint/suspicious/noThenProperty: This object is intentionally thenable
83
+ this.#readable.catch = (onrejected) => {
84
+ return this.#resolver.promise.catch(onrejected);
85
+ };
86
+ // biome-ignore lint/suspicious/noThenProperty: This object is intentionally thenable
87
+ this.#readable.finally = (onfinally) => {
88
+ return this.#resolver.promise.finally(onfinally);
89
+ };
74
90
  }
75
91
  }
76
92
 
77
- export interface ConcatBufferReadableStream
78
- extends ReadableStream<Uint8Array>,
79
- Promise<Uint8Array> {}
93
+ /**
94
+ * A `TransformStream` that concatenates strings.
95
+ *
96
+ * Its `readable` is also a Promise-like, that can be `await`ed to get the result.
97
+ *
98
+ * ```ts
99
+ * const result: string = await readable.pipeThrough(new ConcatStringStream());
100
+ * ```
101
+ */
102
+ export class ConcatStringStream extends AccumulateStream<string, string> {
103
+ constructor() {
104
+ // PERF: rope (concat strings) is faster than `[].join('')`
105
+ super(
106
+ "",
107
+ (chunk, current) => current + chunk,
108
+ (output) => output,
109
+ );
110
+ }
111
+ }
80
112
 
81
113
  /**
82
- * A `TransformStream` that concatenates `Uint8Array`s.
114
+ * Concatenate all chunks into a single `Uint8Array`.
83
115
  *
84
- * If you want to decode the result as string,
85
- * prefer `.pipeThrough(new TextDecoderStream()).pipeThrough(new ConcatStringStream())`,
86
- * than `.pipeThough(new ConcatBufferStream()).pipeThrough(new TextDecoderStream())`,
87
- * because of JavaScript engine optimizations,
88
- * concatenating strings is faster than concatenating `Uint8Array`s.
116
+ * If there is only one chunk, it will be returned directly.
117
+ * @param chunks An array of `Uint8Array`s to concatenate
118
+ * @returns An `Uint8Array` containing all chunks. If there is only one chunk, it will be returned directly.
89
119
  */
90
- export class ConcatBufferStream {
91
- #segments: Uint8Array[] = [];
120
+ export function concatUint8Arrays(chunks: readonly Uint8Array[]): Uint8Array {
121
+ switch (chunks.length) {
122
+ case 0:
123
+ return EmptyUint8Array;
124
+ case 1:
125
+ return chunks[0]!;
126
+ }
92
127
 
93
- #resolver = new PromiseResolver<Uint8Array>();
128
+ const length = chunks.reduce((a, b) => a + b.length, 0);
129
+ const output = new Uint8Array(length);
130
+ let offset = 0;
131
+ for (const chunk of chunks) {
132
+ output.set(chunk, offset);
133
+ offset += chunk.length;
134
+ }
135
+ return output;
136
+ }
94
137
 
95
- #writable = new WritableStream<Uint8Array>({
96
- write: (chunk) => {
97
- this.#segments.push(chunk);
98
- },
99
- close: () => {
100
- let result: Uint8Array;
101
- let offset = 0;
102
- switch (this.#segments.length) {
103
- case 0:
104
- result = EmptyUint8Array;
105
- break;
106
- case 1:
107
- result = this.#segments[0]!;
108
- break;
109
- default:
110
- result = new Uint8Array(
111
- this.#segments.reduce(
112
- (prev, item) => prev + item.length,
113
- 0,
114
- ),
115
- );
116
- for (const segment of this.#segments) {
117
- result.set(segment, offset);
118
- offset += segment.length;
119
- }
120
- break;
121
- }
138
+ export function toUint8Array(
139
+ buffer: ArrayBufferLike | ArrayBufferView<ArrayBufferLike>,
140
+ ): Uint8Array {
141
+ if (buffer instanceof Uint8Array) {
142
+ return buffer;
143
+ }
144
+ if (ArrayBuffer.isView(buffer)) {
145
+ return new Uint8Array(
146
+ buffer.buffer,
147
+ buffer.byteOffset,
148
+ buffer.byteLength,
149
+ );
150
+ }
151
+ return new Uint8Array(buffer);
152
+ }
122
153
 
123
- this.#resolver.resolve(result);
124
- this.#readableController.enqueue(result);
125
- this.#readableController.close();
126
- },
127
- abort: (reason) => {
128
- this.#resolver.reject(reason);
129
- this.#readableController.error(reason);
130
- },
131
- });
132
- get writable(): WritableStream<Uint8Array> {
133
- return this.#writable;
154
+ export function concatBuffers(
155
+ buffers: readonly (ArrayBufferLike | ArrayBufferView<ArrayBufferLike>)[],
156
+ ): Uint8Array {
157
+ switch (buffers.length) {
158
+ case 0:
159
+ return EmptyUint8Array;
160
+ case 1:
161
+ return toUint8Array(buffers[0]!);
134
162
  }
135
163
 
136
- #readableController!: ReadableStreamDefaultController<Uint8Array>;
137
- #readable = new ReadableStream<Uint8Array>({
138
- start: (controller) => {
139
- this.#readableController = controller;
140
- },
141
- }) as ConcatBufferReadableStream;
142
- get readable(): ConcatBufferReadableStream {
143
- return this.#readable;
164
+ const length = buffers.reduce((a, b) => a + b.byteLength, 0);
165
+ const output = new Uint8Array(length);
166
+ let offset = 0;
167
+ for (const buffer of buffers) {
168
+ output.set(toUint8Array(buffer), offset);
169
+ offset += buffer.byteLength;
144
170
  }
171
+ return output;
172
+ }
145
173
 
174
+ /**
175
+ * A `TransformStream` that concatenates `Uint8Array`s.
176
+ *
177
+ * Its `readable` is also a Promise-like, that can be `await`ed to get the result.
178
+ *
179
+ * To convert a `ReadableStream<Uint8Array>` to a string,
180
+ * prefer `.pipeThrough(new TextDecoderStream()).pipeThrough(new ConcatStringStream())`,
181
+ * to `.pipeThrough(new ConcatBufferStream()).pipeThrough(new TextDecoderStream())`.
182
+ * Because of JavaScript engine optimizations,
183
+ * concatenating strings is faster than concatenating `Uint8Array`s.
184
+ */
185
+ export class ConcatBufferStream extends AccumulateStream<
186
+ Uint8Array,
187
+ Uint8Array,
188
+ Uint8Array[]
189
+ > {
146
190
  constructor() {
147
- void Object.defineProperties(this.#readable, {
148
- then: {
149
- get: () =>
150
- this.#resolver.promise.then.bind(this.#resolver.promise),
151
- },
152
- catch: {
153
- get: () =>
154
- this.#resolver.promise.catch.bind(this.#resolver.promise),
191
+ super(
192
+ [],
193
+ (chunk, current) => {
194
+ current.push(chunk);
195
+ return current;
155
196
  },
156
- finally: {
157
- get: () =>
158
- this.#resolver.promise.finally.bind(this.#resolver.promise),
197
+ (current) => {
198
+ const result = concatUint8Arrays(current);
199
+ // `current` is no longer needed. Clear it to free memory.
200
+ current.length = 0;
201
+ return result;
159
202
  },
160
- });
203
+ );
161
204
  }
162
205
  }
@@ -1,6 +1,6 @@
1
1
  import { Consumable } from "../consumable.js";
2
- import type { QueuingStrategy } from "../stream.js";
3
- import { ReadableStream } from "../stream.js";
2
+ import type { QueuingStrategy } from "../global/index.js";
3
+ import { ReadableStream } from "../global/index.js";
4
4
 
5
5
  export interface ConsumableReadableStreamController<T> {
6
6
  enqueue(chunk: T): Promise<void>;
@@ -1,5 +1,5 @@
1
1
  import type { Consumable } from "../consumable.js";
2
- import { ReadableStream } from "../stream.js";
2
+ import { ReadableStream } from "../global/index.js";
3
3
 
4
4
  import { ConsumableReadableStream } from "./readable.js";
5
5
 
@@ -9,21 +9,34 @@ export class ConsumableWrapByteReadableStream extends ReadableStream<
9
9
  constructor(
10
10
  stream: ReadableStream<Uint8Array>,
11
11
  chunkSize: number,
12
- min?: number,
12
+ options?: {
13
+ min?: number | undefined;
14
+ onRead?: ((size: number) => void) | undefined;
15
+ },
13
16
  ) {
14
17
  const reader = stream.getReader({ mode: "byob" });
15
- let array = new Uint8Array(chunkSize);
18
+ let buffer = new ArrayBuffer(chunkSize);
16
19
  super({
17
20
  async pull(controller) {
18
- const { done, value } = await reader.read(array, { min });
21
+ const { done, value } = await reader.read(
22
+ new Uint8Array(buffer),
23
+ {
24
+ min: options?.min,
25
+ },
26
+ );
27
+
28
+ // `value` might be defined even when `done` is true
29
+ if (value) {
30
+ await ConsumableReadableStream.enqueue(controller, value);
31
+ options?.onRead?.(value.byteLength);
32
+ }
33
+
19
34
  if (done) {
20
35
  controller.close();
21
36
  return;
22
37
  }
23
38
 
24
- await ConsumableReadableStream.enqueue(controller, value);
25
-
26
- array = new Uint8Array(value.buffer);
39
+ buffer = value.buffer;
27
40
  },
28
41
  cancel(reason) {
29
42
  return reader.cancel(reason);
@@ -1,5 +1,5 @@
1
1
  import type { Consumable } from "../consumable.js";
2
- import { WritableStream } from "../stream.js";
2
+ import { WritableStream } from "../global/index.js";
3
3
 
4
4
  export class ConsumableWrapWritableStream<in T> extends WritableStream<
5
5
  Consumable<T>
@@ -3,8 +3,8 @@ import type {
3
3
  QueuingStrategy,
4
4
  WritableStreamDefaultController,
5
5
  WritableStreamDefaultWriter,
6
- } from "../stream.js";
7
- import { WritableStream } from "../stream.js";
6
+ } from "../global/index.js";
7
+ import { WritableStream } from "../global/index.js";
8
8
 
9
9
  export interface ConsumableWritableStreamSink<in T> {
10
10
  start?(
package/src/consumable.ts CHANGED
@@ -14,12 +14,20 @@ import {
14
14
  import type { Task } from "./task.js";
15
15
  import { createTask } from "./task.js";
16
16
 
17
+ const Brand = Symbol.for("Consumable.brand");
18
+
17
19
  export class Consumable<T> {
18
20
  static readonly WritableStream = ConsumableWritableStream;
19
21
  static readonly WrapWritableStream = ConsumableWrapWritableStream;
20
22
  static readonly ReadableStream = ConsumableReadableStream;
21
23
  static readonly WrapByteReadableStream = ConsumableWrapByteReadableStream;
22
24
 
25
+ readonly [Brand] = true;
26
+
27
+ static [Symbol.hasInstance](value: unknown) {
28
+ return !!(value as Consumable<unknown> | undefined)?.[Brand];
29
+ }
30
+
23
31
  readonly #task: Task;
24
32
  readonly #resolver: PromiseResolver<void>;
25
33
 
@@ -1,6 +1,6 @@
1
1
  import { Consumable } from "./consumable.js";
2
+ import { TransformStream } from "./global/index.js";
2
3
  import { MaybeConsumable } from "./maybe-consumable.js";
3
- import { TransformStream } from "./stream.js";
4
4
 
5
5
  /**
6
6
  * Splits or combines buffers to specified size.
package/src/duplex.ts CHANGED
@@ -6,8 +6,8 @@ import type {
6
6
  ReadableStream,
7
7
  ReadableStreamDefaultController,
8
8
  WritableStreamDefaultWriter,
9
- } from "./stream.js";
10
- import { WritableStream } from "./stream.js";
9
+ } from "./global/index.js";
10
+ import { WritableStream } from "./global/index.js";
11
11
  import { tryClose } from "./try-close.js";
12
12
  import { WrapReadableStream } from "./wrap-readable.js";
13
13