-
-
Notifications
You must be signed in to change notification settings - Fork 396
Expand file tree
/
Copy pathWebWritableStream.ts
More file actions
47 lines (45 loc) · 1.58 KB
/
WebWritableStream.ts
File metadata and controls
47 lines (45 loc) · 1.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import { type Handler, Parser, type ParserOptions } from "./Parser.js";
/**
* WebWritableStream makes the `Parser` interface available as a Web Streams API WritableStream.
*
* This is useful for piping `fetch()` response bodies directly into the parser.
* @see Parser
* @example
* ```typescript
* import { WebWritableStream } from "htmlparser2/WebWritableStream";
*
* const stream = new WebWritableStream({
* onopentag(name, attribs) {
* console.log("Opened:", name);
* },
* });
*
* const response = await fetch("https://example.com");
* await response.body.pipeTo(stream);
* ```
*/
// eslint-disable-next-line n/no-unsupported-features/node-builtins -- Web Streams API; requires a runtime with WritableStream (browsers, Deno, Node ≥18.0)
export class WebWritableStream extends WritableStream<string | Uint8Array> {
constructor(cbs: Partial<Handler>, options?: ParserOptions) {
const parser = new Parser(cbs, options);
const decoder = new TextDecoder();
const streamOption: TextDecodeOptions = { stream: true };
super({
write(chunk) {
parser.write(
typeof chunk === "string"
? chunk
: decoder.decode(chunk, streamOption),
);
},
close() {
// Flush any remaining bytes in the decoder
const remaining = decoder.decode();
if (remaining) {
parser.write(remaining);
}
parser.end();
},
});
}
}