@yume-chan/adb 0.0.10 → 0.0.11

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 (318) hide show
  1. package/CHANGELOG.json +26 -0
  2. package/CHANGELOG.md +15 -1
  3. package/LICENSE +1 -1
  4. package/README.md +56 -43
  5. package/esm/adb.d.ts +48 -0
  6. package/esm/adb.d.ts.map +1 -0
  7. package/esm/adb.js +141 -146
  8. package/esm/adb.js.map +1 -1
  9. package/{dts → esm}/auth.d.ts +8 -8
  10. package/esm/auth.d.ts.map +1 -0
  11. package/esm/auth.js +68 -108
  12. package/esm/auth.js.map +1 -1
  13. package/esm/backend.d.ts +9 -0
  14. package/esm/backend.d.ts.map +1 -0
  15. package/{dts → esm}/commands/base.d.ts +1 -1
  16. package/esm/commands/base.d.ts.map +1 -0
  17. package/esm/commands/base.js +1 -0
  18. package/esm/commands/base.js.map +1 -1
  19. package/{dts → esm}/commands/framebuffer.d.ts +3 -3
  20. package/esm/commands/framebuffer.d.ts.map +1 -0
  21. package/esm/commands/framebuffer.js +15 -18
  22. package/esm/commands/framebuffer.js.map +1 -1
  23. package/esm/commands/index.d.ts +9 -0
  24. package/esm/commands/index.d.ts.map +1 -0
  25. package/esm/commands/index.js +8 -8
  26. package/esm/commands/index.js.map +1 -1
  27. package/esm/commands/install.d.ts +4 -0
  28. package/esm/commands/install.d.ts.map +1 -0
  29. package/esm/commands/install.js +21 -13
  30. package/esm/commands/install.js.map +1 -1
  31. package/esm/commands/power.d.ts +23 -0
  32. package/esm/commands/power.d.ts.map +1 -0
  33. package/esm/commands/power.js +45 -0
  34. package/esm/commands/power.js.map +1 -0
  35. package/{dts → esm}/commands/reverse.d.ts +3 -3
  36. package/esm/commands/reverse.d.ts.map +1 -0
  37. package/esm/commands/reverse.js +49 -60
  38. package/esm/commands/reverse.js.map +1 -1
  39. package/esm/commands/subprocess/index.d.ts +57 -0
  40. package/esm/commands/subprocess/index.d.ts.map +1 -0
  41. package/esm/commands/subprocess/index.js +83 -0
  42. package/esm/commands/subprocess/index.js.map +1 -0
  43. package/esm/commands/subprocess/legacy.d.ts +28 -0
  44. package/esm/commands/subprocess/legacy.d.ts.map +1 -0
  45. package/esm/commands/subprocess/legacy.js +44 -0
  46. package/esm/commands/subprocess/legacy.js.map +1 -0
  47. package/esm/commands/subprocess/protocol.d.ts +38 -0
  48. package/esm/commands/subprocess/protocol.d.ts.map +1 -0
  49. package/esm/commands/subprocess/protocol.js +155 -0
  50. package/esm/commands/subprocess/protocol.js.map +1 -0
  51. package/esm/commands/subprocess/types.d.ts +47 -0
  52. package/esm/commands/subprocess/types.d.ts.map +1 -0
  53. package/esm/commands/{shell → subprocess}/types.js +0 -0
  54. package/esm/commands/{shell → subprocess}/types.js.map +1 -1
  55. package/{dts/commands/shell → esm/commands/subprocess}/utils.d.ts +0 -0
  56. package/esm/commands/subprocess/utils.d.ts.map +1 -0
  57. package/esm/commands/{shell → subprocess}/utils.js +0 -0
  58. package/esm/commands/subprocess/utils.js.map +1 -0
  59. package/esm/commands/sync/index.d.ts +8 -0
  60. package/esm/commands/sync/index.d.ts.map +1 -0
  61. package/esm/commands/sync/index.js +7 -7
  62. package/esm/commands/sync/index.js.map +1 -1
  63. package/{dts → esm}/commands/sync/list.d.ts +4 -4
  64. package/esm/commands/sync/list.d.ts.map +1 -0
  65. package/esm/commands/sync/list.js +16 -19
  66. package/esm/commands/sync/list.js.map +1 -1
  67. package/esm/commands/sync/pull.d.ts +11 -0
  68. package/esm/commands/sync/pull.d.ts.map +1 -0
  69. package/esm/commands/sync/pull.js +17 -11
  70. package/esm/commands/sync/pull.js.map +1 -1
  71. package/esm/commands/sync/push.d.ts +8 -0
  72. package/esm/commands/sync/push.d.ts.map +1 -0
  73. package/esm/commands/sync/push.js +19 -37
  74. package/esm/commands/sync/push.js.map +1 -1
  75. package/{dts → esm}/commands/sync/request.d.ts +3 -3
  76. package/esm/commands/sync/request.d.ts.map +1 -0
  77. package/esm/commands/sync/request.js +24 -27
  78. package/esm/commands/sync/request.js.map +1 -1
  79. package/{dts → esm}/commands/sync/response.d.ts +2 -2
  80. package/esm/commands/sync/response.d.ts.map +1 -0
  81. package/esm/commands/sync/response.js +16 -20
  82. package/esm/commands/sync/response.js.map +1 -1
  83. package/{dts → esm}/commands/sync/stat.d.ts +4 -4
  84. package/esm/commands/sync/stat.d.ts.map +1 -0
  85. package/esm/commands/sync/stat.js +22 -27
  86. package/esm/commands/sync/stat.js.map +1 -1
  87. package/esm/commands/sync/sync.d.ts +83 -0
  88. package/esm/commands/sync/sync.d.ts.map +1 -0
  89. package/esm/commands/sync/sync.js +92 -89
  90. package/esm/commands/sync/sync.js.map +1 -1
  91. package/{dts → esm}/commands/tcpip.d.ts +1 -1
  92. package/{dts → esm}/commands/tcpip.d.ts.map +1 -1
  93. package/esm/commands/tcpip.js +14 -19
  94. package/esm/commands/tcpip.js.map +1 -1
  95. package/{dts → esm}/crypto.d.ts +7 -7
  96. package/esm/crypto.d.ts.map +1 -0
  97. package/esm/crypto.js +26 -29
  98. package/esm/crypto.js.map +1 -1
  99. package/{dts → esm}/features.d.ts +0 -0
  100. package/{dts → esm}/features.d.ts.map +0 -0
  101. package/esm/features.js +1 -1
  102. package/esm/features.js.map +1 -1
  103. package/esm/index.d.ts +11 -0
  104. package/esm/index.d.ts.map +1 -0
  105. package/esm/index.js +10 -10
  106. package/esm/index.js.map +1 -1
  107. package/esm/packet.d.ts +28 -0
  108. package/esm/packet.d.ts.map +1 -0
  109. package/esm/packet.js +26 -51
  110. package/esm/packet.js.map +1 -1
  111. package/esm/socket/controller.d.ts +37 -0
  112. package/esm/socket/controller.d.ts.map +1 -0
  113. package/esm/socket/controller.js +52 -66
  114. package/esm/socket/controller.js.map +1 -1
  115. package/{dts → esm}/socket/dispatcher.d.ts +10 -23
  116. package/esm/socket/dispatcher.d.ts.map +1 -0
  117. package/esm/socket/dispatcher.js +148 -164
  118. package/esm/socket/dispatcher.js.map +1 -1
  119. package/esm/socket/index.d.ts +3 -0
  120. package/esm/socket/index.d.ts.map +1 -0
  121. package/esm/socket/index.js +2 -6
  122. package/esm/socket/index.js.map +1 -1
  123. package/esm/socket/socket.d.ts +34 -0
  124. package/esm/socket/socket.d.ts.map +1 -0
  125. package/esm/socket/socket.js +69 -14
  126. package/esm/socket/socket.js.map +1 -1
  127. package/esm/stream/buffered.d.ts +35 -0
  128. package/esm/stream/buffered.d.ts.map +1 -0
  129. package/esm/stream/buffered.js +123 -0
  130. package/esm/stream/buffered.js.map +1 -0
  131. package/esm/stream/detect.bak.d.ts +240 -0
  132. package/esm/stream/detect.bak.d.ts.map +1 -0
  133. package/esm/stream/detect.bak.js +60 -0
  134. package/esm/stream/detect.bak.js.map +1 -0
  135. package/esm/stream/detect.d.ts +18 -0
  136. package/esm/stream/detect.d.ts.map +1 -0
  137. package/esm/stream/detect.js +6 -0
  138. package/esm/stream/detect.js.map +1 -0
  139. package/esm/stream/detect.native.d.ts +240 -0
  140. package/esm/stream/detect.native.d.ts.map +1 -0
  141. package/esm/stream/detect.native.js +60 -0
  142. package/esm/stream/detect.native.js.map +1 -0
  143. package/esm/stream/detect.polyfill.d.ts +18 -0
  144. package/esm/stream/detect.polyfill.d.ts.map +1 -0
  145. package/esm/stream/detect.polyfill.js +6 -0
  146. package/esm/stream/detect.polyfill.js.map +1 -0
  147. package/esm/stream/index.d.ts +4 -0
  148. package/esm/stream/index.d.ts.map +1 -0
  149. package/esm/stream/index.js +3 -2
  150. package/esm/stream/index.js.map +1 -1
  151. package/esm/stream/transform.d.ts +98 -0
  152. package/esm/stream/transform.d.ts.map +1 -0
  153. package/esm/stream/transform.js +352 -0
  154. package/esm/stream/transform.js.map +1 -0
  155. package/{dts → esm}/utils/auto-reset-event.d.ts +1 -1
  156. package/esm/utils/auto-reset-event.d.ts.map +1 -0
  157. package/esm/utils/auto-reset-event.js +2 -1
  158. package/esm/utils/auto-reset-event.js.map +1 -1
  159. package/esm/utils/base64.d.ts +5 -0
  160. package/esm/utils/base64.d.ts.map +1 -0
  161. package/esm/utils/base64.js +116 -80
  162. package/esm/utils/base64.js.map +1 -1
  163. package/esm/utils/encoding.d.ts +3 -0
  164. package/{dts → esm}/utils/encoding.d.ts.map +1 -1
  165. package/esm/utils/encoding.js +1 -1
  166. package/esm/utils/encoding.js.map +1 -1
  167. package/esm/utils/index.d.ts +4 -0
  168. package/esm/utils/index.d.ts.map +1 -0
  169. package/esm/utils/index.js +3 -5
  170. package/esm/utils/index.js.map +1 -1
  171. package/package.json +50 -44
  172. package/src/adb.ts +147 -143
  173. package/src/auth.ts +23 -19
  174. package/src/backend.ts +3 -12
  175. package/src/commands/base.ts +1 -1
  176. package/src/commands/framebuffer.ts +4 -4
  177. package/src/commands/index.ts +8 -8
  178. package/src/commands/install.ts +26 -15
  179. package/src/commands/power.ts +54 -0
  180. package/src/commands/reverse.ts +10 -8
  181. package/src/commands/subprocess/index.ts +124 -0
  182. package/src/commands/subprocess/legacy.ts +58 -0
  183. package/src/commands/subprocess/protocol.ts +185 -0
  184. package/src/commands/subprocess/types.ts +55 -0
  185. package/src/commands/{shell → subprocess}/utils.ts +0 -0
  186. package/src/commands/sync/index.ts +7 -7
  187. package/src/commands/sync/list.ts +7 -6
  188. package/src/commands/sync/pull.ts +27 -18
  189. package/src/commands/sync/push.ts +25 -30
  190. package/src/commands/sync/request.ts +7 -7
  191. package/src/commands/sync/response.ts +4 -4
  192. package/src/commands/sync/stat.ts +8 -6
  193. package/src/commands/sync/sync.ts +64 -32
  194. package/src/commands/tcpip.ts +3 -3
  195. package/src/crypto.ts +38 -43
  196. package/src/index.ts +11 -10
  197. package/src/packet.ts +37 -52
  198. package/src/socket/dispatcher.ts +90 -103
  199. package/src/socket/index.ts +2 -6
  200. package/src/socket/socket.ts +117 -16
  201. package/src/stream/buffered.ts +147 -0
  202. package/src/stream/detect.native.ts +362 -0
  203. package/src/stream/detect.polyfill.ts +25 -0
  204. package/src/stream/detect.ts +25 -0
  205. package/src/stream/index.ts +3 -2
  206. package/src/stream/transform.ts +427 -0
  207. package/src/utils/auto-reset-event.ts +1 -1
  208. package/src/utils/base64.ts +161 -129
  209. package/src/utils/encoding.ts +3 -3
  210. package/src/utils/index.ts +3 -5
  211. package/tsconfig.build.json +3 -0
  212. package/tsconfig.build.tsbuildinfo +1 -0
  213. package/tsconfig.test.json +10 -0
  214. package/dts/adb.d.ts +0 -46
  215. package/dts/adb.d.ts.map +0 -1
  216. package/dts/auth.d.ts.map +0 -1
  217. package/dts/backend.d.ts +0 -13
  218. package/dts/backend.d.ts.map +0 -1
  219. package/dts/commands/base.d.ts.map +0 -1
  220. package/dts/commands/demo-mode.d.ts +0 -41
  221. package/dts/commands/demo-mode.d.ts.map +0 -1
  222. package/dts/commands/framebuffer.d.ts.map +0 -1
  223. package/dts/commands/index.d.ts +0 -9
  224. package/dts/commands/index.d.ts.map +0 -1
  225. package/dts/commands/install.d.ts +0 -3
  226. package/dts/commands/install.d.ts.map +0 -1
  227. package/dts/commands/reverse.d.ts.map +0 -1
  228. package/dts/commands/shell/index.d.ts +0 -46
  229. package/dts/commands/shell/index.d.ts.map +0 -1
  230. package/dts/commands/shell/legacy.d.ts +0 -38
  231. package/dts/commands/shell/legacy.d.ts.map +0 -1
  232. package/dts/commands/shell/protocol.d.ts +0 -45
  233. package/dts/commands/shell/protocol.d.ts.map +0 -1
  234. package/dts/commands/shell/types.d.ts +0 -47
  235. package/dts/commands/shell/types.d.ts.map +0 -1
  236. package/dts/commands/shell/utils.d.ts.map +0 -1
  237. package/dts/commands/sync/index.d.ts +0 -8
  238. package/dts/commands/sync/index.d.ts.map +0 -1
  239. package/dts/commands/sync/list.d.ts.map +0 -1
  240. package/dts/commands/sync/pull.d.ts +0 -11
  241. package/dts/commands/sync/pull.d.ts.map +0 -1
  242. package/dts/commands/sync/push.d.ts +0 -8
  243. package/dts/commands/sync/push.d.ts.map +0 -1
  244. package/dts/commands/sync/request.d.ts.map +0 -1
  245. package/dts/commands/sync/response.d.ts.map +0 -1
  246. package/dts/commands/sync/stat.d.ts.map +0 -1
  247. package/dts/commands/sync/sync.d.ts +0 -68
  248. package/dts/commands/sync/sync.d.ts.map +0 -1
  249. package/dts/crypto.d.ts.map +0 -1
  250. package/dts/index.d.ts +0 -11
  251. package/dts/index.d.ts.map +0 -1
  252. package/dts/packet.d.ts +0 -27
  253. package/dts/packet.d.ts.map +0 -1
  254. package/dts/socket/close-event-emitter.d.ts +0 -8
  255. package/dts/socket/close-event-emitter.d.ts.map +0 -1
  256. package/dts/socket/controller.d.ts +0 -43
  257. package/dts/socket/controller.d.ts.map +0 -1
  258. package/dts/socket/data-event-emitter.d.ts +0 -10
  259. package/dts/socket/data-event-emitter.d.ts.map +0 -1
  260. package/dts/socket/dispatcher.d.ts.map +0 -1
  261. package/dts/socket/index.d.ts +0 -7
  262. package/dts/socket/index.d.ts.map +0 -1
  263. package/dts/socket/logger.d.ts +0 -9
  264. package/dts/socket/logger.d.ts.map +0 -1
  265. package/dts/socket/socket.d.ts +0 -22
  266. package/dts/socket/socket.d.ts.map +0 -1
  267. package/dts/stream/buffered-stream.d.ts +0 -28
  268. package/dts/stream/buffered-stream.d.ts.map +0 -1
  269. package/dts/stream/index.d.ts +0 -3
  270. package/dts/stream/index.d.ts.map +0 -1
  271. package/dts/stream/stream.d.ts +0 -15
  272. package/dts/stream/stream.d.ts.map +0 -1
  273. package/dts/utils/auto-reset-event.d.ts.map +0 -1
  274. package/dts/utils/base64.d.ts +0 -7
  275. package/dts/utils/base64.d.ts.map +0 -1
  276. package/dts/utils/chunk.d.ts +0 -3
  277. package/dts/utils/chunk.d.ts.map +0 -1
  278. package/dts/utils/encoding.d.ts +0 -3
  279. package/dts/utils/event-queue.d.ts +0 -35
  280. package/dts/utils/event-queue.d.ts.map +0 -1
  281. package/dts/utils/index.d.ts +0 -6
  282. package/dts/utils/index.d.ts.map +0 -1
  283. package/esm/commands/demo-mode.js +0 -170
  284. package/esm/commands/demo-mode.js.map +0 -1
  285. package/esm/commands/shell/index.js +0 -62
  286. package/esm/commands/shell/index.js.map +0 -1
  287. package/esm/commands/shell/legacy.js +0 -49
  288. package/esm/commands/shell/legacy.js.map +0 -1
  289. package/esm/commands/shell/protocol.js +0 -106
  290. package/esm/commands/shell/protocol.js.map +0 -1
  291. package/esm/commands/shell/utils.js.map +0 -1
  292. package/esm/socket/close-event-emitter.js +0 -28
  293. package/esm/socket/close-event-emitter.js.map +0 -1
  294. package/esm/socket/data-event-emitter.js +0 -25
  295. package/esm/socket/data-event-emitter.js.map +0 -1
  296. package/esm/socket/logger.js +0 -2
  297. package/esm/socket/logger.js.map +0 -1
  298. package/esm/stream/buffered-stream.js +0 -67
  299. package/esm/stream/buffered-stream.js.map +0 -1
  300. package/esm/stream/stream.js +0 -41
  301. package/esm/stream/stream.js.map +0 -1
  302. package/esm/utils/chunk.js +0 -70
  303. package/esm/utils/chunk.js.map +0 -1
  304. package/esm/utils/event-queue.js +0 -104
  305. package/esm/utils/event-queue.js.map +0 -1
  306. package/src/commands/demo-mode.ts +0 -160
  307. package/src/commands/shell/index.ts +0 -87
  308. package/src/commands/shell/legacy.ts +0 -59
  309. package/src/commands/shell/protocol.ts +0 -121
  310. package/src/commands/shell/types.ts +0 -55
  311. package/src/socket/close-event-emitter.ts +0 -28
  312. package/src/socket/controller.ts +0 -105
  313. package/src/socket/data-event-emitter.ts +0 -27
  314. package/src/socket/logger.ts +0 -12
  315. package/src/stream/buffered-stream.ts +0 -92
  316. package/src/stream/stream.ts +0 -50
  317. package/src/utils/chunk.ts +0 -70
  318. package/src/utils/event-queue.ts +0 -145
@@ -0,0 +1,427 @@
1
+ import { PromiseResolver } from "@yume-chan/async";
2
+ import type Struct from "@yume-chan/struct";
3
+ import type { StructValueType } from "@yume-chan/struct";
4
+ import { decodeUtf8 } from "../utils/index.js";
5
+ import { BufferedStream, BufferedStreamEndedError } from "./buffered.js";
6
+ import { AbortController, AbortSignal, ReadableStream, ReadableStreamDefaultReader, TransformStream, WritableStream, WritableStreamDefaultWriter, type QueuingStrategy, type ReadableStreamDefaultController, type ReadableWritablePair, type UnderlyingSink, type UnderlyingSource } from "./detect.js";
7
+
8
+ export interface DuplexStreamFactoryOptions {
9
+ preventCloseReadableStreams?: boolean | undefined;
10
+
11
+ close?: (() => void | Promise<void>) | undefined;
12
+ }
13
+
14
+ export class DuplexStreamFactory<R, W> {
15
+ private readableControllers: ReadableStreamDefaultController<R>[] = [];
16
+ private pushReadableControllers: PushReadableStreamController<R>[] = [];
17
+
18
+ private _closed = new PromiseResolver<void>();
19
+ public get closed() { return this._closed.promise; }
20
+
21
+ private options: DuplexStreamFactoryOptions;
22
+
23
+ private _closeRequestedByReadable = false;
24
+ private _writableClosed = false;
25
+
26
+ public constructor(options?: DuplexStreamFactoryOptions) {
27
+ this.options = options ?? {};
28
+ }
29
+
30
+ public createPushReadable(source: PushReadableStreamSource<R>, strategy?: QueuingStrategy<R>): PushReadableStream<R> {
31
+ return new PushReadableStream<R>(controller => {
32
+ this.pushReadableControllers.push(controller);
33
+
34
+ controller.abortSignal.addEventListener('abort', async () => {
35
+ this._closeRequestedByReadable = true;
36
+ await this.close();
37
+ });
38
+
39
+ source({
40
+ abortSignal: controller.abortSignal,
41
+ async enqueue(chunk) {
42
+ await controller.enqueue(chunk);
43
+ },
44
+ close: async () => {
45
+ controller.close();
46
+ this._closeRequestedByReadable = true;
47
+ await this.close();
48
+ },
49
+ error: async (e?: any) => {
50
+ controller.error(e);
51
+ this._closeRequestedByReadable = true;
52
+ await this.close();
53
+ },
54
+ });
55
+ }, strategy);
56
+ };
57
+
58
+ public createWrapReadable(readable: ReadableStream<R>): WrapReadableStream<R, ReadableStream<R>, void> {
59
+ return new WrapReadableStream<R, ReadableStream<R>, void>({
60
+ async start() {
61
+ return {
62
+ readable,
63
+ state: undefined,
64
+ };
65
+ },
66
+ close: async () => {
67
+ this._closeRequestedByReadable = true;
68
+ await this.close();
69
+ },
70
+ });
71
+ }
72
+
73
+ public createReadable(source?: UnderlyingSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R> {
74
+ return new ReadableStream<R>({
75
+ start: async (controller) => {
76
+ this.readableControllers.push(controller);
77
+ await source?.start?.(controller);
78
+ },
79
+ pull: (controller) => {
80
+ return source?.pull?.(controller);
81
+ },
82
+ cancel: async (reason) => {
83
+ await source?.cancel?.(reason);
84
+ this._closeRequestedByReadable = true;
85
+ await this.close();
86
+ },
87
+ }, strategy);
88
+ }
89
+
90
+ public createWritable(sink: UnderlyingSink<W>, strategy?: QueuingStrategy<W>): WritableStream<W> {
91
+ return new WritableStream<W>({
92
+ start: async (controller) => {
93
+ await sink.start?.(controller);
94
+ },
95
+ write: async (chunk, controller) => {
96
+ if (this._writableClosed) {
97
+ throw new Error("stream is closed");
98
+ }
99
+
100
+ await sink.write?.(chunk, controller);
101
+ },
102
+ close: async () => {
103
+ await sink.close?.();
104
+ this.close();
105
+ },
106
+ abort: async (reason) => {
107
+ await sink.abort?.(reason);
108
+ await this.close();
109
+ },
110
+ }, strategy);
111
+ }
112
+
113
+ public async closeReadableStreams() {
114
+ this._closed.resolve();
115
+ await this.options.close?.();
116
+
117
+ for (const controller of this.readableControllers) {
118
+ try {
119
+ controller.close();
120
+ } catch { }
121
+ }
122
+
123
+ for (const controller of this.pushReadableControllers) {
124
+ try {
125
+ controller.close();
126
+ } catch { }
127
+ }
128
+ }
129
+
130
+ public async close() {
131
+ this._writableClosed = true;
132
+
133
+ if (this._closeRequestedByReadable ||
134
+ !this.options.preventCloseReadableStreams) {
135
+ await this.closeReadableStreams();
136
+ }
137
+ }
138
+ }
139
+
140
+ export class DecodeUtf8Stream extends TransformStream<Uint8Array, string>{
141
+ public constructor() {
142
+ super({
143
+ transform(chunk, controller) {
144
+ controller.enqueue(decodeUtf8(chunk));
145
+ },
146
+ });
147
+ }
148
+ }
149
+
150
+ export class GatherStringStream extends TransformStream<string, string>{
151
+ // Optimization: rope (concat strings) is faster than `[].join('')`
152
+ private _result = '';
153
+ public get result() { return this._result; }
154
+
155
+ public constructor() {
156
+ super({
157
+ transform: (chunk) => {
158
+ this._result += chunk;
159
+ },
160
+ });
161
+ }
162
+ }
163
+
164
+ // TODO: Find other ways to implement `StructTransformStream`
165
+ export class StructDeserializeStream<T extends Struct<any, any, any, any>>
166
+ implements ReadableWritablePair<Uint8Array, StructValueType<T>>{
167
+ private _readable: ReadableStream<StructValueType<T>>;
168
+ public get readable() { return this._readable; }
169
+
170
+ private _writable: WritableStream<Uint8Array>;
171
+ public get writable() { return this._writable; }
172
+
173
+ public constructor(struct: T) {
174
+ // Convert incoming chunks to a `BufferedStream`
175
+ let incomingStreamController!: PushReadableStreamController<Uint8Array>;
176
+ const incomingStream = new BufferedStream(
177
+ new PushReadableStream<Uint8Array>(
178
+ controller => incomingStreamController = controller,
179
+ )
180
+ );
181
+
182
+ this._readable = new ReadableStream<StructValueType<T>>({
183
+ async pull(controller) {
184
+ try {
185
+ const value = await struct.deserialize(incomingStream);
186
+ controller.enqueue(value);
187
+ } catch (e) {
188
+ if (e instanceof BufferedStreamEndedError) {
189
+ controller.close();
190
+ return;
191
+ }
192
+ throw e;
193
+ }
194
+ }
195
+ });
196
+
197
+ this._writable = new WritableStream({
198
+ async write(chunk) {
199
+ await incomingStreamController.enqueue(chunk);
200
+ },
201
+ abort() {
202
+ incomingStreamController.close();
203
+ },
204
+ close() {
205
+ incomingStreamController.close();
206
+ },
207
+ });
208
+ }
209
+ }
210
+
211
+ export class StructSerializeStream<T extends Struct<any, any, any, any>>
212
+ extends TransformStream<T['TInit'], Uint8Array>{
213
+ constructor(struct: T) {
214
+ super({
215
+ transform(chunk, controller) {
216
+ controller.enqueue(struct.serialize(chunk));
217
+ },
218
+ });
219
+ }
220
+ }
221
+
222
+ export interface WritableStreamWrapper<T, W extends WritableStream<T>, S> {
223
+ start(): Promise<{ writable: W, state: S; }>;
224
+ close?(state: S): Promise<void>;
225
+ }
226
+
227
+ export class WrapWritableStream<T, W extends WritableStream<T>, S> extends WritableStream<T>{
228
+ public writable!: W;
229
+
230
+ private writer!: WritableStreamDefaultWriter<T>;
231
+
232
+ private state!: S;
233
+
234
+ public constructor(wrapper: WritableStreamWrapper<T, W, S>) {
235
+ super({
236
+ start: async () => {
237
+ const { writable, state } = await wrapper.start();
238
+ this.writable = writable;
239
+ this.writer = writable.getWriter();
240
+ this.state = state;
241
+ },
242
+ write: async (chunk) => {
243
+ // Maintain back pressure
244
+ await this.writer.ready;
245
+ await this.writer.write(chunk);
246
+ },
247
+ abort: async (reason) => {
248
+ await this.writer.abort(reason);
249
+ wrapper.close?.(this.state);
250
+ },
251
+ close: async () => {
252
+ await this.writer.close();
253
+ await wrapper.close?.(this.state);
254
+ },
255
+ });
256
+ }
257
+ }
258
+
259
+ export interface ReadableStreamWrapper<T, R extends ReadableStream<T>, S> {
260
+ start(): Promise<{ readable: R, state: S; }>;
261
+ close?(state: S): Promise<void>;
262
+ }
263
+
264
+ export class WrapReadableStream<T, R extends ReadableStream<T>, S> extends ReadableStream<T>{
265
+ public readable!: R;
266
+
267
+ private reader!: ReadableStreamDefaultReader<T>;
268
+
269
+ private state!: S;
270
+
271
+ public constructor(wrapper: ReadableStreamWrapper<T, R, S>) {
272
+ super({
273
+ start: async () => {
274
+ const { readable, state } = await wrapper.start();
275
+ this.readable = readable;
276
+ this.reader = readable.getReader();
277
+ this.state = state;
278
+ },
279
+ cancel: async (reason) => {
280
+ await this.reader.cancel(reason);
281
+ wrapper.close?.(this.state);
282
+ },
283
+ pull: async (controller) => {
284
+ const result = await this.reader.read();
285
+ if (result.done) {
286
+ wrapper.close?.(this.state);
287
+ controller.close();
288
+ } else {
289
+ controller.enqueue(result.value);
290
+ }
291
+ }
292
+ });
293
+ }
294
+ }
295
+
296
+ export class ChunkStream extends TransformStream<Uint8Array, Uint8Array>{
297
+ public constructor(size: number) {
298
+ super({
299
+ transform(chunk, controller) {
300
+ for (let start = 0; start < chunk.byteLength;) {
301
+ const end = start + size;
302
+ controller.enqueue(chunk.subarray(start, end));
303
+ start = end;
304
+ }
305
+ }
306
+ });
307
+ }
308
+ }
309
+
310
+ function* splitLines(text: string): Generator<string, void, void> {
311
+ let start = 0;
312
+
313
+ while (true) {
314
+ const index = text.indexOf('\n', start);
315
+ if (index === -1) {
316
+ return;
317
+ }
318
+
319
+ const line = text.substring(start, index);
320
+ yield line;
321
+
322
+ start = index + 1;
323
+ }
324
+ }
325
+
326
+ export class SplitLineStream extends TransformStream<string, string> {
327
+ public constructor() {
328
+ super({
329
+ transform(chunk, controller) {
330
+ for (const line of splitLines(chunk)) {
331
+ controller.enqueue(line);
332
+ }
333
+ }
334
+ });
335
+ }
336
+ }
337
+
338
+ /**
339
+ * Create a new `WritableStream` that, when written to, will write that chunk to
340
+ * `pair.writable`, when pipe `pair.readable` to `writable`.
341
+ *
342
+ * It's the opposite of `ReadableStream.pipeThrough`.
343
+ *
344
+ * @param writable The `WritableStream` to write to.
345
+ * @param pair A `TransformStream` that converts chunks.
346
+ * @returns A new `WritableStream`.
347
+ */
348
+ export function pipeFrom<W, T>(writable: WritableStream<W>, pair: ReadableWritablePair<W, T>) {
349
+ const writer = pair.writable.getWriter();
350
+ const pipe = pair.readable
351
+ .pipeTo(writable);
352
+ return new WritableStream<T>({
353
+ async write(chunk) {
354
+ await writer.ready;
355
+ await writer.write(chunk);
356
+ },
357
+ async close() {
358
+ await writer.close();
359
+ await pipe;
360
+ }
361
+ });
362
+ }
363
+
364
+ export class InspectStream<T> extends TransformStream<T, T> {
365
+ constructor(callback: (value: T) => void) {
366
+ super({
367
+ transform(chunk, controller) {
368
+ callback(chunk);
369
+ controller.enqueue(chunk);
370
+ }
371
+ });
372
+ }
373
+ }
374
+
375
+ export interface PushReadableStreamController<T> {
376
+ abortSignal: AbortSignal;
377
+
378
+ enqueue(chunk: T): Promise<void>;
379
+
380
+ close(): void;
381
+
382
+ error(e?: any): void;
383
+ }
384
+
385
+ export type PushReadableStreamSource<T> = (controller: PushReadableStreamController<T>) => void;
386
+
387
+ export class PushReadableStream<T> extends ReadableStream<T> {
388
+ public constructor(source: PushReadableStreamSource<T>, strategy?: QueuingStrategy<T>) {
389
+ let waterMarkLow: PromiseResolver<void> | undefined;
390
+ const canceled: AbortController = new AbortController();
391
+
392
+ super({
393
+ start: (controller) => {
394
+ source({
395
+ abortSignal: canceled.signal,
396
+ async enqueue(chunk) {
397
+ // Only when the stream in errored, `desiredSize` will be `null`.
398
+ // But since `null <= 0` is `true`
399
+ // (`null <= 0` is evaluated as `!(null > 0)` => `!false` => `true`),
400
+ // not handling it will cause a deadlock.
401
+ if ((controller.desiredSize ?? 1) <= 0) {
402
+ waterMarkLow = new PromiseResolver<void>();
403
+ await waterMarkLow.promise;
404
+ }
405
+
406
+ // `controller.enqueue` will throw error for us
407
+ // if the stream is already errored.
408
+ controller.enqueue(chunk);
409
+ },
410
+ close() {
411
+ controller.close();
412
+ },
413
+ error(e) {
414
+ controller.error(e);
415
+ },
416
+ });
417
+ },
418
+ pull: () => {
419
+ waterMarkLow?.resolve();
420
+ },
421
+ cancel: async (reason) => {
422
+ waterMarkLow?.reject(reason);
423
+ canceled.abort();
424
+ },
425
+ }, strategy);
426
+ }
427
+ }
@@ -1,5 +1,5 @@
1
1
  import { PromiseResolver } from '@yume-chan/async';
2
- import { Disposable } from '@yume-chan/event';
2
+ import type { Disposable } from '@yume-chan/event';
3
3
 
4
4
  export class AutoResetEvent implements Disposable {
5
5
  private readonly list: PromiseResolver<void>[] = [];