|
1 | 1 | import type {ReadStream} from "node:fs"; |
2 | | -import {SaxEventType, SAXParser, Tag, Text} from "sax-wasm"; |
| 2 | +import {SaxEvent, SaxEventType, SAXParser, Tag, Text} from "sax-wasm"; |
3 | 3 | import {finished} from "node:stream/promises"; |
4 | 4 | import fs from "node:fs/promises"; |
5 | 5 | import {createRequire} from "node:module"; |
6 | 6 | import {Directive} from "../linter/LinterContext.js"; |
| 7 | +import {Readable} from "node:stream"; |
7 | 8 | const require = createRequire(import.meta.url); |
8 | 9 |
|
9 | 10 | export function isSaxParserToJSON(tag: unknown): tag is Tag { |
@@ -50,43 +51,32 @@ export function extractDirective(comment: Text): Directive | undefined { |
50 | 51 | }; |
51 | 52 | } |
52 | 53 |
|
53 | | -let saxWasmBuffer: Buffer; |
| 54 | +let saxWasmBuffer: Uint8Array; |
54 | 55 | export async function initSaxWasm() { |
55 | 56 | if (!saxWasmBuffer) { |
56 | 57 | const saxPath = require.resolve("sax-wasm/lib/sax-wasm.wasm"); |
57 | | - saxWasmBuffer = await fs.readFile(saxPath); |
| 58 | + saxWasmBuffer = await fs.readFile(saxPath) as Uint8Array; |
58 | 59 | } |
59 | 60 |
|
60 | 61 | return saxWasmBuffer; |
61 | 62 | } |
62 | 63 |
|
63 | 64 | export async function parseXml( |
64 | | - contentStream: ReadStream, parseHandler: typeof SAXParser.prototype.eventHandler, |
| 65 | + contentStream: ReadStream, parseHandler: (event: SaxEvent[0], detail: SaxEvent[1]) => void, |
65 | 66 | events: number = SaxEventType.CloseTag | SaxEventType.OpenTag | SaxEventType.Comment) { |
66 | 67 | const saxWasmBuffer = await initSaxWasm(); |
67 | 68 | const saxParser = new SAXParser(events); |
68 | 69 |
|
69 | | - saxParser.eventHandler = parseHandler; |
70 | | - |
71 | 70 | // Instantiate and prepare the wasm for parsing |
72 | 71 | if (!await saxParser.prepareWasm(saxWasmBuffer)) { |
73 | 72 | throw new Error("Unknown error during WASM Initialization"); |
74 | 73 | } |
75 | 74 |
|
76 | | - // Start the stream |
77 | | - contentStream.on("data", (chunk: Uint8Array) => { |
78 | | - try { |
79 | | - saxParser.write(chunk); |
80 | | - } catch (err) { |
81 | | - if (err instanceof Error) { |
82 | | - // In case of an error, destroy the content stream to make the |
83 | | - // error bubble up to our callers |
84 | | - contentStream.destroy(err); |
85 | | - } else { |
86 | | - throw err; |
87 | | - } |
88 | | - } |
89 | | - }); |
| 75 | + const webContentStream = Readable.toWeb(contentStream) as ReadableStream<Uint8Array>; |
| 76 | + |
| 77 | + for await (const [event, detail] of saxParser.parse(webContentStream.getReader())) { |
| 78 | + parseHandler(event, detail); |
| 79 | + } |
| 80 | + |
90 | 81 | await finished(contentStream); |
91 | | - saxParser.end(); |
92 | 82 | } |
0 commit comments