Skip to content

Optional: a Workers/wasm fetch-based async include loader #650

Description

@joeblew999

I've been running catapulte on Cloudflare Workers (wasm32), which means the reqwest http-loader is out — it doesn't build for wasm. So I needed some other way to resolve <mj-include> partials.

Expected this to be a pain. It wasn't. I implemented AsyncIncludeLoader over the Workers fetch API and it worked first try — the #[async_trait(?Send)] you already put on the trait for wasm32 meant the !Send fetch future just dropped in, no fighting the compiler. The whole loader is about 20 lines:

#[derive(Debug)]
struct FetchIncludeLoader;

#[async_trait::async_trait(?Send)]
impl AsyncIncludeLoader for FetchIncludeLoader {
    async fn async_resolve(&self, path: &str) -> Result<String, IncludeLoaderError> {
        let url = url::Url::parse(path).map_err(|_| IncludeLoaderError::not_found(path))?;
        let mut resp = Fetch::Url(url).send().await
            .map_err(|_| IncludeLoaderError::not_found(path))?;
        if resp.status_code() != 200 {
            return Err(IncludeLoaderError::not_found(path));
        }
        resp.text().await.map_err(|_| IncludeLoaderError::not_found(path))
    }
}

So this is really just a "do you want it upstream?" question. I'm happy to send a PR adding a worker/wasm fetch-based async loader behind a feature flag, sitting next to http-loader, so mrml renders includes on Workers out of the box. Or I'll keep it in my own code if you'd rather not carry another loader — no worries either way.

Mostly wanted to flag that the loader abstraction made this a non-event. Want the PR?

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions