Skip to content

Commit 1b36e68

Browse files
committed
feat(wasm): add Node.js ES module wrapper
- Create async/sync JavaScript API wrapper - Configure package.json with .mjs build script - Handle WASM initialization and module loading
1 parent 755c6ce commit 1b36e68

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

wasm/lib/index.mjs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { readFile } from 'node:fs/promises';
2+
import { fileURLToPath } from 'node:url';
3+
import { dirname, join } from 'node:path';
4+
5+
// Dynamic import to handle the ES module
6+
let wasmModule = null;
7+
8+
async function loadWasmModule() {
9+
if (!wasmModule) {
10+
wasmModule = await import('../pkg/markdown_rs_wasm.mjs');
11+
}
12+
return wasmModule;
13+
}
14+
15+
// Initialize WASM module once
16+
let initialized = false;
17+
let initPromise = null;
18+
19+
async function ensureInitialized() {
20+
if (initialized) return;
21+
if (!initPromise) {
22+
const wasm = await loadWasmModule();
23+
// Read WASM file for Node.js
24+
const __dirname = dirname(fileURLToPath(import.meta.url));
25+
const wasmPath = join(__dirname, '..', 'pkg', 'markdown_rs_wasm_bg.wasm');
26+
const wasmBuffer = await readFile(wasmPath);
27+
28+
initPromise = wasm.default({ module_or_path: wasmBuffer }).then(() => {
29+
initialized = true;
30+
});
31+
}
32+
await initPromise;
33+
}
34+
35+
/**
36+
* Convert markdown to HTML using CommonMark
37+
* @param {string} input - Markdown text
38+
* @returns {Promise<string>} HTML output
39+
*/
40+
export async function toHtml(input) {
41+
await ensureInitialized();
42+
const wasm = await loadWasmModule();
43+
return wasm.to_html(input);
44+
}
45+
46+
/**
47+
* Convert markdown to HTML with options
48+
* @param {string} input - Markdown text
49+
* @param {Object} options - Parsing options
50+
* @param {boolean} [options.gfm] - Enable GitHub Flavored Markdown
51+
* @param {boolean} [options.mdx] - Enable MDX
52+
* @param {boolean} [options.frontmatter] - Enable frontmatter
53+
* @param {boolean} [options.allowDangerousHtml] - Allow raw HTML
54+
* @param {boolean} [options.allowDangerousProtocol] - Allow dangerous protocols
55+
* @returns {Promise<string>} HTML output
56+
*/
57+
export async function toHtmlWithOptions(input, options) {
58+
await ensureInitialized();
59+
const wasm = await loadWasmModule();
60+
return wasm.to_html_with_options(input, options);
61+
}
62+
63+
// Also export sync versions after initialization
64+
export function toHtmlSync(input) {
65+
if (!initialized || !wasmModule) {
66+
throw new Error('WASM not initialized. Call toHtml() first or await init()');
67+
}
68+
return wasmModule.to_html(input);
69+
}
70+
71+
export function toHtmlWithOptionsSync(input, options) {
72+
if (!initialized || !wasmModule) {
73+
throw new Error('WASM not initialized. Call toHtmlWithOptions() first or await init()');
74+
}
75+
return wasmModule.to_html_with_options(input, options);
76+
}
77+
78+
export async function init() {
79+
await ensureInitialized();
80+
}

wasm/package.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "markdown-rs-wasm",
3+
"version": "0.0.1",
4+
"description": "WebAssembly bindings for markdown-rs",
5+
"type": "module",
6+
"exports": "./lib/index.mjs",
7+
"files": [
8+
"lib/",
9+
"pkg/",
10+
"README.md"
11+
],
12+
"scripts": {
13+
"build": "wasm-pack build --target web --out-dir pkg && mv pkg/markdown_rs_wasm.js pkg/markdown_rs_wasm.mjs",
14+
"test": "node --test test/index.test.mjs",
15+
"example:basic": "node examples/basic.mjs",
16+
"example:options": "node examples/with-options.mjs"
17+
},
18+
"keywords": [
19+
"markdown",
20+
"commonmark",
21+
"wasm",
22+
"webassembly",
23+
"mdx",
24+
"gfm"
25+
],
26+
"license": "MIT",
27+
"repository": "https://github.com/wooorm/markdown-rs",
28+
"engines": {
29+
"node": ">=16.0.0"
30+
}
31+
}

0 commit comments

Comments
 (0)