fenjalien / obsidian-typst

Renders typst code blocks in Obsidian into images using Typst through the power of WASM!
Apache License 2.0
335 stars 16 forks source link

[Bug]: TypeError: Cannot read properties of undefined (reading 'compile_svg') #59

Open Schabolon opened 3 months ago

Schabolon commented 3 months ago

I just updated Obsidian to v1.6.5 and now TypeError: Cannot read properties of undefined (reading 'compile_svg') gets displayed for every typst-field. This happens for math-fields (with $ or $$) and code-blocks. I am running linux.

Obsidian Version: v1.6.5

fenjalien commented 3 months ago

I can't reproduce this on Windows but I don't have a Linux machine. Is the same issue present on a new vault with just this plugin installed, with a note with only a typst block?

Schabolon commented 3 months ago

Yes, the same thing happens in a new vault with only the obsidian-typst plugin installed: image (in this case compile_image, on my other vault I use svg)

Screenshot of the console in the new vault: image

If you need any more information feel free to reach out.

Schabolon commented 3 months ago

Debug Info from Obsidian (in the new Vault):

SYSTEM INFO:
    Obsidian version: v1.6.5
    Installer version: v1.6.5
    Operating system: #1 SMP PREEMPT_DYNAMIC Fri, 21 Jun 2024 21:05:23 +0000 6.6.35-2-lts
    Login status: not logged in
    Insider build toggle: off
    Live preview: on
    Base theme: adapt to system
    Community theme: none
    Snippets enabled: 0
    Restricted mode: off
    Plugins installed: 1
    Plugins enabled: 1
        1: Typst Renderer v0.10.0
fenjalien commented 3 months ago

Welll shoot, I've just updated my Obsidian installer to 1.6.5 and it looks like something is wrong with the webassembly in the web worker. This is a pretty serious problem...

d-kaue commented 3 months ago

Welll shoot, I've just updated my Obsidian installer to 1.6.5 and it looks like something is wrong with the webassembly in the web worker. This is a pretty serious problem...

I don't know about web assembly, what I can help with is simply opinionated.

According to the changelog version 1.6.5, the installer is using Electron v30.1.2, and currently has a WebWorker related fix in Electron v31.1.0.

Is there any connection?

aik2mlj commented 2 months ago

Any update on this issue? Same on my Linux with Obsidian 1.6.5.

fenjalien commented 2 months ago

Sorry I haven't had time to properly diagnose this issue, it seems like something has changed with the electron version v30.1.2. An easy work around would be to downgrade to Obsidian 1.6.3 which doesn't have the electron update. You can find the installers here: https://github.com/obsidianmd/obsidian-releases/releases/tag/v1.6.3

Xemay commented 2 months ago

I installed electron 31 and changed version in obsidian start script. Now it works well

OverHash commented 2 months ago

I've been doing some debugging.

Relevant code that causes the error seems to be here, with specific focus on line 831 where we instantiate. This code is produced by wasm-pack, inside pkg/obsidian_typst.js.

My initial findings make it seem as though the type of module is a Response, but there is no global Response object. Still investigating...

Specifically, running typeof Response in the environment will yield "undefined".

OverHash commented 2 months ago

To add to my response above, I was able to patch the code produced by wasm-pack to become:

module = await module.arrayBuffer();
const instance = await WebAssembly.instantiate(module, imports);

which makes everything work :D

I'm really not sure where the fix for this should go. I'm really not sure why Response is an empty object in the Obsidian JS environment, yet there seems to be something which represents a Response returned by await input inside the __wbg_init function.


It looks like __wbg_init is called with input = "blob:app://obsidian.md/becf8bb6-c8c3-4e36-b2dc-f1041cb57454" (a string). __wbg_init will then call input = fetch(input); to fetch the wasm. This seems to return a Promise<Response<...>> object, which __wbg_init will only call await on, leaving us with a Response<...>. However, it looks like the wasm runner expects it to be an array buffer by this point.

Really not sure where to go from here for getting a more stable fix in! I think the weirdest part so far for me is that the Obsidian environment does not have a global Response object. I think if someone who is running an older Obsidian version could confirm if there is a Response object there would really help tell if this is a lead to the issue on the Obsidian plugin side, or if it's more the wasm side.

aik2mlj commented 2 months ago

I just updated to Obsidian 1.6.7 (on arch linux) and this issue seems gone.

OverHash commented 2 months ago

I just updated to Obsidian 1.6.7 (on arch linux) and this issue seems gone.

Strange, I am on Obsidian 1.6.7 and I had the issue. Very strange that it resolved it for you.

OverHash commented 2 months ago

I did some more testing and it looks like inside main.ts, the global Response exists (and is of type function).

However, inside compiler.worker.ts, the type of Response is undefined. I suspect there's been a change here between Obsidian 1.6.3 and Obsidian 1.6.5.


edit: I printed all the globals available inside the worker, and it indeed does seem to be a limited set (which excludes the Response object):

List of globals available inside Worker ``` [ "name", "onmessage", "onmessageerror", "cancelAnimationFrame", "close", "postMessage", "requestAnimationFrame", "webkitRequestFileSystem", "webkitRequestFileSystemSync", "webkitResolveLocalFileSystemSyncURL", "webkitResolveLocalFileSystemURL", "global", "clearImmediate", "setImmediate", "module", "require", "__filename", "__dirname", "fetch", "import_meta", "wasm", "cachedTextDecoder", "cachedUint8Memory0", "getUint8Memory0", "getStringFromWasm0", "heap", "heap_next", "addHeapObject", "getObject", "dropObject", "takeObject", "isLikeNone", "cachedFloat64Memory0", "getFloat64Memory0", "cachedInt32Memory0", "getInt32Memory0", "WASM_VECTOR_LEN", "cachedTextEncoder", "encodeString", "passStringToWasm0", "stack_pointer", "addBorrowedObject", "passArray8ToWasm0", "cachedUint8ClampedMemory0", "getUint8ClampedMemory0", "getClampedArrayU8FromWasm0", "handleError", "SystemWorld", "__wbg_load", "__wbg_get_imports", "__wbg_init_memory", "__wbg_finalize_init", "__wbg_init", "obsidian_typst_default", "canUseSharedArrayBuffer", "decoder", "basePath", "packagePath", "packages", "xhr", "requestData", "compiler" ] ```

Frankly I'm now wondering how the fetch function returns a Response object. I've never played with wasm, or web workers before, so excuse my inexperience :)

OverHash commented 2 months ago

Just put up a PR which should patch this issue! Would love anyone to test it out. You'll need to build the plugin locally:

  1. Clone the repository
  2. npm install
  3. npm run wasm-build
  4. Copy the main.js file over to the relevant Obsidian plugin folder, replacing the existing one.
ghareebishere commented 1 month ago

@OverHash can you provide a build of it? i have no experience in WASM and faced much errors while building it myself

OverHash commented 1 month ago

Hey @ghareebishere, here's my build. I would, of course, recommend that you build yourself if you can.

main.zip