Mercurial
view markdown_converter/wasm/markdown_to_html_wasm.js @ 180:3a4ebe4552bf
Remove playground file as it is not needed to be tracked.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Mon, 19 Jan 2026 08:05:02 -0800 |
| parents | cd35e600ae34 |
| children |
line wrap: on
line source
/** * Markdown to HTML Converter - WASM FFI Wrapper * Loads the C implementation via WebAssembly and provides JavaScript API * * Build the WASM with: bazel build //markdown_converter:markdown_to_html_wasm */ class MarkdownConverterWasm { constructor() { this.wasm = undefined; this.ready = false; } /** * Initialize the WASM module * @param {string} wasmPath - Path to the .wasm file * @returns {Promise<void>} */ async init(wasmPath = '/markdown_to_html_wasm.wasm') { if (this.ready) return; try { this.wasm = await WebAssembly.instantiateStreaming(fetch(wasmPath), { env: {} }); this.ready = true; } catch (err) { console.error('Failed to load markdown WASM module:', err); throw err; } } /** * Write string to WASM memory * @private */ _writeString(str) { const encoder = new TextEncoder(); const bytes = encoder.encode(str + '\0'); const ptr = this.wasm.instance.exports.malloc(bytes.length); const memory = new Uint8Array(this.wasm.instance.exports.memory.buffer); memory.set(bytes, ptr); return ptr; } /** * Read string from WASM memory * @private */ _readString(ptr) { const memory = new Uint8Array(this.wasm.instance.exports.memory.buffer); let end = ptr; while (memory[end] !== 0) end++; const bytes = memory.slice(ptr, end); const decoder = new TextDecoder(); return decoder.decode(bytes); } /** * Reset the WASM heap (call between conversions to reclaim memory) */ resetHeap() { if (this.ready) { this.wasm.instance.exports.heap_reset(); } } /** * Convert markdown string to HTML string using WASM * @param {string} markdown - The markdown text to convert * @returns {string} The converted HTML */ convert(markdown) { if (!this.ready) { throw new Error('WASM module not initialized. Call init() first.'); } // Reset heap before each conversion to reclaim memory this.resetHeap(); // Write markdown to WASM memory const inputPtr = this._writeString(markdown); // Call the C function const outputPtr = this.wasm.instance.exports.markdown_to_html(inputPtr); // Read the result const html = this._readString(outputPtr); return html; } /** * Convert markdown to DOM elements (compatible with original API) * @param {string} markdown - The markdown text to convert * @returns {Array<HTMLElement>} Array of DOM elements */ convertToElements(markdown) { const html = this.convert(markdown); const template = document.createElement('template'); template.innerHTML = html; return Array.from(template.content.children); } } // Singleton instance const markdownWasm = new MarkdownConverterWasm(); /** * Convert markdown to DOM elements (WASM version) * Compatible with original markdownConverter() API * @param {string} value - Markdown string * @returns {Promise<Array<HTMLElement>>} Array of DOM elements */ async function markdownConverterWasm(value) { if (!markdownWasm.ready) { await markdownWasm.init(); } return markdownWasm.convertToElements(value); } /** * Render markdown to a container element (WASM version) * Compatible with original renderMarkdown() API * @param {HTMLElement} container - Container element * @param {string} markdown - Markdown string */ async function renderMarkdownWasm(container, markdown) { if (!markdownWasm.ready) { await markdownWasm.init(); } container.innerHTML = markdownWasm.convert(markdown); } // Export for use in other files if (typeof module !== 'undefined' && module.exports) { module.exports = { MarkdownConverterWasm, markdownWasm, markdownConverterWasm, renderMarkdownWasm }; }