mupdf-js icon indicating copy to clipboard operation
mupdf-js copied to clipboard

[FEATURE] Alternative way to instantiate mupdf-js instance

Open lnfel opened this issue 2 years ago • 2 comments

Is your feature request related to a problem? Please describe.

I can instantitate mupdf-js on sveltekit front-end using await createMuPdf(). But I wanted to somehow instantiate mupdf in sveltekit's server side context. If I do await createMuPdf(), sveltekit would give the following error:

Error: Cannot use relative URL (/home/projects/sveltejs-kit-template-default-7koyei/node_modules/mupdf-js/dist/libmupdf.wasm) with global fetch — use event.fetch instead: https://kit.svelte.dev/docs/web-standards#fetch-apis

It seems createMuPdf is doing fetch('/home/projects/sveltejs-kit-template-default-7koyei/node_modules/mupdf-js/dist/libmupdf.wasm') which sveltekit does not like when done server side.

Here is the stackblitz reproduction of the issue: https://stackblitz.com/edit/sveltejs-kit-template-default-7koyei?file=src/routes/+server.js. Clicking on the button will send a post request to svelte server where createMuPdf is called and the above error happens.

Describe the solution you'd like

It would be nice if we could load libmupdf.wasm by passing its path on the disk with createMuPdf, something like:

import * as path from "path"
import { fileURLToPath } from "url"

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

const mupdfPath = path.join(__dirname, '../node_modules/mupdf-js/dist/libmupdf.wasm')
const mupdf = await createMuPdf(mupdfPath)

Since mupdf is already able to get path of libmupdf.wasm like '/home/projects/sveltejs-kit-template-default-7koyei/node_modules/mupdf-js/dist/libmupdf.wasm', loading should be possible.

Describe alternatives you've considered

I tried loading the wasm file using nodejs readFile and do WebAssembly.instantiate but I am having problems with importing. I don't really know about wasm so I am a bit lost.

import { readFile } from 'node:fs/promises'

const mupdfWasmBuffer = await readFile(path.join(__dirname, '../../node_modules/mupdf-js/dist/libmupdf.wasm'))
const mupdfModule = await WebAssembly.compile(mupdfWasmBuffer)
let importObject = {}

for (let imp of WebAssembly.Module.imports(mupdfModule)) {
    if (typeof importObject[imp.module] === "undefined") {
        importObject[imp.module] = {}
    }
    switch (imp.kind) {
        case "function": importObject[imp.module][imp.name] = () => {}; break;
        case "table": importObject[imp.module][imp.name] = new WebAssembly.Table({ initial: 0, element: "anyfunc" }); break;
        case "memory": importObject[imp.module][imp.name] = new WebAssembly.Memory({ initial: 12000, maximum: 32768 }); break;
        case "global": importObject[imp.module][imp.name] = 0; break;
    }
}
const mupdfInstance = await WebAssembly.instantiate(mupdfWasmBuffer, importObject)

lnfel avatar Mar 07 '23 01:03 lnfel

Any news on this?

tgdn avatar Oct 03 '23 11:10 tgdn

@tgdn I've switched to use the original MdPDF wasm build by ArtifexSofware: https://mupdf.readthedocs.io/en/latest/mupdf-wasm.html

lnfel avatar Oct 09 '23 05:10 lnfel