Skip to content

[Draft] Package support in Web/Wasm via Async support#16

Closed
fallible-algebra wants to merge 1 commit into
Relacibo:mainfrom
fallible-algebra:feature/async-package-resolver
Closed

[Draft] Package support in Web/Wasm via Async support#16
fallible-algebra wants to merge 1 commit into
Relacibo:mainfrom
fallible-algebra:feature/async-package-resolver

Conversation

@fallible-algebra

Copy link
Copy Markdown

As far as I can tell, the main thing in the way of package support on web is support for an async API (as blocking requests aren't possible or desired on the web). This likely means duplicating a bunch of methods and storages and relying on the async_traits crate.

I'm opening this PR early to open discussion, mostly. I've tried vendoring this crate before and it's been a bit more than what I've had capacity to do, but I'd like to hack at it here and there now I've had a look at the internals after the recent-ish rewrite. That being said I'm stretched a bit thin right now, so I'm not making promises.

@Relacibo

Copy link
Copy Markdown
Owner

Ok, cool. Yeah, I once tried making this work on web, but I hit some barriers and stopped there. I mean typst only provides us with a blocking context. I don't see how we can break out of that. I mean there is no AsyncTypstWorld or something. We have to implement TypstWorld which requires blocking functions.

fn source(&self, id: FileId) -> FileResult<Source> {

So we would need to rewrite/adjust this typst compile function in async:
https://github.com/typst/typst/blob/0264534928864c7aed0466d670824ac0ce5ca1a8/crates/typst/src/lib.rs#L91
I don't think we would necessarily need to duplicate all of my Resolvers as we could probably have a way to call the blocking resolvers from async. There would be an enum (I don't know if possible):

FileResolverEnum {Async(Box<dyn AsyncFileResolver + Send + Sync + 'static>), Sync(Box<dyn FileResolver + Send + Sync + 'static>)}

We would store the FileResolvers in the TypstEngine like this:

pub struct TypstEngine<T = TypstTemplateCollection> {
     ...
    file_resolvers: Vec<FileResolverEnum>,
    ...
}

I currently don't have the time to work on this and I personally don't need this feature, but I know, that it is very much desired by a lot of people.

@fallible-algebra

fallible-algebra commented Jul 13, 2025

Copy link
Copy Markdown
Author

Thanks for your thoughts! These are very helpful pointers.

I wonder if a reasonable side-step to "get an async compile fn implementation upstream/off an extension trait" might be taking the ASTs from source files and pre-fetching what packages are referenced by them before we hand a synchronous file resolver off to the synchronous typst world, assuming one can't dynamically reference universe packages in a typst project. This would keep async off of the main typst logic, but we would need to do this for the whole dependency tree and it maybe only aligns with my use case, which is entirely static-resolver based.

I'll have a look at how async-able an alternative compile_impl is when I have some time. I expect it to be gnarly, but who knows.

@fallible-algebra

Copy link
Copy Markdown
Author

Succeeded by #52

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants