fix: direct WASM instantiation without wasm-bindgen JS glue

This commit is contained in:
Accusys
2026-05-18 11:56:17 +08:00
parent e53106f7e2
commit 773ab67092

View File

@@ -31,15 +31,6 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-
</style>
</head>
<body>
<script>
window.addEventListener('error', function(e) {
document.getElementById('content').innerHTML = '<p style="color:red">Global error: ' + e.message + '</p>';
});
window.addEventListener('unhandledrejection', function(e) {
document.getElementById('content').innerHTML = '<p style="color:red">Unhandled: ' + e.reason + '</p>';
});
</script>
<script src="/doc-wasm/pkg/md_wasm.js"></script>
<div id="app">
<div class="sidebar">
<h1>Momentry Docs</h1>
@@ -49,7 +40,7 @@ window.addEventListener('unhandledrejection', function(e) {
</div>
</div>
<div class="content" id="content">
<p>Loading WASM...</p>
<p>Loading...</p>
</div>
</div>
<script>
@@ -69,7 +60,38 @@ const MODULES = [
];
const el = document.getElementById('content');
let wasm = null;
let wasm_render = null;
async function initWasm() {
const resp = await fetch('/doc-wasm/pkg/md_wasm_bg.wasm');
const bytes = await resp.arrayBuffer();
const wasm = await WebAssembly.instantiate(bytes, {
wbg: { __wbindgen_init_externref_table: function() {} },
'./md_wasm_bg.js': {}
});
wasm_render = wasm.instance.exports.render;
}
function md2html(md) {
if (!wasm_render) return '<p>WASM not loaded</p>';
// Call the WASM render function
// It takes (ptr, len) and returns [ptr, len]
const encoder = new TextEncoder();
const buf = encoder.encode(md);
const malloc = wasm.instance.exports.__wbindgen_malloc;
const free = wasm.instance.exports.__wbindgen_free;
const memory = wasm.instance.exports.memory;
const ptr = malloc(buf.length, 1);
const mem = new Uint8Array(memory.buffer);
mem.set(buf, ptr);
const result = wasm_render(ptr, buf.length);
const [rptr, rlen] = result;
const ret = new TextDecoder().decode(new Uint8Array(memory.buffer, rptr, rlen));
free(rptr, rlen, 1);
return ret.replace(/<table>/g, '<table class="table">');
}
async function loadDoc(name) {
el.innerHTML = '<p>Loading...</p>';
@@ -77,25 +99,23 @@ async function loadDoc(name) {
const resp = await fetch('/doc-wasm/modules/' + name + '.md');
if (!resp.ok) throw new Error('HTTP ' + resp.status);
const md = await resp.text();
if (!wasm) throw new Error('WASM not initialized');
var html = wasm.render(md);
if (html.length === 0) throw new Error('WASM render returned empty HTML');
el.innerHTML = html;
if (!wasm_render) throw new Error('WASM not loaded');
el.innerHTML = md2html(md);
document.querySelectorAll('.sidebar a.module-link').forEach(function(a) { a.classList.remove('active'); });
var link = document.querySelector('.sidebar a[data-module="' + name + '"]');
if (link) link.classList.add('active');
history.pushState(null, '', '#' + name);
} catch(e) {
el.innerHTML = '<p style="color:red">Error: ' + e.message + '</p><pre style="font-size:12px;background:#f8f8f8;padding:8px">' + e.stack + '</pre>';
el.innerHTML = '<p style="color:red">Error: ' + e.message + '</p><pre>'+e.stack+'</pre>';
}
}
async function init() {
try {
el.innerHTML = '<p>Initializing WASM...</p>';
wasm = await wasm_bindgen();
el.innerHTML = '<p>Loading modules...</p>';
const listEl = document.getElementById('module-list');
el.innerHTML = '<p>Loading WASM...</p>';
await initWasm();
el.innerHTML = '<p>Building modules...</p>';
var listEl = document.getElementById('module-list');
MODULES.forEach(function(m) {
var a = document.createElement('a');
a.className = 'module-link';
@@ -111,7 +131,7 @@ async function init() {
var hash = location.hash.slice(1);
await loadDoc(hash || '01_auth');
} catch(e) {
el.innerHTML = '<p style="color:red">Init error: ' + e.message + '</p><pre style="font-size:12px;background:#f8f8f8;padding:8px">' + e.stack + '</pre>';
el.innerHTML = '<p style="color:red">Init error: ' + e.message + '</p><pre>'+e.stack+'</pre>';
}
}